#375 Git 链接文件

2020-03-22

Git 在团队协作的情况下容易遇到很多小问题,有一类是由于跨平台的系统差异导致的。有人习惯 Windows 下开发,有人习惯 Linux 下开发。

最常见的是这么四个问题:

  1. 文件权限问题
  2. 基本上我还没有遇到有需要给仓库中的文件设置权限的情况,但是由于权限的变更导致提交进来没有内容更改的文件就完全没有必要
  3. 所以非常必要设置 core.filemode false
  4. chmod 644 *.md
  5. 换行符问题
  6. Windows 新建的文件都是 \r\n 换行,Linux 则是 \n
  7. core.autocrlf true 可以在 checkout 的时候根据系统自动转换换行符
  8. 但是我觉得这个可能放到 hook 里面,在提交检查的时候一起做更加合适
  9. dos2unix *.md
  10. 软链接问题

  11. Linux 下的软链接切到 Windows 下之后,变成了一个普通文本,内容是链接的路径

  12. core.symlinks true 可以解决这个问题,这也是默认值,可是有些时候我们的环境中配置的就是 false
  13. 我的 Git for Windows 不知道为什么,system 配置就是设置成 false 了
  14. 有些情况下,项目配置似乎就默认是 false
  15. 如果已经成为现实了,软链是个文本,我们改配置,重新添加,然后 pull 到本地可以

core.symlinks
If false, symbolic links are checked out as small plain files that contain the link text. git-update-index and git-add will not change the recorded type to regular file. Useful on filesystems like FAT that do not support symbolic links.
The default is true, except git-clone or git-init will probe and set core.symlinks false if appropriate when the repository is created.

  1. 文件名大小写问题
  2. Linux 大小写敏感,比如 Apple.txt 和 apple.txt 可以在同一个目录,Windows 环境克隆下来,只能看到一个文件 apple.txt
  3. 没什么好的办法,应该也是在提交的时候作为风格检查
$ git config --list --global | grep sym
$ git config --list --system | grep sym
core.symlinks=false
$ git config --list --local | grep sym
core.symlinks=false

关于链接的另一个办法

CSDN 博客上看到 《windows上使用git仓库的问题(换行符、文件权限、软链接)》,里面提出下面这个思路。
虽然代码不够严谨,但是思路应该是没有问题的。以后遇到问题可以参考(还没有验证):

  1. 找出链接文件
  2. 创建 Windows 链接
  3. 操作索引区,忽略这个变更
import os

def rindex(lst, value):
    try:
        return lst.rindex(value)
    except ValueError:
        return -1

# find symbol link files or dirs
fp = os.popen("git ls-files -s | awk '/120000/{print $4}'")
links = fp.read().strip().split("\n")

# get symbol links' parent dir
link_dir = set()
for link in links:
    index = rindex(link, "/")
    if (index != -1):
        link_dir.add(link[:index])
    else:
        link_dir.add(".")

work_dir = os.getcwd()
# make link for every symbol link
for d in link_dir:
    os.chdir("/".join([work_dir,d]))
    fp = os.popen("ls -la")
    items = fp.read().strip().split("\n")
    for item in items:
        if "->" in item:
            tks = item.split("->")
            src = tks[0].strip().split(" ")[-1]
            dst = tks[1].strip().split("/")
            if (len(dst) > 1):
                dst = "\\\\".join(dst)
            else:
                dst = dst[0]
            print ("link " + src + " -> " + dst)
            os.popen("rm " + src)
            if (os.path.isfile(dst)):
                os.popen("cmd /c mklink /H " + src + " " + dst)
            else:
                os.popen("cmd /c mklink /j " + src + " " + dst)
            # make links unchanged
            os.popen("git update-index --assume-unchanged " + "/".join([os.getcwd(), src]))

参考资料与拓展阅读

#374 Windows 10 镜像下载

2020-03-19

https://msdn.itellyou.cn/

Windows 10 Enterprise LTSC 2019

# x64
Windows 10 Enterprise LTSC 2019 (x64) - DVD (Chinese-Simplified)
文件名:cn_windows_10_enterprise_ltsc_2019_x64_dvd_9c09ff24.iso
SHA1:24b59706d5eded392423936c82ba5a83596b50cc
文件大小:4.17GB
发布时间:2019-03-15
ed2k://|file|cn_windows_10_enterprise_ltsc_2019_x64_dvd_9c09ff24.iso|4478906368|E7C526499308841A4A6D116C857DB669|/

