├── .gitignore ├── README.md ├── algorithm ├── BinSearch.php ├── BubbleSort.php ├── InsertSort.php ├── MergeSort.php ├── QuickSort.php └── SelectSort.php ├── framework ├── Cache.md ├── Framework.md └── Queue.md ├── git └── README.md ├── javascript └── README.md ├── linux ├── README.md └── Shell.md ├── memcached └── README.md ├── mongo └── README.md ├── mysql ├── Base.md └── README.md ├── network ├── CDN.md ├── Http.md ├── IO.md ├── Internet-protocol.md └── Nginx.md ├── nginx ├── Conf.md ├── README.md └── Rewrite.md ├── other └── encrypt.md ├── pattern ├── AbstractFactory.php ├── Adapter.php ├── Bridge.php ├── Builder.php ├── Command.php ├── Composite.php ├── DataMapper.php ├── Decorator.php ├── Facade.php ├── Factor.php ├── FactoryMethod.php ├── Flyweight.php ├── Interpreter.php ├── Iterator.php ├── Mediator.php ├── Memento.php ├── NullObject.php ├── Observer.php ├── Prototype.php ├── Proxy.php ├── Register.php ├── Responsibility.php ├── Singleton.php ├── State.php ├── Strategy.php ├── Template.php └── Visitor.php ├── php ├── Features.php ├── HttpServer.php ├── Laravel.md ├── README.md ├── SAPI.md └── Zval.md └── redis └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # php-interview 2 | PHP后端开发面试指南。 3 | -------------------------------------------------------------------------------- /algorithm/BinSearch.php: -------------------------------------------------------------------------------- 1 | $target) { 21 | $height = $mid - 1; 22 | }elseif ($list[$mid] < $target) { 23 | $low = $mid + 1; 24 | } 25 | } 26 | return null; 27 | } 28 | 29 | var_dump(binSearch([1,2,4,5], 4)); -------------------------------------------------------------------------------- /algorithm/BubbleSort.php: -------------------------------------------------------------------------------- 1 | $array[$j + 1]) { 18 | $temp = $array[$j]; 19 | $array[$j] = $array[$j + 1]; 20 | $array[$j + 1] = $temp; 21 | } 22 | } 23 | } 24 | return $array; 25 | } 26 | 27 | var_dump(bubbleSort([6, 3, 8, 2, 9, 1])); 28 | 29 | 30 | function betterBubbleSort(array $array) : array 31 | { 32 | $flag = true; 33 | $length = count($array) - 1; 34 | $index = $length; 35 | while ($flag) { 36 | $flag = false; 37 | for ($i = 0; $i < $index; $i++) { 38 | if ($array[$i] > $array[$i+1]) { 39 | $flag = true; 40 | $last = $i; 41 | $temp = $array[$i]; 42 | $array[$i] = $array[$i+1]; 43 | $array[$i+1] = $temp; 44 | } 45 | } 46 | $index = isset($last) ? $last : $index; 47 | } 48 | return $array; 49 | } 50 | 51 | var_dump(bubbleSort([6, 3, 8, 2, 9, 1])); -------------------------------------------------------------------------------- /algorithm/InsertSort.php: -------------------------------------------------------------------------------- 1 | = count($list) - 1) { 13 | return $list; 14 | } 15 | 16 | $next = $list[$point + 1]; 17 | for ($i = $point; $i >= 0; --$i) { 18 | if ($list[$i] > $next) { 19 | $list[$i + 1] = $list[$i]; 20 | if ($i === 0) { 21 | $list[$i] = $next; 22 | break; 23 | } 24 | continue; 25 | } 26 | $list[$i + 1] = $next; 27 | break; 28 | } 29 | $point += 1; 30 | insertSort($list, $point); 31 | return $list; 32 | } 33 | 34 | $list = [5,3,1,2,4]; 35 | var_dump(insertSort($list)); 36 | 37 | 38 | function forInsertSort(array &$list = []) : array 39 | { 40 | $length = count($list); 41 | for ($i = 1;$i < $length; $i++) { 42 | $base = $list[$i]; 43 | for($j = $i - 1; $j >= 0; $j--) { 44 | if ($base < $list[$j]) { 45 | $list[$j+1] = $list[$j]; 46 | if ($j === 0) { 47 | $list[$j] = $base; 48 | break; 49 | } 50 | continue; 51 | } 52 | $arr[$j + 1] = $base; 53 | break; 54 | } 55 | } 56 | return $list; 57 | } 58 | 59 | $list = [5,3,1,2,4]; 60 | var_dump(forInsertSort($list)); -------------------------------------------------------------------------------- /algorithm/MergeSort.php: -------------------------------------------------------------------------------- 1 | $array[$j]) { 16 | $point = $j; 17 | } 18 | } 19 | $tmp = $array[$i]; 20 | $array[$i] = $array[$point]; 21 | $array[$point] = $tmp; 22 | } 23 | return $array; 24 | } 25 | $array = [1,4,2,5,3]; 26 | selectSort($array); 27 | var_dump($array); -------------------------------------------------------------------------------- /framework/Cache.md: -------------------------------------------------------------------------------- 1 | #### 缓存 2 | CDN缓存、反向代理缓存、本地应用缓存、分布式缓存 3 | 4 | CDN(Content Delivery Network 内容分发网络)的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求 5 | 6 | 反向代理位于应用服务器机房,处理所有对WEB服务器的请求。 7 | 如果用户请求的页面在代理服务器上有缓冲的话,代理服务器直接将缓冲内容发送给用户。如果没有缓冲则先向WEB服务器发出请求,取回数据,本地缓存后再发送给用户。通过降低向WEB服务器的请求数,从而降低了WEB服务器的负载。 8 | 9 | 本地应用缓存指的是在应用中的缓存组件,其最大的优点是应用和cache是在同一个进程内部,请求缓存非常快速,没有过多的网络开销等,在单应用不需要集群支持或者集群情况下各节点无需互相通知的场景下使用本地缓存较合适; 10 | 同时,它的缺点也是应为缓存跟应用程序耦合,多个应用程序无法直接的共享缓存,各应用或集群的各节点都需要维护自己的单独缓存,对内存是一种浪费。 11 | 12 | 分布式缓存指的是与应用分离的缓存组件或服务,其最大的优点是自身就是一个独立的应用,与本地应用隔离,多个应用可直接的共享缓存(如redis、memcached) 13 | 14 | #### Nginx本地缓存 15 | 16 | ​Nginx 作为Web服务器或者负载均衡器,一般不执行业务逻辑,而是将请求转到后端服务器,比如 Tomcat 或者 php-fpm,后端处理完毕之后将经过 nginx 将数据返回给用户。 17 | 在请求转发的过程中,nginx 可将中间数据在本地进行缓存,这样未来一段时间内的请求相同的数据,Nginx 可以直接返回本地复本,而不是再次向后端服务发起请求,可以大大降低后端服务器的压力。 18 | 同时,在后端服务器宕机时,Nginx 还可返回缓存数据,而不中端服务,提高了服务的可用性。 19 | 20 | ``` 21 | # 定义缓存路径、过期时间、空间大小等 22 | proxy_cache_path /tmp/nginx/cache levels=2:2:2 use_temp_path=off keys_zone=my_cache_name:10m inactive=1h max_size=1g; 23 | 24 | server { 25 | listen 8000; 26 | server_name localhost; 27 | # 添加缓存的 http 状态头 28 | add_header X-Cache-Status $upstream_cache_status; 29 | 30 | location / { 31 | # 定义缓存名称 32 | proxy_cache my_cache_name; 33 | # 定义缓存key 34 | proxy_cache_key $host$uri$is_args$args; 35 | # 针对返回装装他码单独定义缓存时间 36 | proxy_cache_valid 200 304 10m; 37 | # url 上代用 nocache 获取请求投中代用 nocache,切值为true 时不走缓存。 38 | proxy_cache_bypass $arg_nocache $http_nocahe; 39 | 40 | proxy_pass http://localhost:8080; 41 | } 42 | } 43 | ``` 44 | 45 | #### 客户端缓存 46 | - 浏览器端缓存 47 | 主要是利用 Cache-Control 参数。 48 | 49 | - H5 缓存 50 | html5缓存主要可以分为http协议缓存、应用缓存、DOM Storage、webSQL和indexedDB 51 | 52 | #### Redis与Memcached比较 53 | 54 | | | Redis | Memcached | 55 | | :------------: | :----------------------------------------------------------: | :----------------------------------------------------------: | 56 | | 支持的数据结构 | 哈希、列表、集合、有序集合 | 纯kev-value | 57 | | 持久化支持 | 有 | 无 | 58 | | 高可用支持 | redis天然支持集群功能,可以实现主动复制,读写分离。官方也提供了sentinel集群管理工具,能够实现主从服务监控,故障自动转移,这一切,对于客户端都是透明的,无需程序改动,也无需人工介入 | 需要二次开发 | 59 | | 存储value容量 | 最大512M | 最大1M | 60 | | 内存分配 | 临时申请空间,可能导致碎片 | 预分配内存池的方式管理内存,能够省去内存分配时间 | 61 | | 虚拟内存使用 | 有自己的VM机制,理论上能够存储比物理内存更多的数据,当数据超量时,会引发swap,把冷数据刷到磁盘上 | 所有的数据存储在物理内存里 | 62 | | 网络模型 | 非阻塞IO复用模型,提供一些非KV存储之外的排序,聚合功能,在执行这些功能时,复杂的CPU计算,会阻塞整个IO调度 | 非阻塞IO复用模型 | 63 | | 水平扩展的支持 | 暂无 | 暂无 | 64 | | 多线程 | Redis支持单线程 | Memcached支持多线程,CPU利用方面Memcache优于Redis | 65 | | 过期策略 | 有专门线程,清除缓存数据 | 懒淘汰机制:每次往缓存放入数据的时候,都会存一个时间,在读取的时候要和设置的时间做TTL比较来判断是否过期 | 66 | | 单机QPS | 约10W | 约60W | 67 | | 源代码可读性 | 代码清爽简洁 | 能是考虑了太多的扩展性,多系统的兼容性,代码不清爽 | 68 | | 适用场景 | 复杂数据结构、有持久化、高可用需求、value存储内容较大 | 纯KV,数据量非常大,并发量非常大的业务 | 69 | 70 | 71 | - Memcached 72 | 采用多路复用技术提高并发性。 73 | slab分配算法: memcached给Slab分配内存空间,默认是1MB。分配给Slab之后 把slab的切分成大小相同的chunk,Chunk是用于缓存记录的内存空间,Chunk 的大小默认按照1.25倍的速度递增。 74 | 好处是不会频繁申请内存,提高IO效率,坏处是会有一定的内存浪费。 75 | 76 | - Redis底层原理 77 | 使用 ziplist 存储链表,ziplist是一种压缩链表,它的好处是更能节省内存空间,因为它所存储的内容都是在连续的内存区域当中的。 78 | 使用 skiplist(跳跃表)来存储有序集合对象、查找上先从高Level查起、时间复杂度和红黑树相当,实现容易,无锁、并发性好。 79 | 80 | #### 分层缓存架构设计 81 | 82 | ![分层缓存架构](https://user-gold-cdn.xitu.io/2018/7/9/1647c7f9ec13f9c7?imageView2/0/w/1280/h/960/format/webp/ignore-error/1) 83 | 84 | #### 缓存带来的复杂度问题 85 | 86 | - 数据一致性 87 | 88 | - 缓存穿透 89 | 解决方案:对结果为空的数据也进行缓存,当此key有数据后,清理缓存;一定不存在的key,采用布隆过滤器,建立一个大的Bitmap中,查询时通过该bitmap过滤 90 | 91 | - 缓存雪崩 92 | 93 | - 缓存高可用 94 | 分布式:实现数据的海量缓存 95 | 复制:实现缓存数据节点的高可用 96 | 97 | - 缓存热点 98 | 复制多份缓存副本,把请求分散到多个缓存服务器上,减轻缓存热点导致的单台缓存服务器压力 99 | 100 | #### 缓存失效策略 101 | - FIFO:First In First Out,先进先出。判断被存储的时间,离目前最远的数据优先被淘汰。 102 | 103 | - LRU:Least Recently Used,最近最少使用。判断最近被使用的时间,目前最远的数据优先被淘汰。 104 | 105 | - LFU:Least Frequently Used,最不经常使用。在一段时间内,数据被使用次数最少的,优先被淘汰。 -------------------------------------------------------------------------------- /framework/Framework.md: -------------------------------------------------------------------------------- 1 | #### RESTful 2 | 3 | 一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。 4 | 5 | 在 REST 样式的 Web 服务中,每个资源都有一个地址。资源本身都是方法调用的目标,方法列表对所有资源都是一样的。这些方法都是标准方法,包括 HTTP GET、POST、PUT、DELETE,还可能包括 HEADER 和 OPTIONS。 6 | 7 | 优势在于能够穿透防火墙,使用方便,语言无关,基本上可以使用各种开发语言实现的系统,都可以接受Restful 的请求。 但性能和带宽占用上有劣势。 8 | 9 | 10 | #### RPC 11 | 12 | RPC(Remote Procedure Call Protocol)就是远程调用。远程调用免不了消息通信,所以本质上都是一种通信。RPC应该有各种各样的协议,基于或扩展与socket,HTTP等协议。 13 | 14 | 以Apache Thrift为代表的二进制RPC,支持多种语言(但不是所有语言),四层通讯协议,性能高,节省带宽。相对Restful协议,使用Thrifpt RPC,在同等硬件条件下,带宽使用率仅为前者的20%,性能却提升一个数量级。但是这种协议最大的问题在于,无法穿透防火墙。 15 | 16 | 17 | #### RPC VS RESTful 18 | 19 | - 从使用方面看,Http接口只关注服务提供方,对于客户端怎么调用,调用方式怎样并不关心,通常情况下,我们使用Http方式进行调用时,只要将内容进行传输即可,这样客户端在使用时,需要更关注网络方面的传输,比较不适用与业务方面的开发;而RPC服务则需要客户端接口与服务端保持一致,服务端提供一个方法,客户端通过接口直接发起调用,业务开发人员仅需要关注业务方法的调用即可,不再关注网络传输的细节,在开发上更为高效。 20 | 21 | - 从性能角度看,使用Http时,Http本身提供了丰富的状态功能与扩展功能,但也正由于Http提供的功能过多,导致在网络传输时,需要携带的信息更多,从性能角度上讲,较为低效。而RPC服务网络传输上仅传输与业务内容相关的数据,传输数据更小,性能更高。 22 | 23 | - 从运维角度看,使用Http接口时,常常使用一个前端代理,来进行Http转发代理请求的操作,需要进行扩容时,则需要去修改代理服务器的配置,较为繁琐,也容易出错。而使用RPC方式的微服务,则只要增加一个服务节点即可,注册中心可自动感知到节点的变化,通知调用客户端进行负载的动态控制,更为智能,省去运维的操作。 -------------------------------------------------------------------------------- /framework/Queue.md: -------------------------------------------------------------------------------- 1 | #### 消息队列 2 | 指利用 高效可靠 的 消息传递机制 进行与平台无关的 数据交流,并基于 数据通信 来进行分布式系统的集成。 3 | 4 | 低耦合、可靠投递、广播、流量控制、最终一致性等功能 5 | 6 | 通过提供 消息传递 和 消息排队 模型,它可以在 分布式环境 下提供 应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步 等等功能,其作为 分布式系统架构 中的一个重要组件,有着举足轻重的地位。 7 | 8 | #### 常见的消息队列 9 | - RabbitMQ 10 | RabbitMQ实现了AQMP协议,AQMP协议定义了消息路由规则和方式。生产端通过路由规则发送消息到不同queue,消费端根据queue名称消费消息。 11 | RabbitMQ既支持内存队列也支持持久化队列,消费端为推模型,消费状态和订阅关系由服务端负责维护,消息消费完后立即删除,不保留历史消息。 12 | 13 | - RocketMQ 14 | - ActiveMQ 15 | - Kafka 16 | Kafka只支持消息持久化,消费端为拉模型,消费状态和订阅关系由客户端端负责维护,消息消费完后不会立即删除,会保留历史消息。因此支持多订阅时,消息只会存储一份就可以了。但是可能产生重复消费的情况。 17 | 18 | - ZeroMQ 19 | - MetaMQ 20 | - Redis 21 | - MySQL 22 | 23 | #### 消息队列的传输模式 24 | 25 | - 点对点传输 26 | + 每个消息只用一个消费者; 27 | + 发送者和接受者没有时间依赖; 28 | + 接受者确认消息接受和处理成功。 29 | - 发布/订阅模型(Pub/Sub) 30 | + 每个消息可以有多个订阅者; 31 | + 客户端只有订阅后才能接收到消息; 32 | + 持久订阅和非持久订阅。 33 | 34 | #### 消息队列应用场景 35 | - 异步处理 36 | 37 | 非核心 流程 异步化,减少系统 响应时间,提高 吞吐量。例如:短信通知、终端状态推送、App 推送、用户注册 等 38 | 39 | - 系统解耦 40 | 41 | 不强依赖 于非本系统的核心流程,对于 非核心流程,可以放到消息队列中让 消息消费者 去按需消费,而 不影响核心主流程。 42 | 43 | - 最终一致性 44 | 45 | 最终一致性 不是 消息队列 的必备特性,但确实可以依靠 消息队列 来做 最终一致性 的事情。 46 | 47 | - 广播 48 | 49 | 生产者/消费者 模式,只需要关心消息是否 送达队列,至于谁希望订阅和需要消费,是 下游 的事情,无疑极大地减少了开发和联调的工作量。 50 | 51 | - 流量削峰和流控 52 | 53 | 当 上下游系统 处理能力存在差距的时候,利用 消息队列 做一个通用的 “漏斗”,进行 限流控制。在下游有能力处理的时候,再进行分发。 54 | 55 | - 日志处理 56 | 57 | 将消息队列用在 日志处理 中,比如 Kafka 的应用,解决 海量日志 传输和缓冲的问题。 58 | 59 | - 消息通讯 60 | 61 | 消息队列一般都内置了 高效的通信机制,因此也可以用于单纯的 消息通讯,比如实现 点对点消息队列 或者 聊天室 等。 -------------------------------------------------------------------------------- /git/README.md: -------------------------------------------------------------------------------- 1 | #### Git速查表 2 | 3 | | 序号 | 模块 | 功能 | 4 | | -------- | ------- | ------ | 5 | | 1 | CREATE | 关于创建的 | 6 | | 2 | LOCAL CHANGES | 关于本地改动方面的 | 7 | | 3 | COMMIT HISTORY | 关于提交历史的 | 8 | | 4 | BRANCHES & TAGS | 关于分支和标签类的 | 9 | | 5 | UPDATE & PUBLISH | 关于更新和发布的 | 10 | | 6 | MERGE & REBASE | 关于分支合并类的 | 11 | | 7 | UNDO | 关于撤销类的 | 12 | | 8 | SUBMODULE | 关于子模块 | 13 | 14 | ##### CREATE 15 | 16 | 从远程仓库获取代码 17 | ``` 18 | git clone ssh://user@domain.com/repo.git 19 | ``` 20 | 21 | 初始化本地仓库 22 | ``` 23 | git init 24 | ``` 25 | 26 | ##### LOCAL CHANGES 27 | 28 | 查看仓库的状态,(显示已改动的文件) 29 | ``` 30 | git status 31 | ``` 32 | 33 | 比较工作区与最新本地版本库 34 | ``` 35 | git diff 36 | ``` 37 | 38 | 添加所有变化(新增 new、修改 modified、删除 deleted)到暂存区 39 | ``` 40 | git add -A 41 | ``` 42 | 43 | 添加所有变化(新增 new、修改 modified)到暂存区,不包括被删除(deleted)文件 44 | ``` 45 | git add . 46 | ``` 47 | 48 | 添加修改(modified)和被删除(deleted)文件,不包括新文件(new)也就是不是被追踪文件(untracked) 49 | ``` 50 | git add -u 51 | ``` 52 | 53 | 添加文件内某些改动到暂存区 54 | ``` 55 | git add -p 56 | ``` 57 | 58 | 提交所有的放在暂存区的文件和已经修改(不在暂存区)的文件,且问件是要被追踪(tracked)的 59 | ``` 60 | git commit -a 61 | ``` 62 | 63 | 提交所有被在暂存区的问件 64 | ``` 65 | git commit 66 | ``` 67 | 68 | 修改上一次提交日志 69 | ``` 70 | git commit --amend 71 | ``` 72 | 73 | ##### COMMIT HISTORY 74 | 75 | 查看提交日志 76 | ``` 77 | git log 78 | ``` 79 | 80 | 跟踪查看某个文件的历史修改记录 81 | ``` 82 | git log -p 83 | ``` 84 | 85 | 查看文件是谁什么时候修改什么地方 86 | ``` 87 | git blame 88 | ``` 89 | ##### BRANCHES & TAGS 90 | 91 | 查看所有分支(包括远程分支) 92 | ``` 93 | git branch -a 94 | ``` 95 | 96 | 查看所有分支(包括远程分支)和最后一次提交日志 97 | ``` 98 | git branch -av 99 | ``` 100 | 101 | 切换分支 102 | ``` 103 | git checkout 104 | ``` 105 | 106 | 新建分支,不带old-branch为默认在当前分支上建立新分支 107 | ``` 108 | git branch 109 | ``` 110 | 111 | 新建并且换分支 112 | ``` 113 | git branch -b 114 | ``` 115 | 116 | 删除分支,先切换其他分支再删除 117 | ``` 118 | git branch -d 119 | ``` 120 | 121 | 删除远程分支 122 | ``` 123 | git push origin --delete 124 | ``` 125 | 126 | 查看标签 127 | ``` 128 | git tag 129 | ``` 130 | 131 | 新建标签 132 | ``` 133 | git tag 134 | ``` 135 | 136 | 删除标签 137 | ``` 138 | git tag -d 139 | ``` 140 | 141 | 推送标签到远程 142 | ``` 143 | git push origin tag-name 144 | git push origin --tags 145 | ``` 146 | 147 | ##### UPDATE & PUBLISH 148 | 149 | 列出所有的仓库地址 150 | ``` 151 | git remote -v 152 | ``` 153 | 154 | 查看某个仓库的信息 155 | ``` 156 | git remote show 157 | ``` 158 | 159 | 添加仓库地址 160 | ``` 161 | git remote add 162 | ``` 163 | 164 | 从远程更新代码到本地但不合并 165 | ``` 166 | git fetch 167 | ``` 168 | 169 | 从远程更新代码到本地且合并 170 | ``` 171 | git pull 172 | ``` 173 | 174 | 发布到远程地址 175 | ``` 176 | git push 177 | ``` 178 | 179 | 删除远程地址分支 180 | ``` 181 | git branch -dr 182 | ``` 183 | 184 | 上传标签 185 | ``` 186 | git push --tags 187 | ``` 188 | 189 | ##### MERGE & REBASE 190 | 191 | 合并目标分支到本地分支 192 | ``` 193 | git merge 194 | ``` 195 | 196 | 合并分支,但是不合并提交记录(commit),rebase合并如果有冲突则一个一个文件的去合并解决冲突 197 | ``` 198 | git rebase 199 | ``` 200 | 201 | 合并终止 202 | ``` 203 | git rebase --abort 204 | ``` 205 | 206 | 继续合并 207 | ``` 208 | git rebase --continue 209 | ``` 210 | 211 | 使用配置的合并工具来解决冲突 212 | ``` 213 | git mergetool 214 | ``` 215 | 216 | 添加已手动合并的文件 217 | ``` 218 | git add 219 | ``` 220 | 221 | 删除已手动合并的文件 222 | ``` 223 | git rm 224 | ``` 225 | 226 | ##### UNDO 227 | 228 | 回退到最近一个提交 229 | ``` 230 | git reset --hard HEAD 231 | ``` 232 | 233 | 回退到上一次提交(倒数第二次) 234 | ``` 235 | git reset --hard HEAD^ 236 | ``` 237 | 238 | 回退某次提交的某个文件 239 | ``` 240 | git checkout HEAD 241 | ``` 242 | 243 | 回退到某个提交,但是不删除commit 244 | ``` 245 | git revert 246 | ``` 247 | 248 | 彻底回退到某个提交(commit和代码都回退了) 249 | ``` 250 | git reset --hard 251 | ``` 252 | 253 | 回退到某个提交(commit回退,代码保留) 254 | ``` 255 | git reset 256 | ``` 257 | 258 | 回退到某个提交,并保留以更改的文件 259 | ``` 260 | git reset --keep 261 | ``` 262 | 263 | ##### SUBMODULE 264 | 265 | 添加子模块 266 | ``` 267 | git submodule add https://github.com/xxxxxx/Test 268 | ``` 269 | 270 | 克隆你有子模块的项目 271 | ``` 272 | git clone https://github.com/xxxxxx/MainProject 273 | cd MainProject // 子模块目录Test没有文件 274 | cd Test 275 | git submodule init 276 | git submodule update // 执行完后就有子模块的代码了 277 | 278 | //方法二 279 | // 自动更新子模块中的代码 280 | git clone --recurse-submodules https://github.com/xxxxxx/MainProject 281 | ``` 282 | 283 | 合并两个不同的项目 284 | ``` 285 | // 需使用 `--allow-unrelated-histories` 286 | // 将远程master项目合并到你本地项目 287 | git pull origin master --allow-unrelated-histories 288 | ``` -------------------------------------------------------------------------------- /javascript/README.md: -------------------------------------------------------------------------------- 1 | ### JavaScript 2 | JavaScript 是互联网上最流行的脚本语言,这门语言可用于 HTML 和 web,更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备。 3 | 4 | #### JavaScript 数据类型 5 | 6 | 字符串(String)、数字(Number)、布尔(Boolean)、数组(Array)、对象(Object)、空(Null)、未定义(Undefined)。 7 | 8 | #### JavaScript 可以通过不同的方式来输出数据: 9 | - 使用 window.alert() 弹出警告框。 10 | - 使用 document.write() 方法将内容写到 HTML 文档中。 11 | - 使用 innerHTML 写入到 HTML 元素。 12 | - 使用 console.log() 写入到浏览器的控制台。 13 | 14 | #### JavaScript 变量 15 | - 局部 JavaScript 变量: 16 | 在 JavaScript 函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它。(该变量的作用域是局部的)。 17 | 您可以在不同的函数中使用名称相同的局部变量,因为只有声明过该变量的函数才能识别出该变量。 18 | 只要函数运行完毕,本地变量就会被删除。 19 | - 全局 JavaScript 变量: 20 | 在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它。 21 | 22 | JavaScript 变量的生命期从它们被声明的时间开始。局部变量会在函数运行以后被删除。全局变量会在页面关闭后被删除。 23 | 24 | #### JavaScript 事件 25 | - HTML 事件(常用) 26 | + onchange HTML 元素改变 27 | + onclick 用户点击 HTML 元素 28 | + onmouseover 用户在一个HTML元素上移动鼠标 29 | + onmouseout 用户从一个HTML元素上移开鼠标 30 | + onkeydown 用户按下键盘按键 31 | + onload 浏览器已完成页面的加载 32 | + onkeydown 某个键盘按键被按下 33 | + onkeypress 某个键盘按键被按下并松开 34 | + onkeyup 某个键盘按键被松开 35 | + onblur 元素失去焦点时触发 36 | + onfocus 元素获取焦点时触发 37 | + onfocusin 元素即将获取焦点时触发 38 | + onfocusout 元素即将失去焦点时触发 39 | + oninput 元素获取用户输入时触发 40 | + onreset 表单重置时触发 41 | + onsearch 用户向搜索域输入文本时触发 ( ) 42 | + onselect 用户选取文本时触发 (