日常工作中的学习心得、技术总结与读书感悟
TCP(传输控制协议)是互联网中最重要的传输层协议之一。与 UDP 不同,TCP 提供可靠的、面向连接的通信服务。在开始传输数据之前,TCP 需要在通信双方之间建立连接,这个过程就是著名的"三次握手"(Three-way Handshake)。
三次握手的核心目的是:确认双方的发送和接收能力都正常,同时协商初始序列号(ISN)。简单来说,就是双方互相确认"我能发、你能收;你能发、我能收"。
整个过程如下:
seq = x。客户端进入 SYN_SENT 状态。seq = y,以及对客户端 SYN 的确认 ack = x + 1。服务器进入 SYN_RECEIVED 状态。ack = y + 1。此时连接建立完成,双方进入 ESTABLISHED 状态。如果只有两次握手,可能会出现一个经典问题:假设客户端之前发送了一个 SYN 报文,由于网络拥堵,这个报文在网络中滞留了很长时间。之后客户端重新发起连接并成功完成通信后断开了。此时那个滞留的 SYN 到达了服务器,服务器会认为这是一个新的连接请求,直接建立连接并等待数据——但客户端早已关闭,服务器就会白白浪费资源。
三次握手通过让客户端确认服务器的 SYN,解决了这个"历史连接"问题。
断开连接的过程称为"四次挥手"(Four-way Handshake),之所以需要四次而不是三次,是因为 TCP 是全双工通信,关闭连接需要双方分别关闭自己的发送通道:
TIME_WAIT 状态,等待 2MSL 后关闭。TIME_WAIT 状态持续 2MSL(Maximum Segment Lifetime,报文最大生存时间)。这个等待有两个目的:
理解 TCP 的连接管理机制,是掌握网络编程和排查网络问题的基础。很多生产环境中遇到的"连接超时""大量 TIME_WAIT"等问题,都与此密切相关。
Cal Newport 在《深度工作》(Deep Work)一书中提出了一个重要论断:在知识经济时代,能够进行"深度工作"——即在无干扰的专注状态下完成高认知需求任务的能力——正变得越来越稀缺,同时也越来越有价值。掌握深度工作的人,将在职业发展中拥有巨大优势。
深度工作(Deep Work)是指在无干扰的状态下进行的专业活动,它能将你的认知能力推向极限。这类工作能创造新价值、提升技能,且难以被复制。与之相对的是"浮浅工作"(Shallow Work),如回复邮件、参加无效会议、刷社交媒体等——这些任务往往在认知上不具有挑战性,容易被打断,也容易被替代。
读完这本书后,我决定采用"节奏式"哲学,每天早上 8:00-11:00 设定为深度工作时段。这期间关闭手机通知、不查看邮件和消息,专注于当天最重要的一项任务。下午则处理沟通、会议等浮浅工作。
一周下来,发现效率确实有明显提升。之前需要一整天完成的报告,现在 3 小时就能写完,而且质量更高。关键在于消除了频繁切换上下文带来的认知损耗。
"在一个越来越注意力涣散的世界里,专注就是超能力。" —— Cal Newport
在日常运维工作中,快速获取系统信息是最基本的需求。以下是一些常用命令:
# 查看系统内核版本 uname -a # 查看操作系统发行版信息 cat /etc/os-release # 查看 CPU 信息 lscpu # 查看内存使用情况 free -h # 查看磁盘使用情况 df -h # 查看系统运行时间和负载 uptime
进程管理是运维中最高频的操作之一。掌握以下命令可以快速定位和处理问题进程:
# 查看所有进程 ps aux # 实时监控进程(推荐用 htop 替代 top) top -c # 查找特定进程 ps aux | grep nginx # 查看进程树 pstree -p # 优雅地停止进程 kill -15 <PID> # 强制终止进程 kill -9 <PID> # 查看端口占用 ss -tlnp # 或者使用 netstat -tlnp
网络问题是最常见也最棘手的运维问题。以下命令能帮助快速定位网络故障:
# 测试网络连通性 ping -c 4 example.com # 路由追踪 traceroute example.com # DNS 查询 dig example.com nslookup example.com # 查看网络连接状态 ss -s # 查看网络接口信息 ip addr show # 抓包分析(需要 root 权限) tcpdump -i eth0 -nn port 80 -c 100 # 测试 TCP 端口连通性 nc -zv example.com 443
日志是排查问题的关键线索。高效地查看和分析日志能大幅提升排错效率:
# 实时跟踪日志 tail -f /var/log/syslog # 查看最后 100 行 tail -n 100 /var/log/nginx/error.log # 搜索关键词 grep "error" /var/log/syslog # 按时间范围过滤(结合 awk) awk '/2026-04-15 10:00/,/2026-04-15 11:00/' access.log # 统计错误次数 grep -c "500" access.log # 查看 systemd 服务日志 journalctl -u nginx --since "1 hour ago"
磁盘空间不足是经常遇到的问题,以下命令可以快速定位大文件:
# 查看目录占用空间(排序)
du -sh /* | sort -rh | head -20
# 查找大于 100MB 的文件
find / -type f -size +100M -exec ls -lh {} \;
# 查看 inode 使用情况
df -i
# 查看某个目录的文件数量
find /var/log -type f | wc -l
当系统出现性能问题时,需要从 CPU、内存、磁盘 I/O、网络四个维度进行排查:
top、mpstat、vmstat 查看 CPU 使用率和负载。如果 load average 超过 CPU 核心数,说明系统压力大。free -h 查看。注意 Linux 的缓存机制会占用大量内存,这是正常的。重点关注 available 字段。iostat -x 1 查看。如果 %util 接近 100%,说明磁盘已经饱和。iftop 或 nethogs 查看实时流量。养成命令行排查问题的习惯,比依赖图形界面监控工具更高效。遇到紧急问题时,SSH 登录服务器后能立即开始排查,这就是运维工程师的核心竞争力。
HTTP(HyperText Transfer Protocol)是一种明文传输协议,所有数据在网络中以明文形式传输,任何人只要截获了通信内容就能直接阅读。这在传输敏感信息(如密码、银行卡号)时存在严重的安全风险。
HTTPS = HTTP + TLS/SSL。TLS(Transport Layer Security,传输层安全协议)在 HTTP 和 TCP 之间增加了一层加密,确保数据在传输过程中的保密性、完整性和认证性。
TLS 握手是建立安全连接的关键步骤,主要完成三件事:协商加密算法、验证服务器身份、交换密钥。以 TLS 1.2 为例:
TLS 1.3 是 2018 年发布的最新版本,相比 1.2 有显著改进:
浏览器验证服务器证书的过程:
如果任何一步验证失败,浏览器会显示安全警告。这就是为什么使用自签名证书时浏览器会弹出"不安全"提示的原因。
理解 TLS 握手过程,不仅有助于排查 HTTPS 相关的问题,也能帮助我们更好地理解现代互联网安全的基石。
在团队协作中,没有统一的 Git 工作流会导致很多问题:代码冲突频繁、分支混乱、历史记录难以追溯、上线回滚困难等。一个好的 Git 工作流应该清晰、简单、易于团队成员遵守。
Git Flow 适合发布周期较长的项目。它定义了 main、develop、feature、release、hotfix 五种分支类型,各司其职。优点是结构清晰,缺点是分支管理复杂。
Trunk-Based Development(基于主干的开发)适合持续集成/持续部署(CI/CD)的团队。所有开发者都在 main 分支上工作,通过短生命周期的特性分支和频繁合并来保持代码库的更新。
好的提交信息是可维护代码库的基础。推荐使用约定式提交(Conventional Commits)格式:
<type>(<scope>): <description> # 类型: feat: 新功能 fix: 修复 bug docs: 文档变更 style: 代码格式(不影响功能) refactor: 重构 perf: 性能优化 test: 测试相关 chore: 构建/辅助工具变更
# 创建并切换到新分支 git checkout -b feature/user-auth # 暂存当前修改(不想提交但要切换分支时) git stash git stash pop # 查看提交历史(简洁模式) git log --oneline --graph # 修改最近一次提交 git commit --amend # 交互式变基(整理提交历史) git rebase -i HEAD~3 # 挑选特定提交到当前分支 git cherry-pick <commit-hash>
团队中推行 Git 规范最有效的方式不是写文档,而是在代码审查时坚持标准。让每个人都养成写好提交信息的习惯,长远来看会节省大量时间。
Docker 是一个开源的容器化平台,它允许开发者将应用程序及其所有依赖项打包到一个轻量级、可移植的容器中。容器可以在任何支持 Docker 的环境中运行,确保"在我的机器上能运行"这句话成为历史。
很多人会把容器和虚拟机搞混。它们虽然都提供了隔离的运行环境,但工作原理完全不同:
镜像(Image):只读的模板,包含运行应用所需的一切——代码、运行时、库、环境变量、配置文件。可以理解为"安装包"。
容器(Container):镜像的运行实例。从镜像创建,拥有自己的文件系统、网络、进程空间。可以理解为"正在运行的程序"。
Dockerfile:定义如何构建镜像的文本文件。类似于"安装脚本",描述了从基础镜像开始,需要执行哪些步骤来准备运行环境。
# 拉取镜像 docker pull nginx:latest # 运行容器 docker run -d --name my-nginx -p 8080:80 nginx # 查看运行中的容器 docker ps # 查看容器日志 docker logs -f my-nginx # 进入容器 docker exec -it my-nginx /bin/bash # 构建自定义镜像 docker build -t my-app:1.0 . # 停止并删除容器 docker stop my-nginx && docker rm my-nginx
当项目需要多个服务协同工作时(如 Web 服务器 + 数据库 + 缓存),手动管理每个容器会非常麻烦。Docker Compose 通过一个 YAML 文件定义多容器应用,一条命令就能启动所有服务。
容器化不仅解决了"环境不一致"的问题,还极大地简化了部署和扩展的流程。学会使用 Docker,是每个开发者和运维工程师的必备技能。
德国心理学家赫尔曼·艾宾浩斯通过实验发现,人的记忆会随时间指数级衰减。学习后的 20 分钟,遗忘率约 42%;1 天后约 74%;1 周后约 77%。这就是著名的"遗忘曲线"。
但好消息是,每次复习都会让遗忘的速度变慢。第一次复习后,记忆可能保持 2 天;第二次复习后,保持 1 周;依此类推。这就是间隔重复的理论基础。
间隔重复是指在记忆即将衰退之前进行复习,每次复习后适当延长下次复习的间隔。这是目前认知科学证实的最有效的长期记忆策略之一。
典型的间隔可以是:学习后 → 1天后 → 3天后 → 7天后 → 14天后 → 30天后。具体间隔因人而异,关键是在"快要忘记"的时候复习。
相比被动地重读笔记或教材,主动尝试回忆所学内容的效果要好得多。研究表明,主动回忆的学习效果是重复阅读的 2-3 倍。
实践方法:
Anki 是目前最流行的间隔重复软件,它会根据你的回忆表现自动调整复习间隔。虽然界面比较简陋,但算法经过了大量实践验证,非常有效。适合记忆知识点、单词、公式等结构化信息。
学习不在于花了多少时间,而在于用了什么方法。掌握正确的学习方法,事半功倍。
这应该是每个开发者都知道的基本安全原则。如果数据库被泄露(这种事件比想象中更常见),明文存储的密码意味着所有用户的账号安全直接暴露。考虑到很多用户会在不同网站使用相同密码,一次泄露可能导致多个账号被攻破。
密码应该经过哈希函数处理后再存储。哈希函数是一种单向函数,能将任意长度的输入转换为固定长度的输出(哈希值)。关键特性是:无法从哈希值逆推出原始输入。常见的哈希算法有 MD5、SHA-1、SHA-256 等。
但仅仅使用哈希还不够安全。攻击者可以预先计算大量常见密码的哈希值,形成"彩虹表"。当拿到哈希值后,直接查表就能还原密码。
为了对抗彩虹表攻击,引入了"盐值"的概念。盐值是一个随机字符串,在密码被哈希之前与密码拼接。每个用户使用不同的盐值,这样即使两个用户使用相同的密码,存储的哈希值也完全不同。
# 不加盐(容易被彩虹表攻击)
hash("password123") → "ef92..."
# 加盐(每个用户盐值不同)
hash("a8f3e2" + "password123") → "7b3d..."
hash("c1d9f7" + "password123") → "4e6a..."
MD5 和 SHA 系列设计目的是快速计算,不适合密码哈希。攻击者可以用 GPU 每秒计算数十亿次。推荐使用专门为密码设计的慢哈希算法:
密码安全是信息安全的第一道防线。即使是"内部系统",也必须做好密码保护,因为你永远不知道数据会在什么时候以什么方式泄露。
如果没有索引,数据库在查找数据时只能逐行扫描整张表(全表扫描)。当表中有 100 万条记录时,即使是简单的 WHERE id = 123 查询也需要扫描 100 万行。有了索引,同样的查询只需要访问几个节点就能定位到目标行。
MySQL 的 InnoDB 引擎使用 B+ 树作为索引的底层数据结构。B+ 树是一种平衡多路搜索树,有以下关键特性:
以一个存储 1000 万条记录的表为例,B+ 树的高度大约为 3。这意味着通过索引查找一条记录,只需要 3 次磁盘读取,而全表扫描可能需要数万次。
聚簇索引(Clustered Index):InnoDB 的主键索引就是聚簇索引,表数据按照主键顺序物理存储。每张表只能有一个聚簇索引。
二级索引(Secondary Index):非主键字段上的索引。二级索引的叶子节点存储的是主键值,而不是数据行。通过二级索引查找数据需要"回表"——先通过二级索引找到主键,再通过主键在聚簇索引中找到数据行。
(a, b, c) 可以用于 a、a,b、a,b,c 的查询,但不能用于 b 或 c 的单独查询。WHERE YEAR(created_at) = 2026 无法使用索引,应改为范围查询。EXPLAIN SELECT * FROM users WHERE email = 'test@example.com'; # 关注字段: # type: ALL(全表扫描) → ref(索引查找) 越好 # key: 实际使用的索引 # rows: 预估扫描行数 # Extra: Using index(覆盖索引), Using filesort(需要排序)
索引不是越多越好。每个索引都会占用存储空间,并且在写入数据时需要额外维护。合理的索引设计需要在查询性能和写入性能之间找到平衡。
很多时候,我们以为自己理解了一个概念,但当尝试把它写下来时,才发现理解并不透彻。写作迫使我们将模糊的想法具体化、结构化,这个过程本身就是深度思考。
费曼学习法的核心也在于此:如果你不能用简单的语言向别人解释一个概念,说明你还没有真正理解它。写笔记就是在和未来的自己对话,也是在检验自己是否真正掌握了所学的知识。
虽然用本地笔记软件记录也可以,但公开写作有几个额外的好处:
不需要每篇都写得很长、很完美。一个小的技术发现、一段有启发的文字、一个解决问题的思路,都值得记录。重要的是坚持,让写笔记成为日常习惯的一部分。
"写作不是在记录你知道的东西,而是在发现你知道的东西。" —— Flannery O'Connor