# x86 (32 位)
Windows 10 Enterprise LTSC 2019 (x86) - DVD (Chinese-Simplified)
文件名:cn_windows_10_enterprise_ltsc_2019_x86_dvd_1814dbab.iso
SHA1:ba2169edd94f123211cd4aaca68352f1ab6195d9
文件大小:2.98GB
发布时间:2019-03-15
ed2k://|file|cn_windows_10_enterprise_ltsc_2019_x86_dvd_1814dbab.iso|3196803072|2D39C54A2E99BAC308191C74A15B3237|/
Windows 10 Enterprise LTSC 2021 (x64) - DVD (Chinese-Simplified)
文件:SW_DVD9_WIN_ENT_LTSC_2021_64BIT_ChnSimp_MLF_X22-84402.ISO
大小:4.7GB
MD5:2579B3865C0591EAD3A2B45AF3CABEEE
SHA1:C19D7DAFBAFEB26C36E31D97C465E87C7A6E8A4C
SHA256:C117C5DDBC51F315C739F9321D4907FA50090BA7B48E7E9A2D173D49EF2F73A3
ed2k://|file|SW_DVD9_WIN_ENT_LTSC_2021_64BIT_ChnSimp_MLF_X22-84402.ISO|5044211712|1555B7DCA052B5958EE68DB58A42408D|/

Windows 11

ed2k://|file|zh-cn_windows_11_business_editions_version_22h2_updated_nov_2022_x64_dvd_3623b3e1.iso|5567041536|B83E64D03E93B418840E5B270E164005|/

#373 Linux 磁盘使用情况检查

2020-03-14

我们一般使用 du 命令,不正是做这个用的么(Disk Usage)?

du -hsc          # 当前目录占用空间大小
du -hsc *.log*   # 查看文件大小
du -hsc a b c d  # 查看指定几个目录的大小

#372 SSL/TLS 相关信息

2020-03-13

名称

TLS, Transport Layer Security, 传输层安全性协议
SSL, Secure Sockets Layer, 安全套接层

历史

  1. 90 年代,WWW 先驱网景公司开发 SSL,用于提升 Web 安全性。
  2. 1996,SSL 开始由 IETF (The Internet Engineering Task Force, 互联网工程任务组) 标准化,最后在 1999 年成为 RFC 2246,名字改成了 TLS。
  3. TLS 1.0 约等于 SSL 3.0
  4. 微软 IE 也支持 TLS 1.0
  5. 现在,SSL 时期的三个版本,均已被彻底废弃。
  6. 由于历史原因,很多场合如果不严格区分版本,SSL 等于 TLS。
  7. TLS 1.2 在 2008 年成为 IETF 推荐的版本(2018 年被 TLS 1.3 淘汰)
  8. TLS 1.3 于 2018 年 8 月发表,它的突破性改进包括握手更快从而加快连接速度、简化支持的加密方式、速度和性能优于 TLS 1.2。
协议 发布时间 状态 说明
SSL 1.0 未公布 未公布  
SSL 2.0 1995 年 2011 年弃用  
SSL 3.0 1996 年 2015 年弃用  
TLS 1.0 1999 年 2021 年弃用 RFC 2246
TLS 1.1 2006 年 2021 年弃用 RFC 4346
TLS 1.2 2008 年   RFC 5246
TLS 1.3 2018 年   RFC 8446

旧版本的废弃

  1. SSL 1.0 从未发布。
  2. 2011 年 3 月,RFC 6176 删除了对 SSL 的兼容,避免通过协商使用已经被废弃的 SSL 2.0 而出现安全问题。
  3. 2014 年 10 月,Google 发现 SSL 3.0 有设计缺陷,可以将 TLS 安全连接强行降级到过时且不安全的 SSL 3.0。之后,Google 在自己公司相关产品中陆续禁止回溯兼容,强制使用 TLS 协议。
  4. 2015 年,正式废弃 SSL 3.0。
  5. 微软、Google、苹果、Mozilla 四家浏览器厂商在 2020 年终止支持 TLS 1.0 及 1.1。
  6. 2021 年 3 月,RFC 8996 标准弃用了 TLS 1.0 和 TLS 1.1。

现在主流的是 TLS 1.2 和 TLS 1.3。

相比之下,TLS 1.3 安全性更好,性能也更好。
搜索一下 tls1.2 tls1.3 difference 或者 tls1.2 tls1.3 performance 就能看到很多相关比较。

