diff --git a/clean-code/Clean Code Book.md b/clean-code/Clean Code Book.md new file mode 100644 index 0000000000000000000000000000000000000000..4b9ceeb630d38fd6f90d9bced1c55068924249a8 --- /dev/null +++ b/clean-code/Clean Code Book.md @@ -0,0 +1,312 @@ +# 代码整洁之道笔记 + +## 参考文档 + +- [Clean Code 中文](https://www.bookstack.cn/read/Clean-Code-zh/docs-README.md) + +## Later equals never,稍后等于永不 + +- 童子军军规:让营地比你来时更干净。 +- 不要因为一些原因而留下糟糕的代码。 +- 糟糕的代码会使得今后的开发和维护更加的困难,浪费自己时间,也同样浪费别人的时间。 + +## 第 1 章 整洁代码 + +代码是必要的,时刻都要保持整洁的代码。 + +什么是整洁的代码? + +优雅和高效的代码。代码逻辑应当直截了当,叫缺陷难以隐藏;尽量减少依赖关系,使之便于维护;依据某种分层战略完善错误处理代码;性能调至最优,省得引诱别人做没规矩的优化,搞出一堆混乱来。 + +起码要做到以下几点: + +- 能通过所有的测试。 +- 没有重复代码。 +- 体现系统中的全部设计理念。 +- 包含尽量少的实体、比如类、方法、函数等。 + +即整洁的代码需要做到: + +- 职责明确,没有多余 +- 减少依赖,便于维护 +- 高效 + +## 第 2 章 有意义的命名 + +- 名副其实。 + - 一个好的命名可以省去大量的时间。 + - 命名一定要做到,词要达意! + - 说起来很简单。选个好名字需要花时间,但省下的时间比花掉的多。 + - 注意命名,一旦有好的命名,就换掉旧的。 + - 示例: + + ```java + int d;// 消失的时间,以日计。 + int elapsedTimeInDays; + ``` + +- 避免思维映射 + - 例如循环中的 i、j、k 等单字母名称不是个好选择,读者必须在脑中将它映射为真实概念。最好用 filter、map 等方法代替 for循环。 +- 避免误导 + - 比如不是 List 类型,就不要用个 accountList 来命名,这样形成误导。 +- 做有意的区分 + - Variable 一词 永远不应当出现在变量名中。 + - Table 一词永远不应当出现在表名中。 + - NameString 会比 Name 好吗,难道 Name 会是一个浮点数不成。 + - 如有一个 Customer 的类,有又一个 CustomerObject 的类。 +- 类名应该是名词或短语 + - 像 Customer,Account,避免使用 Manager,Processor,Data 或者 Info 这样的类名。 + - 类名不应当是动词。 + - 方法名应该是动词或动词短语。 + - 如 postPayment,deletePage 或 Save,属性访问、修改和断言应该根据其值来命名,并加上 get,set,is 这些前缀。 +- 每个概念对应一个词 + - 在一堆代码中有 Controller,又有 manager,driver 就会令人困惑。 +- 好的名字相当于为代码写了一段有用的注释。 + +## 第 3 章 函数 + +Function should do one thing. They should do it well. They should do it only. + +函数只应该做一件事情,把一件事情做好,而且只由它来做这一件事情。 + +一个好的函数应该满足以下规则: + +- 短小 + - 函数的第一规则是要短小。 + - 第二条规则是还要更短小。 + - 例如 if、else、while 等语句,其中的代码应该只有一行。该行大抵应该是一个函数调用语句。因为块内的函数拥有较具体说明性的名称,从而增加了文档上的价值。 +- 只做一件事,做好这件事 + - 无副作用 + - 确保函数功能就像函数名描述的一样,不要做函数名描述以外的事情。应该为起一个更能描述函数功能的函数名。 +- 参数 + - 尽量少的函数参数。 + - 有两个参数的函数要比一元函数的难懂。 + - 如果需要三个或者三个以上的参数应该封装成类了。 + - 最理想的参数数量是零。 +- 不要重复一段代码 + - 如果一段相同的代码出现了两次,想一想是不是应该抽取方法了。 + +如何写出好函数: + +- 分解函数,抽象分层 +- 一个好的命名 +- 消除重复代码 + +## 第 4 章 注释 + +Comments Do Not Make Up for Bad Code. + +注释不是对劣质代码的补救。 + +- 与其花时间编写解释糟糕的代码注释,不如花时间清洁糟糕的代码。 +- TODO 注释虽好,但也要定期查看,删除不再需要的。 +- 警示,告诉别人要注意这个方法之类的。 +- 放大,有的代码可能看着有点多余,但编码者当时是有他自己的考虑,这个时候需要注释下这个代码的重要性。避免后面被优化掉。 +- 注释掉的代码。 + - 不要的代码应该立即删掉。(有 VCS 可以找回) + +## 第 5 章 格式 + +### 垂直格式 + +- 函数与函数之间留空行 +- 变量声明 + - 变量声明应该尽可能靠近其使用位置。 + - 因为函数很短,本地变量应该在函数的顶部出现。 + - 实体变量应该在内的顶部,相当于我们的 field 字段,会被使用的多。 +- 相关函数 + - 若某个函数调用了另一个函数,就应该把它们放到一起,而且调用者应该尽可能放在被调用者上面。这样程序就有个自然顺序。 +- 概念相关的代码应该放到一起 + - 相关性越强,彼此之间的距离就该越短。 + +### 横向格式 + +- 一行的长度不要太长 +- 赋值语句两端留空 + - `a = b;` +- 不在函数名和左括号间加空格 + - 因为函数与其参数密切相关。 +- 缩进 + - 要体现层级的概念。 + +## 第 6 章 对象和数据结构 + +- 数据抽象 + - 隐藏实现关乎抽象,类并不简单地取值器和赋值器将变量推向外间,而是暴露抽象接口,以便用户无需了解数据的实现就能擦做数据本体。 +- 数据、对象的反对称性 + - 对象把数据隐藏于抽象之后,暴露操作数据的函数。数据结构暴露其数据,没有提供有意义的函数。回头再读一遍,留意这两种定义的本质。他们是对立的,这种差异貌似渺小,但却有深远的意义。对象与数据结构的二分原理: + - 过程式代码(使用数据结构的代码)便于在不改动既有数据结构的前提下添加新函数。面向对象代码便于在不改动既有函数的前提下添加新类。 + - 反过来讲也说得通: 过程式代码难以添加新的数据结构,因为必须修改所有函数。面向对象代码难以添加新函数,因为必须修改所有类。 +- 迪米特法则 + - 模块不应了解它所操作对象的内部情形。对象隐藏数据,暴露操作。者意味着对象不应通过存取其暴露其内部结构,因为这样更像是暴露而非隐藏其内部结构。 +- 数据传送对象 + - 最为精练的数据结构,是一个只有公共变量,没有函数的类。这种数据结构有时被称为数据传送对象,或 DTO。 + +## 第 7 章 错误处理 + +- 使用异常而非返回码。 +- 在编写可能抛出异常的代码时,先写 `try-Catch-Finally`语句。 +- 使用不可控异常:C 使用可控异常的代价是:违反“开放/闭合原则”。对于一般性应用开发,其依赖成本要高于收益。 +- 给出异常发生的环境说明:应创建信息充分的错误消息,并和异常一起传递出去,以便判断错误的来源和处所。 +- 依调用者需要定义异常类(看异常如何被捕获):如打包调用 API 确保返回通用异常类型。 +- 定义常规流程:创建一个类或配置一个对象,用来处理特例。 +- try catch 语句块的范围不要太大,这样不利于对异常的分析。 +- 别返回 null 值,这样可以减少调用者的防御性检测。 + - 与其返回 null,不如抛出异常,或是返回特例对象。 +- 别传递 null 值,传递 null 就要求被调用函数需要一系列防御性检测,也就意味着程序有更大可能出错。 + +## 第 8 章 边界 + +- 使用第三方代码 + - 使用第三方代码时,如果有边界接口,可将其保留在类或近亲中,避免从公共 API 中返回边界接口,或者将其边界接口作为参数传给公共 API。 +- 浏览和学习边界 + - 在利用第三方程序包时,没有测试第三方代码的职责,但为要使用的第三方代码编写测试,可能最符合我们的利益。不要在生成代码中实验新东西,而是编写测试来遍览和理解第三方代码。 +- 学习性测试的好处不只是免费 + - 学习性测试是一种精确试验,帮助我们增进对 api 的理解。当第三方程序包发布了新版本,我们可以运行学习性测验,看看程序包的行为有没有改变。学习性测试确保第三方程序包按照我们想要的方式工作。一旦整合进来,就不能保证第三方代码总与我们的需要兼容。如果第三方程序包的修改与测试不兼容,我们也能马上发现。 +- 整洁的边界 + - 在使用我们控制不了的代码时,必须加倍小心,确保未来的修改代价不会太大。边界上的代码需要清晰的分隔和定义了期望的测试。 + +## 第 9 章 单元测试 + +- TDD 三定律 + - 定律一,在编写不能通过的单元测试前,不可编写生成代码。 + - 定律二,只可编写刚好无法通过的单元测试,不能编译也不算通过。 + - 定律三,只可编写刚好足以通过当前失败测试的生成代码。 +- 保持测试整洁 + - 可读性,可读性,可读性。 + - 如何做到可读,那就是要保证测试代码同其他代码一样,明确,简洁,足具表达力,这也是这本书一直强调的事情。 + - 测试代码和生产代码一样重要。需要被思考,设计和照料。应该和生产代码一样整洁。 +- 每个测试一个断言 + - 在尽可能减少每个概念的断言数量的同时,最好能做到每个测试函数中只测试一个概念。 +- F.I.R.S.T 原则 + - 快速 (Fast) 测试应该够快。 + - 独立 (Independent) 测试应该相互独立。 + - 可重复 (Repeatable) 测试应当可在任何环境中重复通过。 + - 自足验证 (Self-Validating) 测试应该有布尔值输出。 + - 及时 (Timely) 测试应及时编写。 + +## 第 10 章 类 + +- 类的组织 + - 遵循标准的 JAVA 约定,类应该从一组变量列表开始。 + - 变量顺序: + - 公共静态常量 + - 私有静态变量 + - 私有实体变量 + - 很少有公共变量,公共函数应该在变量列表后面。公共函数调用的私有工具函数紧随在该公共函数的后面。 +- 类应该短小 +- 单一权责原则 (SRP) + - 类或模块应有且只有一条加以修改的理由。系统应该有许多短小的类而不是巨大的类组成。 +- 内聚 + - 内聚性高:类中的方法和变量相互依赖、互相结合成一个逻辑整体。 + - 当类丧失了内聚性,就需要拆分它。将大函数拆分为许多小函数,往往也是将类拆分为许多个小类的时机。程序会更有组织,也会拥有更为透明的结构。 +- 为了修改而组织 + - 在整洁的系统中,对类进行组织,以降低修改的风险(通过扩展而非修改现有的代码来添加新的特性)。 + - 隔离修改 + - 遵循依赖倒置原则(DIP),应该依赖于抽象而非具体细节。 + +## 第 11 章 系统 + +Complexity kills. It sucks the life out of developers, it makes products difficult to plan, build and test. + +复杂要人命,它消磨开发者的生命,让产品难于规划、构建和测试。 + +- 将构造和使用分开的方法: + - 分解 main,将系统中的全部构造过程搬迁到 main 或者 main 模块中。 + - main 函数创建对象,再将对象传递给应用程序,应用程序只管使用,对构造一无所知。 + - 如果应用程序需要负责确定何时创建对象,可以创建抽象工厂,让应用程序控制实体创建的时机。 + - 依赖注入,控制反转 IoC 是依赖管理的手段,它将应用需要的依赖对象的创建权责从对象中拿出来,放在一个专注于此事的对象中,并通过依赖注入(赋值器)将依赖对象传递给应用。 +- 扩容: + - 面向方面编程(AOP),Java 中三种方面和类似方面的机制:代理,纯 AOP 框架,AspectJ。 + - java 代理:适用于简单情况,如在单独对象或类中包装方法调用。代码量和复杂度是代理的两大弱点。 + - 纯 Java AOP 框架,如 Spring AOP、JBoss AOP。 + - AspectJ:提供将方面作为模块构造处理支持的 Java 扩展。 +- 最佳系统架构由模块化的关注面领域组成,每个关注面均用纯 Java(或其他语言)对象实现。不同领域之间用最不具有侵害性的方面或类方面工具整合起来。这种架构能测试驱动,就像代码一样。 +- 拥有模块化关注面的 POJO 系统提供的敏捷能力,允许我们基于最新的知识做出优化的、时机刚好的决策。决策的复杂性也降低了。 +- 领域特定语言(DSL)允许所有抽象层级和应用程序中的所有领域,从高级策略到底层细节,使用 POJO 来表达。 + +## 第 12 章 迭进 + +简单设计规则 + +- 运行所有测试 + - 不可测试的系统不可验证,不可验证的系统,绝不能部署。 +- 不可重复 + - 通过抽取或是模板方法整合重复代码。 + - 示例: + + ```java + int size(); + bool isEmpty(); + ``` + + 这两个方法可以分别实现,但可以在 `isEmpty` 中使用 `size` 消除重复。 + + ```java + bool isEmpty() { + return size() == 0; + } + ``` + +- 表达力 + - 选用好的名称来表达。 +- 尽可能少的类 + +## 第 13 章 并发编程 + +- 为什么要并发 + - 并发是一种解耦策略,它帮助我们把做什么(目的)和何时(时机)做分解开。 + - 解耦目的与时机能明显地改进应用程序的吞吐量和结构。 + - 单线程程序许多时间花在等待 web 套接字 I/O 结束上面,通过采用同时访问多个站点的多线程算法,就能改进性能。 +- 常见的迷思和误解 + - 并发总能改进性能 + - 只在多个线程或处理器之间能分享大量等待时间的时候管用。 + - 编写并发程序无需修改设计 + - 可能与单线程系统的设计极不相同。 + - 在采用 web 或 ejb 容器时,理解并发问题并不重要。 +- 有关编写并发软件的中肯的说法 + - 并发会在性能和编写额外代码上增加一些开销。 + - 正确的并发是复杂的,即使对于简单的问题也是如此。 + - 并发缺陷并非总能重现,所以常被看做偶发事件而忽略,未被当做真的缺陷看待。 + - 并发常常需要对设计策略的根本性修改。 +- 并发防御原则 + - 单一权责原则 + - 限制数据作用域 + - 使用数据副本 + - 线程应尽可能独立 +- 了解 Java 库 + - 使用类库提供的线程安全群集 + - 使用 executor 框架(executor framework)执行无关任务 + - 尽可能使用非锁定解决方案 + - 有几个类并不是线程安全的 +- 了解执行模型 +- 警惕同步方法之间的依赖 +- 保持同步区域微小 +- 很维编写正确的关闭代码 + - 平静关闭很难做到,常见问题与死锁有关,线程一直等待永远不会到来的信号。 + - 建议:尽早考虑关闭问题,尽早令其工作正常。 +- 测试线程代码 + - 建议:编写有潜力曝露问题的测试,在不同的编程配置、系统配置和负载条件下频繁运行。如果测试失败,跟踪错误。别因为后来测试通过了后来的运行就忽略失败。 + - 将伪失败看作可能的线程问题 + - 线程代码导致“不可能失败的”失败,不要将系统错误归咎于偶发事件。 + - 先使非线程代码可工作 + - 不要同时追踪非线程缺陷和线程缺陷,确保代码在线程之外可工作 + - 编写可插拔的线程代码,能在不同的配置环境下运行。 + - 编写可调整的线程代码 + - 允许线程依据吞吐量和系统使用率自我调整。 + - 运行多于处理器数量的线程 + - 任务交换越频繁,越有可能找到错过临界区域导致死锁的代码。 + - 在不同平台上运行 + - 尽早并经常地在所有目标平台上运行线程代码。 + - 装置试错代码 + - 增加对 `Object.wait()`、`Object.sleep()`、`Object.yield()`、`Object.priority()` 等方法的调用,改变代码执行顺序,硬编码或自动化。 + +## 第 14 章 逐步改进 + +## 第 15 章 JUnit 内幕 + +## 第 16 章 重构 SerialDate + +## 第 17 章 味道与启发 + +## 附录 A 并发编程 II diff --git a/docker/Docker.md b/docker/Docker.md new file mode 100644 index 0000000000000000000000000000000000000000..0639ae3454371d7e78dca73b89df4dbad98f0f0b --- /dev/null +++ b/docker/Docker.md @@ -0,0 +1,543 @@ +# Docker 笔记 + +## 参考文档 + +- [Docker 菜鸟](https://www.runoob.com/docker/docker-tutorial.html) + +## CI/CD + +- continuous integration,持续集成 +- continuous delivery,持续交付 +- continuous deployment,持续部署 + +## Docker 简介 + +Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。 + +Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。 + +容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。 + +### 三个基本概念 + +- 镜像(Image):Docker 镜像, + - 相当于是一个 root 文件系统。 + - 比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。 +- 容器(container): + - 镜像和容器的关系,就像是类和实例的关系一样。 + - 镜像是静态的定义,容器就像是镜像运行时的实体。 + - 容器可以创建、启动、停止、删除、暂停等。 +- 仓库(Repository): + - 仓库可以看成是一个代码控制中心,用来保存镜像。 + +### STATUS 容器状态 + +状态有7种: + +- `created`(已创建) +- `restarting`(重启中) +- `running` 或 `Up`(运行中) +- `removing`(迁移中) +- `paused`(暂停) +- `exited`(停止) +- `dead`(死亡) + +## 命令的使用 + +- 直接输入 `docker` 命令来查看到 Docker 客户端的所有命令选项。 +- 通过命令 `docker command --help` 更深入的了解指定的 Docker 命令使用方法。 + +## 容器的使用 + +### 获取镜像 + +- 如果我们本地没有 ubuntu 镜像,我们可以使用 `docker pull` 命令来载入 ubuntu 镜像: + - `docker pull ubuntu` + +### 启动容器 + +- 以下命令使用 ubuntu 镜像启动一个容器,参数为以命令行模式进入该容器: + - `docker run -it ubuntu /bin/bash` + - 参数说明: + - -i: 交互式操作。 + - -t: 终端。 + - ubuntu: ubuntu 镜像。 + - `/bin/bash`:放在镜像名后的是命令 + - 这里我们希望有个交互式 Shell,因此用的是 `/bin/bash`。 +- 要退出终端,直接输入 `exit`。 + +### 启动已停止运行的容器 + +- `docker ps -a`,查看所有容器。 +- `docker ps`, +- 启动一个已停止的容器,`docker start`。 + +### 后台运行 + +在大部分的场景下,我们希望 docker 的服务是在后台运行的,我们可以过 -d 指定容器的运行模式。 + +- `docker run -itd --name ubuntu-test ubuntu /bin/bash` +- `-d` 参数默认不会进入容器。 + +### 停止 / 重启一个容器 + +- `docker stop <容器 ID>`,停止 +- `docker restart <容器 ID>`,重启 + +### 进入容器 + +在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入: + +- `docker attach` + - `docker attach 1e560fca3906` +- `docker exec` + - `docker exec -it 243c32535da7 /bin/bash` +- 推荐使用 `docker exec` 命令,因为这个退出容器终端,不会导致容器的停止。 + +### 导出和导入容器 + +#### 导出 + +- `docker export` 命令,导出本地某个容器。 + - `docker export 1e560fca3906 > ubuntu.tar` + - 导出容器 1e560fca3906 快照到本地文件 ubuntu.tar。 + +#### 导入 + +- `docker import` 从容器快照文件中再导入为镜像。 + - `cat docker/ubuntu.tar | docker import - test/ubuntu:v1` + - 将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1 + +#### 指定 url 进行导入 + +- `docker import http://example.com/exampleimage.tgz example/imagerepo` + +### 删除容器 + +- `docker rm ID` +- `docker container prune`,清理掉所有处于终止状态的容器。 + +## 运行一个 WEB 应用 + +- `docker pull training/webapp` # 载入镜像 +- `docker run -d -P training/webapp python app.py` + - `-d`:让容器在后台运行。 + - `-P`:将容器内部使用的网络端口随机映射到我们使用的主机上。 +- 也可以通过 `-p` 参数来设置不一样的端口: + - `docker run -d -p 5000:5000 training/webapp python app.py` + +### 查看网络端口 + +1. `docker ps` +1. `docker <容器 ID 或者 容器 name>` + +### 查看 WEB 应用程序日志 + +- `docker logs [ID 或者名字]`,可以查看容器内部的标准输出。 +- 例如 + - `docker logs -f bf08b7f2cd89` + - `-f` + - 让 `docker logs` 像使用 `tail -f` 一样来输出容器内部的标准输出。 + - `-t`,显示时间戳 + +### 查看容器内的进程 + +- `docker top [name / id]` + +### 检查 WEB 应用程序 + +- `docker inspect [name / id]`,检查 Docker 的底层信息。 +- 它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。 + +### 停止 / 重启 WEB 应用容器 + +- `docker stop [name / id]` +- `docker restart [name / id]` + +### 移除 WEB 应用容器 + +- `docker rm [name / id]` +- 删除容器时,容器的状态必须是停止状态。 + +## 镜像的使用 + +当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。 + +Docker 的默认存储位置 var/lib/docker + +### 列出镜像列表 + +- `docker images`,列出本地主机的镜像。 +- 各个选项说明: + - `REPOSITORY`:表示镜像的仓库源 + - `TAG`:镜像的标签 + - `IMAGE ID`:镜像ID + - `CREATED`:镜像创建时间 + - `SIZE`:镜像大小 +- 使用 `REPOSITORY:TAG` 来定义不同的镜像。 + +### 获取一个新的镜像 + +- `docker pull ubuntu:13.10` + +### 查找镜像 + +- `docker search httpd` +- 参数说明: + - `NAME`: 镜像仓库源的名称 + - `DESCRIPTION`: 镜像的描述 + - `OFFICIAL`: 是否 docker 官方发布 + - `stars`: 类似 Github 里面的 star,表示点赞、喜欢的意思。 + - `AUTOMATED`: 自动构建。 + +### 删除镜像 + +- `docker rmi hello-world` +- 注意,这里是 **`rmi`**,rm iamge,删除容器是 rm。 + +### 创建镜像 + +当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。 + +1. 从已经创建的容器中更新镜像,并且提交这个镜像。 +1. 使用 Dockerfile 指令来创建一个新的镜像。 + +### 更新镜像 + +更新镜像之前,需要使用镜像来创建一个容器。 + +1. 在运行的镜像内使用 `apt-get update` 来更新镜像。 +1. 完成操作,输入 exit 退出这个容器。 +1. `docker commit`,提交容器副本。 + - 例如,`docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2` + - 参数说明: + - `-m`: 提交的描述信息 + - `-a`: 指定镜像作者 + - `e218edb10161`:容器 ID + - `runoob/ubuntu:v2`: 指定要创建的目标镜像名 +1. 查看新镜像,`docker images`。 +1. 使用新镜像来启动一个容器。 + - 例如:`docker run -t -i runoob/ubuntu:v2 /bin/bash` + +### 构建镜像 + +使用命令 `docker build`, 从零开始来创建一个新的镜像。为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。 + +1. 创建 Dockerfile 文件。 + + ```bash + FROM centos:6.7 + MAINTAINER Fisher "fisher@sudops.com" + + RUN /bin/echo 'root:123456' |chpasswd + RUN useradd runoob + RUN /bin/echo 'runoob:123456' |chpasswd + RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local + EXPOSE 22 + EXPOSE 80 + CMD /usr/sbin/sshd -D + ``` + + - 每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。 + - 第一条 FROM,指定使用哪个镜像源 + - RUN 指令告诉 docker 在镜像内执行命令,安装了什么。 + +1. 使用 docker build 命令进行构建。 + - `docker build -t runoob/centos:6.7 .` + - `-t`:指定要创建的目标镜像名 + - `.`:Dockerfile 文件所在目录,可以指定 Dockerfile 的绝对路径 + +### 设置镜像标签 + +- `docker tag 860c279d2fec runoob/centos:dev` +- `docker tag [容器 ID] [用户名]/[镜像源名]:[新标签名]` + +## 容器连接 + +### 网络端口映射 + +- 本地端口:容器端口 +- `-P`:是容器内部端口 *随机* 映射到主机的端口。 +- `-p`:是容器内部端口绑定到 *指定* 的主机端口。 + +## 仓库管理 + +目前 Docker 官方维护了一个公共仓库 Docker Hub。 + +大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。 + +在 https://hub.docker.com 免费注册一个 Docker 账号。 + +登录需要输入用户名和密码,登录成功后,我们就可以从 docker hub 上拉取自己账号下的全部镜像。 + +- 登录,`docker login` +- 退出,`docker logout` + +### 拉取镜像 + +- 使用 `docker search` 查找镜像,然后使用 `docker pull` 将它下载到本地。 + +### 推送镜像 + +1. `docker push username/ubuntu:18.04` + - `docker push [用户名]/[镜像名]:[标签名]` +2. `docker search username/ubuntu` + +## Dockerfile + +Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。 + +### 定制镜像 + +例如定制一个 nginx 镜像(构建好的镜像内会有一个 /usr/share/nginx/html/index.html 文件): + +1. 在一个空目录下,新建一个名为 Dockerfile 文件,并在文件内添加以下内容: + + ```bash + FROM nginx + RUN echo '这是一个本地镜像' > /usr/share/nginx/html/index.html + ``` + + - FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。 + - RUN:用于执行后面跟着的命令行命令。有以下俩种格式: + - shell 格式: + - `RUN <命令行命令> 参数1 参数2` + - <命令行命令> 等同于,在终端操作的 shell 命令。 + - exec 格式: + - `RUN ["可执行文件", "参数1", "参数2"]` + - 例如: + - `RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline` +1. 在 Dockerfile 文件的存放目录下,执行构建动作。 + - 以下示例,通过目录下的 Dockerfile 构建一个 nginx:v3(镜像名称:镜像标签)。 + - 注:最后的 . 代表本次执行的上下文路径,下一节会介绍。 + +### 上下文路径 + +`docker build -t nginx:v3 .`,指令最后一个 `.` 是上下文路径。 + +- 上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),`docker build` 命令得知这个路径后,会将路径下的所有内容打包。 + +- 解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。 + +- 如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。 + +**注意:** 上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。 + +### 指令集 + +#### **COPY** + +复制指令,从上下文目录中复制文件或者目录到容器里指定路径。 + +- 格式: + + ```bash + COPY [--chown=:] <源路径1>... <目标路径> + COPY [--chown=:] ["<源路径1>",... "<目标路径>"] + [--chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。 + ``` + + - <源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如: + + ```bash + COPY hom* /mydir/ + COPY hom?.txt /mydir/ + ``` + + - <目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。 + +#### **ADD** + +ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下: + +ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。 +ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。 + +#### **CMD** + +类似于 RUN 指令,用于运行程序,但二者运行的时间点不同: + +- CMD 在docker run 时运行。 +- RUN 是在 docker build。 + +作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。 + +**注意:** 如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。 + +- 格式: + + ```bash + CMD + CMD ["<可执行文件或命令>","","",...] + CMD ["","",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数 + ``` + +推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。 + +#### **ENTRYPOINT** + +类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。 + +但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 CMD 指令指定的程序。 + +优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。 + +注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。 + +格式: + +ENTRYPOINT ["","","",...] +可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。 + +示例: + +假设已通过 Dockerfile 构建了 nginx:test 镜像: + +FROM nginx + +ENTRYPOINT ["nginx", "-c"] # 定参 +CMD ["/etc/nginx/nginx.conf"] # 变参 +1、不传参运行 + +$ docker run nginx:test +容器内会默认运行以下命令,启动主进程。 + +nginx -c /etc/nginx/nginx.conf +2、传参运行 + +$ docker run nginx:test -c /etc/nginx/new.conf +容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件) + +nginx -c /etc/nginx/new.conf + +#### **ENV** + +设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。 + +格式: + +ENV +ENV = =... +以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用: + +ENV NODE_VERSION 7.2.0 + +RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \ + && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" + +#### **ARG** + +构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。 + +构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。 + +格式: + +ARG <参数名>[=<默认值>] + +#### **VOLUME** + +定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。 + +作用: + +避免重要的数据,因容器重启而丢失,这是非常致命的。 +避免容器不断变大。 +格式: + +VOLUME ["<路径1>", "<路径2>"...] +VOLUME <路径> +在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。 + +#### **EXPOSE** + +仅仅只是声明端口。 + +作用: + +帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。 +在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。 +格式: + +EXPOSE <端口1> [<端口2>...] + +#### **WORKDIR** + +指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。 + +docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。 + +格式: + +WORKDIR <工作目录路径> + +#### **USER** + +用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。 + +格式: + +USER <用户名>[:<用户组>] + +#### **HEALTHCHECK** + +用于指定某个程序或者指令来监控 docker 容器服务的运行状态。 + +格式: + +HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令 +HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令 + +HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。 + +#### **ONBUILD** + +用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。 + +格式: + +ONBUILD <其它指令> + +#### **LABEL** + +LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下: + +LABEL = = = ... +比如我们可以添加镜像的作者: + +LABEL org.opencontainers.image.authors="runoob" + +## Compose + +### 简介 + +- Compose 是用于定义和运行多容器 Docker 应用程序的工具。 +- 通过 Compose,可以使用 YML 文件来配置应用程序需要的所有服务。 +- 然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。 + +### 使用步骤 + +1. 使用 Docker 定义应用程序的环境。 +1. 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。 +1. 最后,执行 `docker-compose up` 这个命令来启动并运行整个应用程序。 + +- docker-compose.yml 配置案例如下: + + ```bash + # yaml 配置实例 + version: '3' + services: + web: + build: . + ports: + - "5000:5000" + volumes: + - .:/code + - logvolume01:/var/log + links: + - redis + redis: + image: redis + volumes: + logvolume01: {} + ``` diff --git a/git/Git Advance.md b/git/Git Advance.md new file mode 100644 index 0000000000000000000000000000000000000000..47051cb46c455db9d4123dc772ebc38a64427e89 --- /dev/null +++ b/git/Git Advance.md @@ -0,0 +1,63 @@ +# Git 笔记 + +## 参考文档 + +- [Pro Git](https://git-scm.com/book/en/v2) + +## HEAD + +所有的操作都是在 HEAD 进行。 + +- `git checkout 分支名`,那么 HEAD -> 分支 -> commitId(hash) +- `git checkout hash`,那么 HEAD -> commitId(hash) + +## branch + +- `git branch -f 分支名`,如何移动 + +## cherry-pick + +`git cherry-pick` 要获取的 commitId ...<可以多个> + +## rebase + +`git rebase A B`,意思是 B 以 A 为基,并切换到 B 分支。(B 在 A 后面) + +## origin/branch + +当你 git fetch 的时候,拉下来的是远程的 o/branch,这里的 o/branch 不会自己移动,只有远程的 branch 有了新的提交,它才会移动。 + +一般使用 git fetch,将远程分支的当前位置拉下来,然后现在本地会有 o/branch,这时候,你执行 git rebase o/branch,将当前分支变基到 o/branch 再进行提交,就不会出错了。 + +## checkout -- filename + +撤销现有的所有修改,将未暂存的修改撤销。 + +- 如果已经 add,这时候再写 aaa,这时候撤销只会撤销 aaa。 +- 如果没有 add,这时候撤销会回到上一次 commit 的状态。 + +## restore + +将暂存区的内容撤销。 + +- `git restore`,清空未暂存的修改 +- `git restore --staged`,仅将文件撤销暂存 + +## reset + +- `git reset --hard`,清空暂存区和本地 + +## git 实战 + +- 强制修改分支位置 + - `git branch -f <目标分支> HEAD~3`,使用 -f。 +- 改变提交记录 + - 就是将指定的提交(commit)应用到当前分支 + - `git cherry-pick ` + - `git rebase -i <往前几次提交>`,界面化的。 + - `git rebase A B`,就是将 B 的 commit 添加在 A 的后面。 +- checkout 改变 HEAD,branch -f 改变分支所处的 commit +- `git describe` 的语法是: + - `git describe `,`` 可以是任何能被 Git 识别成提交记录的引用,如果你没有指定的话,Git 会以你目前所检出的位置(HEAD)。 +- `git pull` 就是 `fetch 和 merge` 的简写 + - 类似的 `git pull --rebase` 就是 fetch 和 rebase 的简写! diff --git a/git/Git Base.md b/git/Git Base.md new file mode 100644 index 0000000000000000000000000000000000000000..8fe15d44a7773bcbea566317ad8c9b242c69b0b1 --- /dev/null +++ b/git/Git Base.md @@ -0,0 +1,404 @@ +# Git 笔记 + +## 参考文档 + +- [Pro Git](https://git-scm.com/book/en/v2) +- [廖雪峰 Git](https://www.liaoxuefeng.com/wiki/896043488029600) +- [Git Learn Games](https://learngitbranching.js.org/?locale=zh_CN) + +## 安装 + +- 在 Linux 上安装 + + 如果你想在 Linux 上用二进制安装程序来安装基本的 Git 工具,可以使用发行版包含的基础软件包管理工具来安装。 + - 以 Fedora 为例,如果你在使用它(或与之紧密相关的基于 RPM 的发行版,如 RHEL 或 CentOS),你可以使用 dnf: + - `$ sudo dnf install git-all` + - 如果你在基于 Debian 的发行版上,如 Ubuntu,请使用 apt: + - `$ sudo apt install git-all` + +## git 的三种状态/ 阶段 + +### 三种状态 + +- 已修改 - 修改了文件,还没有保存到数据库。 +- 已暂存 - 表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。 +- 已提交 - 数据已经安全地保存在本地数据库中。 + +### 三种阶段 + +以上的三种状态对应Git 项目拥有三个阶段:工作区、暂存区以及 Git 目录。 + +- 工作区:对项目的某个版本独立提取出来的内容。 + - 这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改。 +- 暂存区:一个文件,保存了下次将要提交的文件列表信息,一般在 Git 仓库目录中。 + - 按照 Git 的术语叫做“索引”,不过一般说法还是叫“暂存区”。 +- Git 仓库目录:Git 用来保存项目的元数据和对象数据库的地方。 + - 这是 Git 中最重要的部分,从其它计算机克隆仓库时,复制的就是这里的数据。 + +## 工作流程 + +1. 在工作区中修改文件。 +2. 将你想要下次提交的更改选择性地暂存,这样只会将更改的部分添加到暂存区。 +3. 提交更新,找到暂存区的文件,将快照永久性存储到 Git 目录。 + +## 帮助 + +- Git 命令的综合手册(manpage): + - `git help`,bash 下有效 + - `git --help` + - `man git` +- `git config` 命令的手册,执行 + - `git help config` + +## Git 基础 + +### 获取一个仓库 + +- 新建,将尚未进行版本控制的本地目录转换为 Git 仓库。 + - 切换到工程的根目录下,再执行 `git init`。 +- 从其它服务器克隆一个已存在的 Git 仓库。 + - `git clone ` + +### 记录每次更新到仓库 + +- 检查当前文件状态 + - `git status` 详细展示 + - `git -s` 或者 `git --short` 状态简览。 + - 新添加的未跟踪文件前面有 `??` 标记。 + - 新添加到暂存区中的文件前面有 `A` 标记。 + - 修改过的文件前面有 `M` 标记。 +- `git add` 开始跟踪一个文件,如果后面跟的是一个目录,那么将会跟踪该目录下的所有文件。 +- `Changes not staged for commit` 这行内容下面的文件,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。 +- 要暂存这次更新,需要运行 `git add` 命令。 +- 忽略文件 + - 创建一个名为 `.gitignore` 的文件 + - 忽略文件规范 + - 所有空行或者以 `#` 开头的行都会被 Git 忽略。 + - 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。 + - glob 模式是指 shell 所使用的简化了的正则表达式。 + - 星号 `*` 匹配零个或多个任意字符; + - `[abc]` 匹配任何一个列在方括号中的字符 + - 这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c; + - 问号 `?` 只匹配一个任意字符; + - 如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配 + - 比如 [0-9] 表示匹配所有 0 到 9 的数字. 使用两个星号 `*` 表示匹配任意中间目录,比如 a//z 可以匹配 a/z 、 a/b/z 或 a/b/c/z 等。 + - 匹配模式可以以 `/` 开头防止递归。 + - `/usr` 的意思是只对这一层目录有效。 + - 匹配模式可以以 `/` 结尾指定目录。 + - 例如: `usr/` 的意思就是指定只是 usr 这个文件夹。 + - 要忽略指定模式以外的文件或目录,可以在模式前加上叹号 `!` 取反。 +- 查看已经暂存和未暂存的修改 + - `git diff`,这里以补丁的形式进行展示。 + - `git diff` 展示的是未暂存的修改(已暂存的不显示) + - `git diff --staged` 或者 `--cached` 参数,展示的是已暂存的修改。 +- 提交文件 + - `git commit -m 'information'`进行提交,提交时记录的是放在暂存区域的快照。 + - 任何还未暂存文件的仍然保持已修改状态,可以在下次提交时纳入版本管理。 + - 每一次运行提交操作,都是对你项目做一次快照,以后可以回到这个状态,或者进行比较。 + - `git commit -a`,跳过 add,但是如果是新建的文件还是需要 add。 +- 跳过使用暂存区 + - `git commit -a` ,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤。 +- 移除文件 + - Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 + - `git rm`,移除文件, 删除工作区(本地)文件,并且将这次删除放入暂存区。 + - **注意:** 要删除的文件是没有修改过的,并且没加到暂存区的,就是说和当前版本库文件的内容相同。 + - `git rm --cached filename`,删除暂存区文件,但保留工作区的文件,并且将这次删除放入暂存区。本地文件取消跟踪。 + - `git rm -f`,删除工作区和暂存区文件,并且将这次删除放入暂存区。 + - 就是说,要删除的文件只要修改过,`git rm` 就删除不了。删除后再提交,删除版本库。 + - 实例 + - 一个文件 test,使用 `rm test` 命令在本地删除以后,并没有从暂存区删除。 + - 如果想要从暂存区删除,那么需要 `git add test` ,将这个文件的变动记录到暂存区,然后 `git commit -m 'delete test'`,到这里,这个文件在暂存区和版本库中也被删除了。 +- 移动文件/重命名 + - `git mv file_from file_to` + - 实例 + - `git mv README.md README` + - 运行 git mv 就相当于运行了下面三条命令: + - `mv README.md README` + - `git rm README.md` + - `git add README` + +### 查看提交历史 + +- `git log -number`,时间最近的在上面,数字限制展示几条。 + - `-p` 或者 `--patch`,将每次的改动详情也展示出来,按补丁格式显示每个提交引入的差异。 + - `--stat`,简要统计信息,显示每次提交的文件修改统计信息。 + - `--pretty`,选择格式展示,使用其他格式显示历史提交信息。 + + 可用的选项包括: + + - oneline + - short + - full + - fuller + - format(用来定义自己的格式) + + 例如: + + - `git -log --pretty=oneline`, + - online 会将每个提交放在一行显示,在浏览大量的提交时非常有用。 + - 另外还有 short,full 和 fuller 。 + - `format`,定制显示样式 + - 比如: + - `git log --pretty=format:"%h - %an, %ar : %s"` + - `%H` - 提交的完整哈希值 + - `%h` - 提交的简写哈希值 + - `%T` - 树的完整哈希值 + - `%t` - 树的简写哈希值 + - `%P` - 父提交的完整哈希值 + - `%p` - 父提交的简写哈希值 + - `%an` - 作者名字 + - `%ae` - 作者的电子邮件地址 + - `%ad` - 作者修订日期(可以用 --date=选项 来定制格式) + - `%ar` - 作者修订日期,按多久以前的方式显示 + - `%cn` - 提交者的名字 + - `%ce` - 提交者的电子邮件地址 + - `%cd` - 提交日期 + - `%cr` - 提交日期(距今多长时间) + - `%s` - 提交说明 + - `--shortstat`,只显示 `--stat` 中最后的行数修改添加移除统计。 + - `--name-only`,仅在提交信息后显示已修改的文件清单。 + - `--name-status`,显示新增、修改、删除的文件清单。 + - `--abbrev-commit`,仅显示 SHA-1 校验和所有 40 个字符中的前几个字符。 + - `--relative-date`,使用较短的相对时间而不是完整格式显示日期(比如“2 weeks ago”)。 + - `--graph`,在日志旁以 ASCII 图形显示分支与合并历史。 + - `--oneline`,是 `--pretty=oneline --abbrev-commit` 合用的简写。 +- 限制输出长度 + - `--since`, `--after`,仅显示指定时间之后的提交。 + + 例如: + + - `git log --since=2.weeks`,最近两周的。 + - 该命令可用的格式十分丰富。 + - 可以是类似 "2008-01-15" 的具体的某一天 + - 也可以是类似 "2 years 1 day 3 minutes ago" 的相对日期。 + - `--until`,`--before`,仅显示指定时间之前的提交。 + - `--author`,仅显示作者匹配指定字符串的提交。 + - `--committer`,仅显示提交者匹配指定字符串的提交。 + - `--grep`,仅显示提交说明中包含指定字符串的提交。 + - `-S`,仅显示添加或删除内容匹配指定字符串的提交。 + + 例子 + + 查看 Junio Hamano 在 2008 年 10 月其间, 除了合并提交之外的哪一个提交修改了测试文件,可以使用下面的命令: + - `git log --pretty="%h - %s" --author='Junio C Hamano' --since="2008-10-01" \ --before="2008-11-01" --no-merges -- t/` + +### 撤销操作 + +- 重新提交 + - `git commit --amend`,修改上一次提交。 + - 例如,提交后发现忘记了暂存某些需要的修改,可以像下面这样操作: + - `git commit -m 'initial commit'` + - `git add forgotten_file` + - `git commit --amend` + - 最终你只会有一个提交,第二次提交将代替第一次提交的结果。 +- 取消暂存文件 + - `git reset,git reset HEAD ...` +- 撤销对文件的修改 + - `git checkout -- file...`,本地文件的任何修改都会消失,Git 会用最近提交的版本覆盖掉它。 + - `git reset <重置到哪里>` + - 清空暂存区,撤销 add,本地修改还在 + - 参数可以使用相对 `HEAD~1`,就是说回退上一位置。修改 HEAD 的位置,即将 HEAD 指向的位置改变为之前存在的某个版本。 + - 回退以后会提示没有任何需要提交的,这个时候强制 push,将会清空远程已有的提交。 + - `--hard` + - 清空工作目录和暂存区的改动,本地和暂存区全都撤回到那一刻。 + - `--soft` + - 保留工作目录的内容,并把因为保留工作目录内容所带来的新的文件差异放进暂存区。 + - 移动 HEAD 到指定的 commit 节点,但保留 工作区和暂存区的内容,简单来说就是你的代码还在只是变成了未提交状态或未添加状态 + - `git revert <需要反做的目标>` + - 撤销 commit,在我们要撤销的提交记录后面居然多了一个新提交!这是因为新提交记录 C2' 引入了更改。这些更改刚好是用来撤销 C2 这个提交的。也就是说 C2' 的状态与 C1 是相同的。(顺序:C0 - C1 - C2 - C2') + +### 远程仓库的使用 + +- 操作远程仓库 + - `origin`,Git 给克隆的仓库(远程)服务器的默认名字。 + - `git remote`,不带参数,列出已经存在的远程分支。 + - `git remote -v | --verbose`,列出详细信息,在每一个名字后面列出其远程 url,此时,`-v` 选项(译注:此为 `–verbose` 的简写,取首字母),显示对应的克隆地址。 + - `git remote add url`,添加一个新的远程 Git 仓库,同时指定一个方便使用的简写。 + - `git remote show `,查看某个仓库。 + - `git remote rename <修改前> <修改后name>`,远程仓库的重命名。 + - `git remote rm` 或者是 `git remote remove`,移除一个远程仓库。一旦你使用这种方式删除了一个远程仓库,那么所有和这个远程仓库相关的远程跟踪分支以及配置信息也会一起被删除。 +- 从远程仓库抓取和拉取 + - `git fetch `,这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。 + - `git fetch` 只会将数据下载到你的本地仓库,它并不会自动合并或修改你当前的工作。 + - 当准备好时你必须手动将其合并入你的工作。`git fetch` 更新你的远程跟踪分支 + - `git fetch `,拉取指定分支。 + - `git fetch :`,拉取到本地,指定分支。 + - `git pull`,自动抓取后合并该远程分支到当前分支。 + - `git pull = git fetch + git merge` + - 默认情况下,`git clone` 命令会自动设置本地 master 分支跟踪克隆的远程仓库的 master 分支(或其它名字的默认分支)。 + - 运行 `git pull` 通常会从最初克隆的服务器上抓取数据并自动尝试合并到当前所在的分支。 +- 推送到远程仓库 + - `git push <远程主机名> <本地分支名> <远程分支名>` + - `git push origin master:refs/for/master` + - 将本地的 master 分支推送到远程主机 origin 上的对应 master 分支。 + - origin 是远程主机名 + - 第一个 master 是本地分支名 + - 第二个 master 是远程分支名 + - `git push origin master` + - 如果远程分支被省略,如上则表示将本地分支推送到与之存在追踪关系的远程分支(通常两者同名) + - 如果该远程分支不存在,则会被新建。 + - `git push origin :refs/for/master` + - 如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支 + - 等同于 `git push origin --delete master` + - `git push origin` + - 如果当前分支与远程分支存在追踪关系,则本地分支和远程分支都可以省略 + - 将当前分支推送到 origin 主机的对应分支 + - `git push` + - 如果当前分支只有一个远程分支,那么主机名都可以省略 + - 形如 `git push`,可以使用 `git branch -r` ,查看远程的分支名。 + +### git 标签 + +- `git tag`,查看(列出)标签。 + - 参数 `-l` 或者 `--list` + - 可以使用 `git tag -l 'string'` 筛选内容。 +- 打标签 + - 标签分为: + - 附注标签 + - 轻量标签 + - 默认标签是打在最新提交的commit上的。 + - 轻量标签 + - `git tag ` + - 附注标签 + - `git tag -a -m "description"` + - 带有说明的标签: + - `-a` 指定标签名 + - `-m` 指定说明文字 + - 如果没有为附注标签指定一条信息,Git 会启动编辑器要求你输入信息。 +- `git show `,查看具体标签信息,命令可以看到标签信息和与之对应的提交信息。 +- `git tag ` + - 给历史提交打标签。 +- `git push <远程主机名> ` + - 推送某个标签 +- `git push origin --tags` + - 推送所有标签到远程。 +- 删除标签 + - `git tag -d `,这只会删除本地的标签。 + - 如果要删除远程的标签的话 + - `git push origin --delete ` +- 检出标签 + - `git checkout ` + +### 设置 git 别名 + +- `git config --global alias.co checkout` +- `git config --global alias.br branch` +- `git config --global alias.ci commit` +- `git config --global alias.st status` + +## 分支 + +- 查看分支列表 + - `git branch` + 看每一个分支的最后一次提交 + - `git branch -v` + 查看已经/没有合并到当前分支的分支列表 + - `--merged` + - `--no-merged` + - 可以指定当前分支的分支名 + - `git branch --merged ` +- 创建分支 + - `git branch branchname` +- 切换分支 + - `git checkout branch` +- 创建同时切换到新分支 + - `git checkout -b ` + - `git checkout --track origin/dev` 等同于 `git checkout -b dev origin/dev` +- 删除分支 + - `git branch -d branchname` + - `-D` 强制删除。 +- 删除远程分支 + - `git push origin --delete branchname` + - 基本上这个命令做的只是从服务器上移除这个指针。Git 服务器通常会保留数据一段时间直到垃圾回收运行,所以如果不小心删除掉了,通常是很容易恢复的。 +- 合并时遇到冲突,解决冲突文件以后,一旦暂存这些原本有冲突的文件,Git 就会将它们标记为冲突已解决。 +- 查看远程分支 + - 注意与 `git remote` 查看远程仓库不同 + - `git ls-remote <远程主机>`,简单列表 + - `git remote show <远程主机名>`,更多信息。 +- 跟踪分支 + - 查看所有跟踪分支 + - `git branch -vv`, + - “ahead” 是 2,意味着本地有两个提交还没有推送到服务器上。 + - 修改正在跟踪的远程分支 + - `git branch -u <远程分支> <本地分支>` + - `-u` 等同于 `--set-upstream-to` + - 设置好跟踪分支后,可以通过简写 `@{upstream}` 或 `@{u}` 来引用它的上游分支。 + + 比如: + + - 在 master 分支时并且它正在跟踪 origin/master 时,如果愿意的话可以使用 `git merge @{u}` 来取代 `git merge origin/master`。 + - 需要重点注意的一点是这些数字的值来自于你从每个服务器上最后一次抓取的数据。 这个命令并没有连接服务器,它只会告诉你关于本地缓存的服务器数据。 + - 如果想要统计最新的领先与落后数字,需要在运行此命令前抓取所有的远程仓库。 + - `git fetch --all; git branch -vv` +- 变基 + - 只对尚未推送或分享给别人的本地修改执行变基操作清理历史。 + - 不要对已推送至别处的提交执行变基操作。 + +## 协议 + +- 本地协议(Local),通常使用普通路径,因为这样更快。 + - 指定路径 + - `git clone /srv/git/project.git` + - Git 会尝试使用硬链接(hard link)或直接复制所需要的文件。 + - 指定 `file://` + - `git clone file:///srv/git/project.git` + - Git 会触发平时用于网路传输资料的进程,那样传输效率会更低。 + - 指定 `file://` 的主要目的是取得一个没有外部参考(extraneous references) 或对象(object)的干净版本库副本——通常是在从其他版本控制系统导入后或一些类似情况需要这么做。。 +- HTTP 协议 + - 需要用户名密码。 +- SSH 协议 + - 需要配置 ssh key,配置以后就不需要再输入用户名密码了。 + - 不支持匿名访问。 +- Git 协议 + - Git 协议是 Git 使用的网络传输协议里最快的。 + +## SSH 公钥 + +- 生成 + - `ssh-keygen` + - 默认情况下,用户的 SSH 密钥存储在其 `~/.ssh` 目录下。 + - 一对以 `id_dsa` 或 `id_rsa` 命名的文件,其中一个带有 `.pub` 扩展名的,将公钥添加到 git 服务器以实现 SSH 方式登录。 +- 使用上 + - 要做到每次提交都有具体的主题,比如每次提交都解决了一个问题,不要将处理的几个问题在一次提交中,提交上去。 + - 提交信息 + - 少于 25 汉字,或者 50 字符的简要概括,然后空一行,再接着继续更详细的解释。 + + ```bash + 1edee6b..fbff5bc master -> master + .. fromref -> toref + ``` + + - oldref 的含义是推送前所指向的引用 + - newref 的含义是推送后所指向的引用 + - fromref 是将要被推送的本地引用的名字 + - toref 是将要被更新的远程引用的名字 + +## .gitkeep 文件 + +- git 默认是不允许提交一个空的目录到版本库上的, 可以在空的文件夹里面建立一个 `.gitkeep` 文件,然后提交去即可。 +- 其实在 git 中 `.gitkeep` 就是一个占位符。 + +## 配置 + +- 配置文件优先级:`.git/config` > `~/.gitconfig` > `/etc/gitconfig` +- 检查配置信息 + - 如果想要检查你的配置,可以使用 `git config --list` 命令来列出所有 Git 当时能找到的配置。 +- 安装完 Git 之后,要做的第一件事就是设置你的用户名和邮件地址。 + - 这一点很重要,因为每一个 Git 提交都会使用这些信息,它们会写入到你的每一次提交中,不可更改: + - `git config --global user.name "John Doe"` + - `git config --global user.email johndoe@example.com` +- **再次强调**,如果使用了 `--global` 选项,那么该命令只需要运行一次,因为之后无论你在该系统上做任何事情, Git 都会使用那些信息。 当你想针对特定项目使用不同的用户名称与邮件地址时,可以在那个项目目录下运行没有 `--global` 选项的命令来配置。很多 GUI 工具都会在第一次运行时帮助你配置这些信息。 +- 常用配置项: + - `git config --global user.name "Aaron Wang"` # 换成自己的名字 + - `git config --global user.email aaron.wang@maiscrm.com` # 换成自己的邮箱 + - `git config --global core.editor vim` + - `git config --global core.quotepath false` + - `git config --global push.default simple` + - `git config --global rerere.enabled true` + - `git config --global alias.c checkout` + - `git config --global alias.d diff` + - `git config --global alias.dc "diff --cached"` + - `git config --global alias.dw "diff --word-diff"` + - `git config --global alias.l "log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"` + - `git config --global alias.s status -sb` + - `git config --global alias.reset-permission '!git diff -p -R --no-color | grep -E "^(diff|(old|new) mode)" --color=never | git apply'` diff --git a/git/Git.md b/git/Git.md deleted file mode 100644 index c77621fbf16820e72cb6a1e3547f6dfd7b69a3f5..0000000000000000000000000000000000000000 --- a/git/Git.md +++ /dev/null @@ -1,5 +0,0 @@ -# Git 笔记 - -## 参考文档 - -- [Pro Git](https://git-scm.com/book/en/v2) diff --git a/html/HTML.md b/html/HTML.md index 629a2b34a699f8a4aa60a0c45d873108b5dbe48e..edb4a03669ba76b3340cd5225f4c5479b81462c4 100644 --- a/html/HTML.md +++ b/html/HTML.md @@ -3,3 +3,391 @@ ## 参考文档 - [网道 HTML](https://wangdoc.com/html/) + +## 结构 + +- 一个控件必须指定它的 name 属性,这样才可以作为键值对,发送到服务器。控件的 name 就是键值对的 K。 +- 所有元素分为两类 + - 块元素 (block),默认占据一行空间,宽度 100%,自动换行。 + - 行内元素(inline)。 + +## 骨架 + +- `` 表示文档类型,告诉浏览器如何解析网页。 + - 一般声明为 html 就可以了,比如 ``。 +- `` 是网页的顶层容器,即标签树结构的顶层节点,也称为根元素(root element),其他元素都是它的子元素。一个网页只能有一个 `` 标签。 + - lang 属性,表示网页内容默认的语言。 + - ``,如果是英文内容的话,那么将 zh-CN 改成 en。 +- ``标签是一个容器标签,用于放置网页的元信息。它的内容不会出现在网页上,而是为网页渲染提供额外信息。 + - `` 是 `` 的第一个子元素。如果网页不包含 ``,浏览器会自动创建一个。 + - `` 的子元素有 7 个: + - ``:设置网页的元数据,用于设置或说明网页的元数据,必须放在 `` 里面,并且是内容的最前面。 + - `charset` 属性,``,注意,这里声明的编码方式,应该与网页实际的编码方式一致,即声明了 utf-8,网页就应该使用 UTF-8 编码保存。如果这里声明了 utf-8,实际却是使用另一种编码(比如 GB2312),并不会导致浏览器的自动转码,网页可能会显示为乱码。 + - `name` 属性,`content` 属性,`name` 属性表示元数据的名字,`content` 属性表示元数据的值。它们合在一起使用,就可以为网页指定一项元数据。比如:``,这里的 `description` 可以是 `keywords`、`author`,分别表示描述、网页内容关键字、作者。 + - `http-equiv` 属性,`content` 属性,用来覆盖 HTTP 回应的头信息字段,`content` 属性是对应的字段内容。这两个属性与 HTTP 协议相关。比如:``。 + - ``:连接外部样式表。 + - ``:设置网页标题。 + - `<style>`:放置内嵌的样式表。 + - `<script>`:引入脚本。 + - `<noscript>`:浏览器不支持脚本时,所要显示的内容。 + - `<base>`:设置网页内部相对 URL 的计算基准。 +- `<body>`标签是一个容器标签,用于放置网页的主体内容。浏览器显示的页面内容,都放置在它的内部。它是 `<html>` 的第二个子元素,紧跟在 `<head>` 后面。 + +## 内容骨架 + +页面分成页眉(``<header>``)、主体(``<main>``)、页尾(``<footer>``)三个部分。 + +- `<header>`标签可以用在多个场景,既可以表示整个网页的头部,也可以表示一篇文章或者一个区块的头部。 + - 如果用在网页的头部,就称为“页眉”。网站导航和搜索栏通常会放在 `<header>` 里面。`<header>` 里面不能包含另一个 `<header>` 或 `<footer>`。 +- `<footer>`标签表示网页、文章或章节的尾部。 + - 如果用于整张网页的尾部,就称为“页尾”,通常包含版权信息或者其他相关信息。`<footer>` 不能嵌套,即内部不能放置另一个 `<footer>`,也不能放置 `<header>`。 +- `<main>` 标签表示页面的主体内容。 + - 一个页面只能有一个 `<main>`。 +- `<article>` 标签表示页面里面一段完整的内容,即使页面的其他部分不存在,也具有独立使用的意义,通常用来表示一篇文章或者一个论坛帖子。 +- `<aside>` 标签用来放置与网页或文章主要内容间接相关的部分。 + - 网页级别的 `<aside>`,可以用来放置侧边栏,但不一定就在页面的侧边;文章级别的 `<aside>`,可以用来放置评论或注释。 +- `<section>` 标签表示一个含有主题的独立部分。 + - 通常用在文档里面表示一个章节,比如 `<article>` 可以包含多个 `<section>`。`<section>` 总是多个一起使用,一个页面不能只有一个 `<section>`。 +- `<nav>` 标签用于放置页面或文档的导航信息。 + +## 文本标签 + +- `<div>` 标签是无语义的标签。 + - 在 HTML 退出语义标签之前,经常是多级的 div 标签进行嵌套使用。但是现在有了语义标签,优先使用语义标签。 +- `<p>` 标签是段落标签,块元素。 +- `<span>`,无语义标签,是行内标签。 +- `<br>`,换行, `<wbr>`,告诉浏览器在哪里进行换行。 +- `<hr>`,分割线。 +- `<b>` 和 `<strong>` 这两个标签都是加粗,但是 `<b>` 是无语义的,建议使用 `<strong>`。 +- `<pre>` 是一个块级元素,表示保留原来的格式(preformatted),即浏览器会保留该标签内部原始的换行和空格。 + - 浏览器默认以等宽字体显示标签内容。 + - **注意**,HTML 标签在 `<pre>` 里面还是起作用的。`<pre>` 只保留空格和换行,不会保留 HTML 标签。 +- `<em>`和 `<i>`,重要,即斜体显示 + - `<i>` 无语义,建议使用 `<em>`。 +- `<sub>` 将内容变成下标,`<sup>` 将内容变成上标, `<var>` 表示内容是公式或者代码,斜体显示。 +- `<u>`,下划线,`<s>`,删除线。 +- `<blockquote>` 是一个块级标签,表示引用他人的话。 + - 浏览器会在样式上,与正常文本区别显示。 + - 有一个 `cite` 属性,它的值是一个网址,表示引言来源,不会显示在网页上。 +- `<q>`是一个行内标签,也表示引用。 + - 它与 `<blockquote>` 的区别,就是它不会产生换行。会给内容加上双引号。 +- `<cite>`标签表示引言出处或者作者,浏览器默认使用斜体显示这部分内容。 +- `<code>` 标签是一个行内元素,表示标签内容是计算机代码,浏览器默认会以等宽字体显示。 + - 如果要表示多行代码,`<code>` 标签必须放在 `<pre>` 内部。`<code>` 本身仅表示一行代码。 +- `<kbd>` 标签是一个行内元素,原意是用户从键盘输入的内容,现在扩展到各种输入,包括语音输入。 + - 浏览器默认以等宽字体显示标签内容。 +- `<samp>` 标签是一个行内元素,表示计算机程序输出内容的一个例子。 + - 浏览器默认以等宽字体显示。 +- `<mark>` 是一个行内标签,表示突出显示的内容。 + - Chrome 浏览器默认会以亮黄色背景,显示该标签的内容。 +- `<small>` 是一个行内标签,浏览器会将它包含的内容,以小一号的字号显示,不需要使用 CSS 样式。 + - 它通常用于文章附带的版权信息或法律信息。 +- `<time>` 是一个行内标签,为跟时间相关的内容提供机器可读的格式。 + - `<data>`和除了时间以外的数据相关。 +- `<address>` 标签是一个块级元素,表示某人或某个组织的联系方式。 + - 内容不得有非联系信息,不能嵌套,并且内部不能有标题标签(`<h1>`~`<h6>`),也不能有 `<article>`、`<aside>`、`<section>`、`<nav>`、`<header>`、`<footer>` 等标签。 + - 通常,它会放在 `<footer>` 里面。 +- `<abbr>` 标签是一个行内元素,表示标签内容是一个缩写。 + - `title` 属性给出缩写的完整形式,或者缩写的描述。 +- `<ins>` 标签是一个行内元素,表示原始文档添加(insert)的内容。 + - `<del>` 与之类似,表示删除(delete)的内容。它们通常用于展示文档的删改。 + - 浏览器默认为 `<del>` 标签的内容加上删除线,为 `<ins>` 标签的内容加上下划线。 +- `<dfn>` 是一个行内元素,表示标签内容是一个术语(definition),本段或本句包含它的定义。 +- `<ruby>` 标签表示文字的语音注释,主要用于东亚文字,比如汉语拼音和日语的片假名。它默认将语音注释,以小字体显示在文字的上方。 + - `<rp>`标签的用处,是为不支持语音注释的浏览器,提供一个兼容方案。对于那些支持语音注释的浏览器,该标签的内容不显示。 + - `<rp>`标签一般用于放置圆括号,如果遇到不支持的浏览器,就会将语音注释显示在括号里面。 + - `<rt>`标签用于放置语音注释。 + - `<rb>`标签用于划分文字单位,与语音注释一一对应。 +- `<bdo>`标签是一个行内元素,表示文字方向与网页主体内容的方向不一致。 + - dir 属性,指定具体的文字方向。它有两个值,ltr 表示从左到右,rtl 表示从右到左。 +- `<bdi>`标签用于不确定文字方向的情况。 + - 比如,网页有一个部分是用户输入的内容,但是不知道输入内容的文字方向。这种情况就可以使用 `<bdi>` 标签,告诉浏览器,不确定文字的方向,由浏览器自己决定。 + +## 列表标签 + +- `<ol>` 标签是一个有序列表容器(ordered list)。 + - `reversed` 属性,倒序。 + - `start` 属性的值是一个整数,表示数字列表的起始编号。 + - `type` 序号类型: + - a:小写字母 + - A:大写字母 + - i:小写罗马数字 + - I:大写罗马数字 + - 1:整数(默认值) +- `<ul>`标签是一个无序列表容器(unordered list)。 +- `<li>`表示列表项 + - `<li>` 有一个 value 属性,定义当前列表项的编号,后面列表项会从这个值开始编号。 +- `<dl>`标签是一个块级元素,表示一组术语的列表(description list)。 + - 术语名(description term)由`<dt>`标签定义 + - 术语解释(description detail)由`<dd>`标签定义。 + - `<dl>` 常用来定义词汇表。 + - `<dt>` 和 `<dd>` 都是块级元素 + - `<dd>` 默认会在 `<dt>` 下方缩进显示。 + +## 图像标签 + +- `<img>`标签用于插入图片。 + - 单独使用,没有闭合标签。`<img>` 可以放在 `<a>` 标签内部,使得图片变成一个可以点击的链接。 + - `alt`:用来设定图片的文字说明。 + - 图片不显示时(比如下载失败,或用户关闭图片加载),图片的位置上会显示该文本。 + - `width`:`height` 属性,图片默认以原始大小插入网页,`width` 属性和 `height` 属性可以指定图片显示时的宽度和高度,单位是像素或百分比。 + - 注意,一旦设置了这两个属性,浏览器会在网页中预先留出这个大小的空间,不管图片有没有加载成功。不过,由于图片的显示大小可以用 CSS 设置,所以不建议使用这两个属性。 + - `loading`:可以指定图片的懒加载 + - 即图片默认不加载,只有即将滚动进入视口,变成用户可见时才会加载,这样就节省了带宽。 + - `auto`:浏览器默认行为 + - 等同于不使用 `loading` 属性。 + - `lazy`:启用懒加载。 + - `eager`:立即加载资源 + - 无论它在页面上的哪个位置。 + - `crossorigin`:用来告诉浏览器,是否采用跨域的形式下载图片,默认是不采用。 + - 有时,图片和网页属于不同的网站,网页加载图片就会导致跨域请求,对方服务器可能要求跨域认证。 + - 简单说,只要打开了这个属性,HTTP 请求的头信息里面,就会加入 origin 字段,给出请求发出的域名,不打开这个属性就不加。 + - `anonymous`:跨域请求不带有用户凭证(通常是 Cookie)。 + - `use-credentials`:跨域请求带有用户凭证。 +- `<figure>` 标签可以理解为一个图像区块,将图像和相关信息封装在一起。 + - `<figcaption>` 是它的可选子元素,表示图像的文本描述,通常用于放置标题。 + - 可以出现多个。 + +## 链接标签 + +- 链接通过 `<a>` 标签表示,用户点击后,浏览器会跳转到指定的网址。 + - `href` 属性给出链接指向的网址。 + - 它的值应该是一个 URL 或者锚点。 + - `hreflang` 属性给出链接指向的网址所使用的语言,纯粹是提示性的,没有实际功能。 + - `title` 属性给出链接的说明信息。 + - 鼠标悬停在链接上方时,浏览器会将这个属性的值,以提示块的形式显示出来。 + - `target` 属性指定如何展示打开的链接。 + - 它可以是在指定的窗口打开,也可以在 `<iframe>` 里面打开。 + - 有以下属性: + - `_self`:当前窗口打开,这是默认值。 + - `_blank`:新窗口打开。 + - `_parent`:上层窗口打开,这通常用于从父窗口打开的子窗口,或者 `<iframe>` 里面的链接。 + - 如果当前窗口没有上层窗口,这个值等同于 `_self`。 + - `_top`:顶层窗口打开。 + - 如果当前窗口就是顶层窗口,这个值等同于 `_self`。 + - `rel` 属性说明链接与当前页面的关系。 + - `alternate`:当前文档的另一种形式 + - 比如翻译。 + - `author`:作者链接。 + - `bookmark`:用作书签的永久地址。 + - `external`:当前文档的外部参考文档。 + - `help`:帮助链接。 + - `license`:许可证链接。 + - `next`:系列文档的下一篇。 + - `nofollow`:告诉搜索引擎忽略该链接,主要用于用户提交的内容,防止有人企图通过添加链接,提高该链接的搜索排名。 + - `noreferrer`:告诉浏览器打开链接时,不要将当前网址作为 HTTP 头信息的 `Referer` 字段发送出去,这样可以隐藏点击的来源。 + - `noopener`:告诉浏览器打开链接时,不让链接窗口通过 JavaScript 的 `window.opener` 属性引用原始窗口,这样就提高了安全性。 + - `prev`:系列文档的上一篇。 + - `search`:文档的搜索链接。 + - `tag`:文档的标签链接。 + - `ping` 属性指定一个网址,用户点击的时候,会向该网址发出一个 POST 请求,通常用于跟踪用户的行为。 + - `type` 属性给出链接 URL 的 MIME 类型 + - 比如到底是网页,还是图像或文件。 + - 它是纯粹提示性的属性,没有实际功能。 + - `download` 属性表明当前链接用于下载,而不是跳转到另一个 URL。 + - **注意**,`download` 属性只在链接与网址同源时,才会生效。 + - 也就是说,链接应该与网址属于同一个网站。 + - 如果 `download` 属性设置了值,那么这个值就是下载的文件名。 + - `mailto` 协议 + - `<a href="mailto:foo@bar.com?cc=test@test.com&subject=The%20subject&body=The%20body">发送邮件</a>` + - `tel` 协议 + - `<a href="tel:13312345678">13312345678</a>` + - 上面代码在手机中,点击链接会唤起拨号界面,可以直接拨打指定号码。 +- `<link>` 标签主要用于将当前网页与相关的外部资源联系起来,通常放在元素里面。最常见的用途就是加载 CSS 样式表。 + - `<link rel="stylesheet" type="text/css" href="theme.css">` + - 还可以加载网站的 favicon 图标文件。 + - `<link rel="icon" href="/favicon.ico" type="image/x-icon">` + - `rel` 属性表示外部资源与当前文档之间的关系,是 `<link>` 标签的必需属性。 + - `preload` 预加载 + - `<link rel="preload" href="style.css" as="style">` 的意思是,要求浏览器提前下载并缓存 style.css。 + - `as` 属性指定加载资源的类型,它的值一般有下面几种: + - "script" + - "style" + - "image" + - "media" + - "document" +- `<script>` 用于加载脚本代码,目前主要是加载 JavaScript 代码。 + - `src` 属性给出外部脚本的地址。 +- `<noscript>` 标签用于浏览器不支持或关闭 JavaScript 时,所要显示的内容。 + - 用户关闭 JavaScript 可能是为了节省带宽,以延长手机电池寿命,或者为了防止追踪,保护隐私。 + +## 多媒体标签 + +- `<video>` 标签是一个块级元素,用于放置视频。 + - 如果浏览器支持加载的视频格式,就会显示一个播放器,否则显示 `<video>` 内部的子元素。 + +## iframe + +- `<iframe>` 标签生成一个指定区域,在该区域中嵌入其他网页。 +- 它是一个容器元素,如果浏览器不支持 `<iframe>`,就会显示内部的子元素。 + - `sandbox` 可以当作布尔属性使用,表示打开所有限制。 + - `loading`,懒加载。如果 `<iframe>` 是隐藏的,则 `loading` 属性无效,将会立即加载。 + +## 表格 + +`<table>` 是一个块级容器标签,所有表格内容都要放在这个标签里面。 + +- `<caption>` 总是 `<table>` 里面的第一个子元素,表示表格的标题。 + - 该元素是可选的。 +- `<thead>`、`<tbody>`、`<tfoot>`都是块级容器元素,且都是`<table>`的一级子元素,分别表示表头、表体和表尾。 +- `<colgroup>`是`<table>`的一级子元素,用来包含一组列的定义。 + - `<col>` 是`<colgroup>`的子元素,用来定义表格的一列。 + - `<col>` 不仅是一个单独使用的标签,没有结束标志,而且还是一个空元素,没有子元素。 + - 它的主要作用,除了申明表格结构,还可以为表格附加样式。 +- `<tr>` 标签表示表格的一行(table row)。 + - 如果表格有 `<thead>`、`<tbody>`、`<tfoot>`,那么 `<tr>` 就放在这些容器元素之中,否则直接放在`<table>`的下一级。 +- `<th>` 和 `<td>` 都用来定义表格的单元格。 + - 其中,`<th>` 是标题单元格,`<td>` 是数据单元格。 + - `colspan` 属性,`rowspan` 属性。 + - `headers` 属性 + - 如果表格很大,单元格很多,源码里面会看不清,哪个单元格对应哪个表头,这时就可以使用 headers 属性。 + - `scope` 属性只有 `<th>` 标签支持,一般不在 `<td>` 标签使用,表示该 `<th>` 单元格到底是栏的标题,还是列的标题。 + - `row`:该行的所有单元格,都与该标题单元格相关。 + - `col`:该列的所有单元格,都与该标题单元格相关。 + - `rowgroup`:多行组成的一个行组的所有单元格,都与该标题单元格相关,可以与 `rowspan` 属性配合使用。 + - `colgroup`:多列组成的一个列组的所有单元格,都与该标题单元格相关,可以与 `colspan` 属性配合使用。 + - `auto`:默认值,表示由浏览器自行决定。 + +## 表单 + +- `<form>` 标签用来定义一个表单,所有表单内容放到这个容器元素之中。 + + `<form>` 有以下属性: + + - `accept-charset`:服务器接受的字符编码列表,使用空格分隔 + - 默认与网页编码相同。 + - `action`:服务器接收数据的 URL。 + - `autocomplete`:如果用户没有填写某个控件,浏览器是否可以自动填写该值。 + - 它的可能取值分别为 off(不自动填写)和 on(自动填写)。 + - `method`:提交数据的 HTTP 方法,可能的值有 post(表单数据作为 HTTP 数据体发送),get(表单数据作为 URL 的查询字符串发送),dialog(表单位于`<dialog>`内部使用)。 + - `enctype`:当 method 属性等于 post 时,该属性指定提交给服务器的 MIME 类型。 + - 可能的值为: + - application/x-www-form-urlencoded(默认值) + - multipart/form-data(文件上传的情况) + - text/plain。 + - 指定了采用 POST 方法提交数据时,浏览器给出的数据的 MIME 类型。参数如下: + - application/x-www-form-urlencoded 是默认类型,控件名和控件值都要转义(空格转为 + 号,非数字和非字母转为 %HH 的形式,换行转为CR LF),控件名和控件值之间用 = 分隔。控件按照出现顺序排列,控件之间用 & 分隔。 + - multipart/form-data 主要用于文件上传。这个类型上传大文件时,会将文件分成多块传送,每一块的 HTTP 头信息都有 Content-Disposition 属性,值为 form-data,以及一个 name 属性,值为控件名。 + - `name`:表单的名称,应该在网页中是唯一的。 + - **注意**,如果一个控件没有设置 name 属性,那么这个控件的值就不会作为键值对,向服务器发送。 + - `novalidate`:布尔属性,表单提交时是否取消验证。 + - `target`:在哪个窗口展示服务器返回的数据 + - 可能的值有 + - `_self`(当前窗口) + - `_blank`(新建窗口) + - `_parent`(父窗口) + - `_top`(顶层窗口) + - `<iframe>`标签的 name 属性(即表单返回结果展示在 `<iframe>` 窗口)。 + - `<fieldset>` 标签是一个块级容器标签,表示控件的集合,用于将一组相关控件组合成一组。 + - `<legend>` 标签用来设置 `<fieldset>` 控件组的标题,通常是 `<fieldset>` 内部的第一个元素,会嵌入显示在控件组的上边框里面。 + - `disabled`:布尔属性 + - 一旦设置会使得 `<fieldset>` 内部包含的控件都不可用,都变成灰色状态。 + - `form`:指定控件组所属的 `<form>` + - 它的值等于 `<form>` 的 id 属性。 + - `name`:该控件组的名称。 +- `<label>` 的 for 属性关联相对应的控件,它的值是对应控件的 id 属性。所以,控件最好设置 id 属性。控件也可以放在 `<label>` 之中,这时不需要 for 属性和 id 属性。form 属性,关联表单的 id 属性。设置了该属性后,`<label>` 可以放置在页面的任何位置,否则只能放在 `<form>` 内部。 +- `<input>` 标签是一个行内元素,用来接收用户的输入。它是一个单独使用的标签,没有结束标志。 + - `autofocus`:布尔属性,是否在页面加载时自动获得焦点。 + - `disabled`:布尔属性,是否禁用该控件。一旦设置,该控件将变灰,用户可以看到,但是无法操作。 + - `form`:关联表单的 id 属性。设置了该属性后,控件可以放置在页面的任何位置,否则只能放在`<form>` 内部。 + - `list`:关联的 `<datalist>` 的 id 属性,设置该控件相关的数据列表,详见后文。 + - `name`:控件的名称,主要用于向服务器提交数据时,控件键值对的键名。 + - **注意**,只有设置了 name 属性的控件,才会向服务器提交,不设置就不会提交。 + - `readonly`:布尔属性,是否为只读。 + - `required`:布尔属性,是否为必填。 + - `type`:控件类型 + - `text`,文本类型 + - `maxlength`:可以输入的最大字符数,值为一个非负整数。 + - `minlength`:可以输入的最小字符数,值为一个非负整数,且必须小于 maxlength。 + - `pattern`:用户输入必须匹配的正则表达式 + - 比如要求用户输入 4 个~ 8 个英文字符,可以写成 `pattern="[a-z]{4,8}"`。 + - 如果用户输入不符合要求,浏览器会弹出提示,不会提交表单。 + - `placeholder`:输入字段为空时,用于提示的示例值。 + - 只要用户没有任何字符,该提示就会出现,否则会消失。 + - `readonly`:布尔属性,表示该输入框是只读的,用户只能看,不能输入。 + - `size`:表示输入框的显示长度有多少个字符宽 + - 它的值是一个正整数,默认等于 20。 + - 超过这个数字的字符,必须移动光标才能看到。 + - `spellcheck`:是否对用户输入启用拼写检查 + - 可能的值为 true 或 false。 + - `search` 是一个用于搜索的文本输入框,基本等同于 `type="text"`。 + - 某些浏览器会在输入的时候,在输入框的尾部显示一个删除按钮,点击就会删除所有输入,让用户从头开始输入。 + - `button`,是没有默认行为的按钮,通常脚本指定 click 事件的监听函数来使用。 + - `value`:控件的值。 + - `checkbox`:同时选中两个复选框,提交的时候就会有两个 name 属性,比如 `interest=coding&interest=music`。 + - `radio`:多个单选框的 name 属性的值,应该都是一致的。 + +## 其他标签 + +- `<dialog>` 标签表示一个可以关闭的对话框。 + - 默认情况下,对话框是隐藏的,不会在网页上显示。 + - 如果要让对话框显示,必须加上 `open` 属性。 + +## 空格和换行 + +- 标签内容的头部和尾部的空格,忽略不计。 +- 内容之间有多个连续空格,浏览器会将它们合并成一个。 +- 浏览器会将文本里面的换行符(`\n`)和回车符(`\r`),替换成空格。 +- URL + - `parameter`,`?a=1&b=2`,多个参数使用 `&` 进行连接。 + - 锚点,`#` 锚点位置,放在地址最后。 + - 锚点名称通过元素的 id 命名。 + - 转义,在字符的十六进制的 ASCII 码前面加上 `%`,例如: + - 空格:`%20` + - `!`:`%21` + - `#`:`%23` + - `$`:`%24` + - `&`:`%26` + - `'`:`%27` + - `(`:`%28` + - `)`:`%29` + - `*`:`%2A` + - `+`:`%2B` + - `,`:`%2C` + - `/`:`%2F` + - `:`:`%3A` + - `;`:`%3B` + - `=`:`%3D` + - `?`:`%3F` + - `@`:`%40` + - `[`:`%5B` + - `]`:`%5D` + - 既不属于合法字符、也不属于保留字符的其他字符(比如汉字),理论上不需要手动转义,可以直接写在 URL 里面 + - 比如 `www.example.com/中国.html`,浏览器会自动将它们转义,发给服务器。 + - 转义方法是使用这些字符的十六进制 UTF-8 编码,每两位算作一组,然后每组头部添加百分号(`%`)。 + - `<base>` 标签指定网页内部的所有相对 URL 的计算基准。 + - 整张网页只能有一个 `<base>` 标签,而且只能放在 `<head>` 里面。 + - 它是单独使用的标签,没有闭合标签。 + +## 元素属性 attribute + +- `id` 属性是元素在网页内的唯一标识符。 + - 比如,网页可能包含多个 `<p>` 标签,`id` 属性可以指定每个`<p>` 标签的唯一标识符。 + - `id` 属性的值必须是全局唯一的,同一个页面不能有两个相同的 `id` 属性。 + - 另外,`id` 属性的值不得包含空格。 + - `id` 属性的值还可以在最前面加上 `#`,放到 URL 中作为锚点,定位到该元素在网页内部的位置。 + - 比如,用户访问网址 `https://foo.com/index.html#bar` 的时候,浏览器会自动将页面滚动到 bar 的位置,让用户第一眼就看到这部分内容。 +- `class` 属性用来对网页元素进行分类。 + - 多个 class,之间使用空格分隔。 + - 如果不同元素的 class 属性值相同,就表示它们是一类的。 +- `title` 属性用来为元素添加附加说明。 + - 大多数浏览器中,鼠标悬浮在元素上面时,会将 `title` 属性值作为浮动提示,显示出来。 +- `tabindex` 属性的值是一个整数,表示用户按下 Tab 键的时候,网页焦点转移的顺序。 + - 负整数:该元素可以获得焦点,但是不参与使用 Tab 键进行遍历。 + - 0,参与遍历。 + - 正整数,按照数字顺序。 +- `accesskey` 属性指定网页元素获得焦点的快捷键,值必须是单个的可打印字符。 + - **注意**,`accesskey` 如果跟操作系统或浏览器级别的快捷键有冲突,这时不会生效。 +- `style` 属性用来指定当前元素的 CSS 样式。 +- `hidden` 是一个布尔属性,表示当前的网页元素不再跟页面相关,因此浏览器不会渲染这个元素,所以就不会在网页中看到它。 + - CSS 的可见性设置,高于 `hidden` 属性。 + - 如果 CSS 设为该元素可见,`hidden` 属性将无效。 +- `lang`,指定页面元素使用的语言 + - `dir`,表示文字阅读的方向。 +- `contenteditable`,网页可编辑。 + - 例如:`contenteditable="true"`。 + - 该属性是枚举属性,不是布尔属性,规范的写法是最好带上属性值。 +- `spellcheck` 属性就表示,是否打开拼写检查。 + - `true`:打开拼写检查。 + - `false`:关闭拼写检查。 + - 枚举属性,如果没有指定这个属性,浏览器将自行决定是否打开拼写检查。对于那些不可编辑的元素,该属性无效。 diff --git a/java/Java.md b/java/Java.md index 49c28adcc1c746680ed521369e338ba9ced29d58..9505652f80aabfbafea6314e8cd30cb576bdace9 100644 --- a/java/Java.md +++ b/java/Java.md @@ -368,6 +368,15 @@ Queue 实际上是实现了一个先进先出(FIFO:First In First Out)的 ## 日期与时间 +### Java 时区问题: + +- `/etc/localtime` 是用来描述本机时间 +- `/etc/timezone` 是用来描述本机所属的时区 + +在 linux 中,有一些程序会自己计算时间,不会直接采用带有时区的本机时间格式,会根据 UTC 时间和本机所属的时区等计算出当前的时间。 + +比如 jdk 应用,时区为 `Etc/UTC`,本机时间改为北京时间,通过 java 代码中 new 出来的时间还是 utc 时间,所以必须得修正本机的时区。 + ### 本地化 - 在计算机中,通常使用 `Locale` 表示一个国家或地区的日期、时间、数字、货币等格式。`Locale` 由 **语言_国家** 的字母缩写构成,例如,`zh_CN` 表示中文 + 中国,`en_US` 表示英文 + 美国。语言使用小写,国家使用大写。 diff --git "a/linux/Linux \345\221\275\344\273\244\350\241\214.md" b/linux/Linux Command.md similarity index 51% rename from "linux/Linux \345\221\275\344\273\244\350\241\214.md" rename to linux/Linux Command.md index 61eb3d48bba07428f115a00b3e289d48858becce..bfd268962df41aa8f81665b2a6968acd0a2a8b44 100644 --- "a/linux/Linux \345\221\275\344\273\244\350\241\214.md" +++ b/linux/Linux Command.md @@ -30,7 +30,16 @@ command 主要有: `CommandLine URL` 或 `CommandLine Uniform Resource Locator`,顾名思义,`curl` 命令是在命令行方式下工作,利用 `URL` 的语法进行数据的传输或者文件的传输。 -- -X 选项,指定请求方式,包括 `GET`、`PUT`、`POST`、`DELETE` 四种方式。 +- 不带参数,默认发送 GET 请求。 + - `curl http://www.baidu.com` +- `-A`,即 `User-Agent`,指定客户端的用户代理标头。 +- `-b`,用来向服务器发送 Cookie。 + - `curl -b 'foo=bar' https://google.com` + - 上面的会生成一个标头 `Cookie: foo=bar` +- `-c`,将服务器设置的 Cookie 写入一个文件。 +- `-d`,用于发送 POST 请求的数据体。 + +- `-X` 选项,指定请求方式,包括 `GET`、`PUT`、`POST`、`DELETE` 四种方式。 ```bash curl -XGET www.baidu.com @@ -38,3 +47,25 @@ command 主要有: curl -XDELETE www.baidu.com curl -XPUT www.baidu.com ``` + +## 守护进程 daemon + +- 前台任务(foreground job),它会独占命令行窗口,只有运行完了或者手动中止,才能执行其他命令。 +- `jobs` 显示当前暂停的进程 +- 在一个命令后面加上 `&`,可以将一个前台任务变成后台任务。 +- 如果想将一个正在运行的任务改成后台任务 + 1. `CTRL + Z`,强制当前进程转为后台,并使之挂起(暂停) + 1. `bg` 命令(让最近一个暂停的"后台任务"继续执行)。 + +### 使用 nohup 启动后台进程 + +nohup,no hang up,不挂起。 + +这个命令不会将启动的任务变成一个后台任务,所以在命令的最后要加一个 & 符号,使启动的任务变成一个后台任务。 + +- `nohup java -jar classwork-0.0.1-SNAPSHOT.jar &> classwork.text &` +- `nohup java -jar classwork-0.0.1-SNAPSHOT.jar > classwork.text 2>&1 &` +- 上面两种方式一样效果。 +- `0` 标准输入 +- `1` 标准输出 +- `2` 标准错误输出 diff --git a/markdown/Markdown.md b/markdown/Markdown.md index feeec6a7db2139b0fdf72d48d2d452b29b448ed4..34d552965a4e4c8f02e29e3cc173c65d3728039e 100644 --- a/markdown/Markdown.md +++ b/markdown/Markdown.md @@ -2,4 +2,106 @@ ## 参考文档 -- [Markdown]() +- [Markdown 指南中文版](https://www.markdown.xyz/basic-syntax/) + +## 基本语法 + +### 标题 + +- `#` H1 +- `##` H2 +- `###` H3 +- `####` H4 +- `#####` H5 +- `######` H6 +- `===` 一级标题 +- `---` 二级标题 + +### 斜体 + +- 使用一个 `*` 将要格式化的字体包起来。 + +### 加粗 + +- 使用两个 `**` 将要格式化的字体包起来。 + +### 加粗倾斜 + +- 三个 `*` 号包起来,前后各三个 `*` 号。 + +### 删除线 + +- 前后各两个 `~~` + +### 分割线 + +- 使用四个中划线 `----`,并且使用分割线之前必须有一行空行。 + +### 引用 + +- 使用 `>text` 的格式进行引用,并且在引用之前必须有一行是空行。 + +### 列表 + +- 列表使用前必须要加空格 +- 无序列表 + - 使用 -、+、*加上文字 text 的格式 +- 有序列表 + - 使用 num.text 的格式 + +### 表格 + +- 表格前必须空一行 +- 单元格使用 `|` 进行分割,表头的分割符使用 `-` 进行分割。 + - `-` 和 `:-` 表示表头和单元格左对齐 + - `-:` 表示右对齐 + - `:-:` 表示居中对齐。 + +### 代码块 + +- 行内代码,使用前后一个 \` 符号包裹起来,注意这里不是单引号是,是反斜号。 +- 多行代码,使用前后三个 \`\`\` 符号包裹起来。并可以指定一种编程语言进行高亮显示。 + - 例如 + + \```js + + 你好 + + \``` + +### 转义字符 + +- 使用反斜杠,`\` 进行特殊字符的转义。 + +### 链接 + +- `[title](URL)`,例如[百度点这里](https://www.baidu.com),注意这里括号之间没有空格。 +- url 地址需要添加网络协议。 + +### 图片 + +- `![title](URL)` + - title 指的是图片的替代文字 + - URL 是图片的地址 + +## 注意事项 + +### 空格 + +- 中英文之间需要增加空格。 +- 中文与数字之间需要增加空格。 +- 数字与单位之间无需增加空格。 +- 全角标点与其他字符之间不加空格。 + - 例外:裸链接后面需空格,不能紧跟标点,否则有些渲染器会把标点当成链接的一部分。 +- 中文与链接、强调、行内代码等格式间是否加空格取决于内容(即以上规则)。 + - 比如书写 Markdown 的规范需要加,而书写中文的规范不需要加。 + +## 怎么写 Markdown + +- 文件名全部用英文,camelCase。 +- 内容全部用中文写。 +- 图片放到文档所在目录的 images/ 子目录内,使用相对路径引用,比如 `![demo](./images/demo.png)`。 +- 引用同一类目下的文档用相对路径,否则用绝对路径,比如 portal 文档引用 mairpc 文档,应使用 /mairpc/xxx 形式的绝对路径。 +- FAQ 子标题应使用疑问句,问号结尾。 +- 引用人名一律用 @xxx.xxx 的形式。 +- 在书写代码块时,请参考 Prism 支持的语言,否则编译时会出现 'Language does not exist xxx',下面列举了常见的错误写法和对应的正确写法。 diff --git a/swagger/Swagger.md b/swagger/Swagger.md new file mode 100644 index 0000000000000000000000000000000000000000..47b71292fbb2bf8f2de82263d98862a8f5e474f4 --- /dev/null +++ b/swagger/Swagger.md @@ -0,0 +1,74 @@ +# Swagger 笔记 + +## 参考文档 + +- [Swagger 官网](https://swagger.io/) + +## 是什么 + +- 一种接口文档定义规范。 +- 帮助开发人员设计、构建、记录和使用 RESTful Web 服务。 +- 工具集支持自动文档、代码生成和测试用例生成。 + +## 基本格式 + +- 同时支持 yaml、json 的写法,推荐使用 yaml。 +- 文档结构 + - info:文档描述信息。 + - host:接口域名。 + - basePath:接口基础路径。 + - 一般为接口版本号。 + - 如果接口没有独立域名,也可以是自定义的一个路径,如 api。 + - tags:接口标签,用于接口分类,可以简单描述一类接口的用途,增强文档可读性。 + - schemes:传输协议,一般为 http、https,群脉只支持 https。 + - consumes:请求数据类型,群脉只支持 application/json。 + - produces:返回数据类型,群脉只支持 application/json。 + - securityDefinitions:权限认证方式定义,群脉采用 api_key 的方式,在 http header 中设置 x-access-token。 + - paths:接口定义,采用 RESTful 风格。 + - definitions:对象定义。 + +## Swagger Editor + +1. **基础信息** + - `swagger`:swagger版本 + - `info`: + - `title`:标题 + - `description`:文档说明 + - `version`:文档版本 +1. **基本 url** + - `host`:主机地址 + - `basePath`:url 前缀 + - `schemes`:网络请求协议:http/https +1. **API 标签** + - `tags`: +1. **接口定义** + - `paths`: + - `/user`: + - `post`:新增接口 + - `tags`:所属标签 + - `operationId`:方法名(生成代码后即是controller层的接口方法名) + - `produces`:生产格式:json/xml + - `consumes`:消费格式:json/xml + - `parameters`:请求参数定义 + - `-name`:参数名 + - `in`:参数类型:可选:body/query/path,分别代表:请求体 /url 拼接参数 /url 占位符替换 + - `required`:是否必需:true/false + - `schema`:参数结构,可引用 definitions 中定义的数据模型 + - `$ref:'#/definitions/User'` + - `responses`:返回格式定义 + - `get`:查询接口 + - `delete`:删除接口 + - `put`:修改接口 + - `'/user/{userId}'`: + - `get`:查询详情接口 +1. **数据模型定义** + - `definitions`: + - `User`:用户 User 类 + - `type`:类型:object + - `properties`:参数列表 + - `userId`:用户 ID + - `type`:参数类型:object/integer/string/array等 + - `format`:参数格式:int32/date-time + - `items`:若是前序的 type 为 array,则需要定义 items 中的数据类型 + - `type`: + - `description`:参数描述