我用JavaScript写了一个小游戏!
链接
我写了一个简单的小游戏。
游戏链接(可能需要加载一段时间)
Github开源地址
简介
前几天我在玩 Emoji Kitchen(一个可以混合emoji变成新的emoji的东西) 的时候,突然想到,有那么多的emoji,这不就是免费的图片素材库嘛,于是就使用纯js和emoji素材写了了这个小游戏。
非常简陋的小游戏,完成度很低,但是这应该是我接触的第一个比较需要代码架构能力的项目,因为之前参加算法竞赛,写的代码都是“一次性”,提交题目通过后就不会再维护,为了在规定时间内完成题目,变量名都是很短的a、b、c,从来没注意可读性和可维护性,也很少写OOP的代码。
写这个小游戏让我学到很多,比如面向对象程序设计、游戏的ECS(Entity Component System)架构(尽管我的游戏里没有用到Component)、代码之间如何解耦、怎么写规范的Commit Message等等。开发过程中也经历了数次痛苦的重构,让我知道了 “Think twice, code once”这句话 有多么的重要。
这还只是一个简陋的demo,可能想起来了就会偶尔加点功能?在代码变成屎山之前我会物尽 ...
SQL学习笔记(五)插入、更新与删除
INSERT
1INSERT INTO 表名 (列名, ...) VALUES (值, ...);
这样可以插入新的数据,例如插入一本新书“A Wrinkle in Time”。
1INSERT INTO books (title, price, sales, category) VALUES ('A Wrinkle in Time',23.99,1,'Fantasy');
键入SELECT * FROM books;可以看到已经成功地插入了新的书。
UPDATE
用UPDATE将所有“Science Fiction”分类改名为“Sci-fi”可以这样写:
1UPDATE books SET category = 'Sci-fi' WHERE category = 'Science Fiction';
这是我们接触到的第一个“破坏性”的命令,所以键入命令时请double check一下,确认这就是你想要的,避免造成严重的后果 。实际的项目中一般有权限控制、备份、生产环境隔离等方法来避免这种悲剧的发生,但是 ...
SQL学习笔记(四)条件与分组语句
上一章节里我们使用了WHERE关键字进行了条件的筛选,实际上这样的关键字还有很多,以下是常用的一些。
GROUP BY
将数据按某个字段分组
1SELECT category, COUNT(*) FROM books GROUP BY category;
输出:
12345678┌─────────────────┬──────────┐│ category │ COUNT(*) │├─────────────────┼──────────┤│ Classic │ 6 ││ Fantasy │ 4 ││ Fiction │ 7 ││ Science Fiction │ 3 │└─────────────────┴──────────┘
ORDER BY
按某个字段排序,例如按每种分类的个数排序。
1SELECT category, COUNT(*) FROM books GROUP BY category ORDER BY COUNT(*);
输出:
12345678 ...
【CS50】课程推荐与学习心得
注:本文中所有标注*号的链接表示需要魔法上网
推荐
CS50真的是非常好的一门计算机入门课程,由哈佛大学David J. Malan教授主讲,它完全是面向对于计算机科学0基础的学习者,既简单易懂又干货满满,我真的难以相信,这是一门完全免费的课程。
看看CS50的目录,CS50是从scratch开始讲的,这足以证明它的初学者友好。
难能可贵的是,这门课并不因为简单就牺牲专业性。这并不是一门水课,它干货满满。从算法、数据结构到web三剑客html、css、js,再到web开发框架flask。全都是干货,况且每一次的CS50课程还配套相应的作业,有些作业难度不低。
这门课程很多内容都只是一个入门的引导,而不是一个完整的教程,但是正如David教授所说的那样,他不是要教你一种编程语言,他要教你 计算机科学 ,让你能够学会任何一门编程语言,让你有能力追逐最新的技术潮流。
学习心得
尽管我并不是零基础的学习者,但是听了这门课程我仍然收获颇丰,不仅收获了专业知识,也获得了很多乐趣,毕竟David教授是我见到的第一个能把课上得比看电影还有意思的教授。
非常羡慕Harvard这样的世界名校提供的资 ...
SQL学习笔记(三)基本查询语句
SQL中的函数
SQL中自带了很多函数,常用的有这几种:
函数
描述
AVG
求平均数
COUNT
计数
DISTINCT
去重
LOWER
小写
UPPER
大写
MAX
取最大值
MIN
取最小值
DISTINCT
假如我们想要查看所有的分类,可以这样子写:
1SELECT DISTINCT(category) FROM books;
输出:
12345678┌─────────────────┐│ category │├─────────────────┤│ Fiction ││ Science Fiction ││ Fantasy ││ Classic │└─────────────────┘
COUNT
查看有多少种分类:
1SELECT COUNT(DISTINCT(category)) FROM books;
输出是这样的
12345┌───────────────────────────┐│ COUNT(DISTINCT(category)) │├─────── ...
SQL学习笔记(二)创建一个表
在命令行里键入以下命令:
1sqlite3
如果你按照上一个章节中那样配置好了环境,应该可以看到以下输出。
123# SQLite version 3.43.1 2023-09-11 12:01:27# Enter ".help" for usage hints.# sqlite>
看到输入提示符变成“sqlite>”,我们就进入了sqlite的命令行。
基本语句
数据库有四个基本操作CRUD,即Create增、Read查、Update改、Delete删,在SQL中分别对应以下语句。
增:CREATE, INSERT
查:SELECT
改:UPDATE
删:DELETE, DROP
创建一个表
使用以下命令来创建一个表,注意所有的SQL语句末尾都要有分号。
1CREATE TABLE 表名 ('列名' 数据类型, ...);
不同的数据库可能对相同的类型有不同的名称、不同的长度、数据范围
以sqlite为例,常用的数据类型有以下几种:
数据类型
描述
NULL
空值NULL
INTEGER
整数,具体位数取决于 ...
SQL学习笔记(一)安装SQLite
引入
现代的程序,无论是网站、手机app等等,往往都要处理大量的数据,这些数据需要通过**数据库(Database)**来管理。为了便于程序与数据库之间的交互,我们引入一门语言,SQL(Structured Query Language,结构化查询语言)。使用SQL可以方便地对 关系型数据库(Relational Database) 进行增、查、改、删等操作。
如果你不知道关系型数据库和非关系型数据库是什么,可以看看我的这篇文章
SQLite的安装
为了学习SQL,我们先来安装一个轻量级的关系型数据库 SQLite ,请与SQL区分,SQL是一种查询语言,SQLiete是一种数据库。
因为我们只是用来学习SQL语言,所以比起Oracle这样的庞然大物,使用轻量级的SQLite是更好的选择。当然,你学会了SQL之后,可以自由选择符合你需求的数据库,关系型数据库都使用统一的SQL语言,无需再次学习。
安装SQLite非常简单,访问SQLite官网的下载页面,下载你的系统对应的带有“Precompiled”前缀的压缩包。以windows x64系统为例,下载这两个文件,并把他们解压到相同的 ...
关系型数据库与非关系型数据库
关系型数据库(Relational Database)与非关系型数据库(NoSQL Database)有什么区别呢?请看下面的表格。
关系型数据库
非关系型数据库
数据结构
数据库表
不固定,如键值对(Key-Value)等
可扩展性
横向扩展较为困难,需要增加外部关联数据表
具有高度可扩展性
查询语言
SQL
通常具有自己的查询语言,没有SQL那样标准化
ACID
支持恢复、回滚、并发控制等
难以保证数据的完整性和安全性
ACID: 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)
简单来说,关系型数据库就像Excel表格,非关系型数据库就像.json文件(当使用键值对数据结构时)。
关系型数据库更成熟稳定,非关系型数据库更灵活易扩展。
环境变量path是什么
有什么用
当你想要在命令行启动某个程序,通常你要cd进入到这个程序所在的目录,或者键入程序的完整路径。如果经常使用它,这样太繁琐了。环境变量path可以告诉命令行去哪里找程序的位置,这样,只需要键入程序名称,无需键入完整路径,就可以打开程序。
具体来说,搜索程序的顺序一般是这样的:
先在当前的工作路径寻找
如果未找到,在环境变量的path中寻找
如果仍未找到,报错
举个例子
假如我们用C语言写了一个简单的加法计算器
123456789101112// /root/myCommands/calculator.cpp#include<stdio.h>int main(int argc, char *argv[]) { int ans = 0, tmp, i; for (i = 1; i < argc; ++i) { sscanf(argv[i], "%d", &tmp); ans += tmp; } printf("%d\n", ans) ...
程序的内存布局
简介
通常,一个程序的内存布局包括以下部分
代码段
初始化数据段
未初始化数据段(bss)
堆
栈
它们的位置如图所示
代码段(Text/Code Segment)
代码段就是程序代码编译后的机器码储存的位置,储存着计算机可执行的指令。
代码段通常是只读的,防止程序在运行的时候意外修改到自身的代码。
数据段
数据段只包含全局变量和静态变量,局部变量并不在这块区域里,而是在栈里。
初始化数据段(Initialized Data Segment)
顾名思义,就是被程序员手动初始化的全局变量和静态变量。
未初始化数据段(Initialized Data Segment)
由于一些历史原因,也被叫做bss段,这个名字是“block started by symbol”的简称,感兴趣的可以在wiki百科(需要魔法)上了解。
未初始化的全局变量和静态变量会被默认置0。
栈(Stack)
开头的图中可以看出,栈区和堆区在程序运行的时候朝着不同的方向增长,当两个区域碰上的时候,程序的可分配内存就耗尽了,可能造成程序异常、崩溃等。
假如向栈内写入了过多数据(如调用函数层数过多,函数使用的局部数据 ...