作用

SSL/TLS 的本质就是非对称加密。

细节

安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性。
该协议由两层组成:

  • TLS 记录协议(TLS Record)
  • TLS 握手协议(TLS Handshake)

握手协议(handshake protocol)
密钥规格变更协议(change cipher spec protocol)
应用数据协议(application data protocol)
警报协议(alert protocol)。

参考资料与拓展阅读

#371 一些不足道哉的开发经验

2020-03-10
  1. 编码:
  2. 遵守一个社区比较公认的编码规范和编程实践,不要试图自己搞一套。
    尤其是命名风格保持统一。
  3. 拆分的思想:分服务,分模块,分文件,分函数,分层。
    不同部分之间的依赖应该非常清晰,严禁无序调用。
  4. 代码复用:尽可能不要重复写类似的代码。
    业务无关代码应该采用公共库,组织内复用,不要重复实现相同的逻辑
  5. 对于功能实现应该有一定的预留空间,对可能发生的调整有一定的包容性
  6. 函数简单:一个函数应该尽可能简单,代码行数少,逻辑清晰。
  7. Git:
  8. 分支管理
  9. 提交管理
    1. 每次代码提交应该有一个明确的目的,和这个目的无关的代码应该另外提交。
      尽可能保证每次提交修改的量比较少。
    2. 提交的时候应该做代码风格检查,没有通过的拒绝接受
  10. 测试:
  11. 单元测试必须要有, 要比业务代码接受更严格的检查
  12. 我认为写单元测试的时间应该开发的时间差不多
  13. 覆盖率要求
  14. 为了保证测试的便利,可以对现有实现进行调整(开发时就应该考虑到测试流程)
  15. 集成测试,回归测试,功能测试,性能测试
  16. 自动化:
  17. 自动化测试
  18. 自动化部署
  19. 日志:
  20. 格式统一
    重点是要能方便地定位到问题, 比如对于同一个请求的所有日志加上相同的标识
  21. 日志级别一定要分清楚,方便做异常监控
  22. 日志监控
  23. 对于请求响应类型的服务,建议分成以下日志文件:
    1. main.log / app.log 主日志,INFO 级别, 保留 15 天
    2. trace.log 调试日志,DEBUG 级别, 保留 3 天
    3. error.log 异常日志,ERROR 级别, 保留 30 天, 可以考虑加上
    4. monitor.log 监控日志
    5. access.log 访问日志
    6. api.log API 调用日志
    7. event.log 重要的时间点记录下来,比如 REQUEST_START, REQUEST_END 等, 保留 30 天
    8. data.log / db.log 数据库操作(包含 Redis), 保留 30 天
    9. message.log / mq.log MQ 消息, 保留 30 天
  24. 对于有监控需求的日志应该加上特殊标识,比如 Monitor:Daily, Monitor:5m, Monitor:UpstreamError
    这个根据监控策略来。
  25. 新开发的逻辑可以加入尽可能多的调试信息,日后根据实际情况调整。
  26. 设计:
  27. 需求评审之后,就要做设计评审(方案评审)
    1. 如果涉及数据库调整,应该由数据库团队参与评审
    2. 如果设计加购调整,应该由架构团队参与评审
  28. 对外接口调整需要谨慎
  29. 其他:
  30. 应当尽可能了解自己参与的项目,重要的数据应该能记住,比如重点客户信息,性能指标,流量等。

#370 Linux 相关标准

2020-03-09
  • Linux Standard Base (LSB)
  • Filesystem Hierarchy Standard (FHS)
  • Application Programming Interface (API) Standards
  • Single UNIX Specification version 4, The Open Group
  • Single UNIX Specification version 3, The Open Group
  • Single UNIX Specification version 2, The Open Group
  • DWARF Standards
  • DWARF Version 4
  • DWARF Version 3
  • DWARF Version 2.0
  • ELF and ABI Standards
  • Tool Interface Standard (TIS) Portable Formats Specification, version 1.1
  • Tool Interface Standard (TIS) Portable Formats Specification, version 1.2
  • System V ABI Edition 4.1
  • System V ABI - DRAFT 24 April 2001
  • Processor Specific ELF documents
  • System V Application Binary Interface Intel386 Architecture Processor Supplment, Fourth Edition
  • Intel Itanium Processor specific ABI
  • System V Application Binary Interface x86-64 Architecture Processor Supplement Draft Version 0.95 | v0.98 | v0.99
  • System V Application Binary Interface MIPS RISC Processor Supplment, 3rd Edition
  • System V Application Binary Interface PowerPC Processor Supplment. This is one of two known PPC ELF standards. This one was developed by SunSoft. The two versions are not identical, and applications can only conform to one or the other, while it seems possible for an implementation to support both simulaneously.
  • ARM Processor Supplment
  • Processor-Specific ELF Supplement for PA-RISC
  • Motorola 8 and 16 bit Embedded ABI
  • Application Binary Interface (ABI) Specifications/Standards
  • gLSB v1.2, Linux Standard Base
  • archLSB-IA32 v1.2, Linux Standard Base
  • archLSB-PPC32 v1.2, Linux Standard Base
  • 3DNow! (AMD K6 & Athlon), AMD
  • AMD Extensions to the 3DNow1 and MMX Instruction Set, AMD
  • Linux for S/390 (32bit) ELF ABI Supplement, IBM
  • Linux for zSeries (64bit) ELF ABI Supplement, IBM
  • C++ ABI for Itanium, v1.86
  • C++ ABI for Itanium, v1.83
  • C++ ABI for Itanium, v1.75
  • Intel Itanium Processor-Specific ABI
  • Related ABI Projects
  • Moblin 1.9.0 spec
  • Moblin 1.9.1 spec

参考资料与拓展阅读

#369 丰田生产方式与精益生产

2020-03-07

丰田生产方式(Toyota Production System,简称 TPS)是一种以精益生产为核心的生产方式,由日本丰田汽车公司所创立。TPS 的目标是通过消除浪费、提高效率和质量,实现生产过程的最优化,从而提高企业的竞争力。

TPS 的核心思想是“精益生产”,即通过消除浪费来提高生产效率和质量。TPS 将浪费分为七种类型,包括:

  1. 过产:生产过多的产品,导致库存过剩。
  2. 等待:生产过程中的等待时间,如等待零部件、等待机器维修等。
  3. 运输:产品在生产过程中的运输过程中产生的浪费。
  4. 过程:生产过程中的不必要的动作和步骤。
  5. 库存:过多的库存会占用空间、增加成本,并可能导致产品过期或损坏。
  6. 过度加工:对产品进行不必要的加工,增加成本和时间。
  7. 缺陷:产品出现缺陷,需要进行返工或废品处理。

TPS 通过消除这些浪费,实现生产过程的最优化。具体来说,TPS 采用了以下几种方法:

  1. 一次性流程:生产过程中,每个工人只负责一道工序,避免了多次加工和运输。
  2. 拉动生产:根据客户需求,生产所需的产品数量,避免了过产和库存过剩。
  3. 精益生产:通过不断改进生产过程,消除浪费,提高效率和质量。
  4. Jidoka:自动化生产过程中,发现异常情况时,自动停机,避免生产缺陷产品。
  5. Kaizen:不断改进生产过程,提高效率和质量。

TPS 的成功得益于其对生产过程的精细管理和不断改进的精神。TPS 的思想已经被广泛应用于各个领域,成为了一种重要的管理理念。

#368 浏览器端存储

2020-03-02

早期只有一种浏览器存储方式,就是万维网早期,由网景公司设计,加入了 HTTP 1.0 的 Cookie。
HTTP5 的时代,一次性加入了三种 API,分别是 Web Storage,IndexedDB,Web SQL。

  • Cookie:通过小型文本文件,在浏览器端存储一些字符类型 key-value 数据,支持设置一些属性。
  • 有单个 Cookie 的大小限制,也有 Cookie 总数限制。这个因浏览器不同而不同(大小尽可能控制在 4KB 以内)。
  • 每一次 HTTP 调用都会自动带上,发送给服务器端。
  • Web Storage:可以存储大量字符类型的 key-value 数据。
  • localStorage:没有时间限制。
  • sessionStorage:会话结束时自动清除。
  • IndexedDB:NoSQL 数据库,可以存储大量的结构化数据。API 相对复杂一丢丢
  • 功能强大,甚至支持事务和索引。
  • 异步 API。
  • Web SQL:基于 SQL 的浏览器端数据库,后来被废弃。

Cookie

Set-Cookie: name=value; expires=Mon, 21 Oct 2019 07:28:00 GMT; path=/; domain=.example.com; secure; HttpOnly
  • expires 过期时间,GMT 格式。如果不设置该属性,则 Cookie 的生命周期为当前会话,即关闭浏览器后 Cookie 就会被删除。
  • path 路径,表示该 Cookie 归属于哪个路径。默认为当前页面的路径。
  • domain 域名,表示该 Cookie 归属于哪个域名。默认为当前页面的域名。
  • secure 只能通过 HTTPS 协议传输,不能通过 HTTP 协议传输。
  • HttpOnly 只在网络传输时使用,不能通过 JavaScript 访问。

Web Storage

localStorage.setItem("key", "value");
var value = localStorage.getItem("key");

sessionStorage.setItem("key", "value");
var value = sessionStorage.getItem("key");
  • setItem(key, value) 存储数据
  • getItem(key) 读取数据
  • removeItem(key) 删除数据
  • clear() 清空数据 (删除所有的键值对)
  • key(index) 获取键名 (根据索引获取对应的键名)

IndexedDB

没有研究过。

// 打开数据库
var request = indexedDB.open("myDatabase", 1);

// 创建对象仓库
request.onupgradeneeded = function (event) {
  var db = event.target.result;
  var objectStore = db.createObjectStore("users", { keyPath: "id" });
  objectStore.createIndex("name", "name", { unique: false });
  objectStore.createIndex("age", "age", { unique: false });
};

// 存储数据
request.onsuccess = function (event) {
  var db = event.target.result;
  var transaction = db.transaction(["users"], "readwrite");
  var objectStore = transaction.objectStore("users");
  var user = { id: 1, name: "张三", age: 20 };
  var request = objectStore.add(user);
  request.onsuccess = function (event) {
    console.log("数据存储成功");
  };
};

// 读取数据
request.onsuccess = function (event) {
  var db = event.target.result;
  var transaction = db.transaction(["users"], "readonly");
  var objectStore = transaction.objectStore("users");
  var index = objectStore.index("name");
  var request = index.get("张三");
  request.onsuccess = function (event) {
    var user = event.target.result;
    console.log(user);
  };
};

#366 Git Hooks

2020-02-24

https://mp.weixin.qq.com/s/67qBDteTmHROeMwOBUeyaw
如何通过 Git 和 Husky 添加提交钩子并实现代码任务自动化

钩子 时机 用途
pre-commit 提交之前 代码检查
prepare-commit-msg 提交信息生成之前 生成提交信息
commit-msg 提交信息保存之前 检验提交信息
post-commit 提交之后 通知,自动测试,CI 等
pre-push push 之前 代码检查,测试,编译打包
applypatch-msg 生成补丁时 验证补丁信息
fsmonitor-watchman 文件系统监视器发现变化时 触发版本控制操作
pre-applypatch 应用补丁之前 验证补丁信息
pre-merge-commit 合并之前 检查将要合并的分支是否符合要求
pre-rebase rebase 操作之前 -
push-to-checkout - -
pre-receive 接受提交之前 代码检查,校验权限
post-receive 接受提交之后 通知,自动测试,CI 等
update 更新操作之前(分支、Tag) 提供从旧版本到新版本的改动列表供用户审核
post-update 更新操作之后(分支、Tag) 通知,自动测试,CI 等

示例

pre-receive

#!/usr/bin/env python

"""
每个人都只能提交代码到 username-date-branchName
username 是 git 用户名
date 是 mmdd 日期
branch 是分支描述,支持小写字母、数字、横杠,2 到 16 个字符
"""

import re
import subprocess
import sys

# 获取提交者的用户名
author = subprocess.check_output(['git', 'config', 'user.name']).decode().strip()

# 获取提交的分支名称
branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).decode().strip()

# 定义分支名称的正则表达式
branch_pattern = r'^%s-\d{4}-[a-z0-9\-]{2,}$' % (author,)

# 检查分支名称是否符合正则表达式
if not re.match(branch_pattern, branch):
    print('Error: Branch name "{}" does not match the required pattern "{}"'.format(branch, branch_pattern), file=sys.stderr)
    sys.exit(1)

# 解析日期并检查其是否合法
try:
    _, date_str, _ = branch.split('-')
    month, day = int(date_str[:2]), int(date_str[2:])
    if month < 1 or month > 12 or day < 1 or day > 31:
        raise ValueError
except ValueError:
    print('Error: Invalid date format in branch name "{}"'.format(branch), file=sys.stderr)
    sys.exit(1)