线上出问题的时候,真正卡住人的往往不是难题,而是几条记不牢的命令和几个含义相近的数字。这篇把五类最常翻的速查内容按「怎么判断该用哪一个」的逻辑串一遍,重点放在容易选错的那几处,以及选错之后会丢什么。
一、Git 撤销:先分清改动在哪一层
Git 的撤销命令之所以容易用错,是因为同一个词「撤销」对应四种完全不同的状态。动手之前先用 git status 确认改动在哪一层,再选命令。
- **只改了工作区,还没
git add**:用git restore <file>(旧版是git checkout -- <file>)。这条命令会把文件还原成上次提交的样子,你的改动直接消失,Git 从未记录过它,reflog也找不回。这是最常见的「一秒钟毁掉半天工作」。 - 已经
git add,还没提交:用git restore --staged <file>把它从暂存区退回工作区,改动内容保留。这一步是安全的。 - 已经提交,还没推送:用
git reset配合三种模式。--soft HEAD~1撤掉提交但改动留在暂存区;默认的--mixed撤掉提交、改动退回工作区;--hard连改动一起丢掉,而且工作区里未提交过的内容无法通过reflog恢复。 - 已经推送到远端:不要改写历史,用
git revert <commit>生成一个反向提交。别人已经基于那个提交工作了,reset加强推会把他们的仓库搞乱。
两条值得养成的习惯:强制推送一律写成 git push --force-with-lease,它会在远端有别人的新提交时拒绝执行,而 --force 会直接覆盖;清理未跟踪文件先用 git clean -n 预演一遍,git clean -f 是永久删除,不进回收站也不进 Git。
误操作之后第一件事是执行 git reflog。只要内容曾经被提交过,绝大多数都能从那里找回哈希再 git checkout 或 git reset 过去。Git命令速查把约七十条命令分成八类并逐条可复制,危险操作单独集中在风险提示区,不确定后果时先在那里对一眼。
二、Linux 权限位:755 与 644 到底在说什么
权限位是三组各三位:所有者、所属组、其他用户,每组是读(4)、写(2)、执行(1)的和。
- 755 的含义是所有者可读可写可执行,组和其他用户可读可执行。它用在两处:可执行脚本,以及所有目录。
- 644 的含义是所有者可读可写,其他人只读。它用在普通文件,包括配置、网页、图片。
目录必须有执行位,这是最反直觉的一点。对目录来说,x 不是「运行」而是「进入与遍历」的权限。把目录设成 644 之后,即使有读权限也无法 cd 进去、无法读取里面任何文件,表现为「明明给了读权限却打不开」。所以递归修改权限时,chmod -R 755 会把所有普通文件也变成可执行,chmod -R 644 会让整棵目录树无法进入。正确做法是目录和文件分开处理,chmod权限计算器里给出了配合 find 的现成写法。
私钥文件必须是 600。SSH 会主动检查私钥权限,只要组或其他用户能读,客户端会直接拒绝使用这把钥匙并报权限过于开放的错误。
第四位是特殊权限,风险集中在这里:
- SUID(4):程序运行时使用文件所有者的身份而不是调用者的身份。属主是 root 的 SUID 程序一旦存在命令注入或缓冲区问题,就是一条现成的本地提权路径。自己写的脚本永远不要加 SUID,很多系统上对脚本加 SUID 本身就无效。
- SGID(2):加在目录上时,目录里新建的文件会继承目录的所属组,多人协作目录用 2775 就是这个用途。
- 粘滞位(1):加在共享可写目录上,让每个人只能删除自己创建的文件,
/tmp的 1777 就是这样来的。没有粘滞位的 777 目录,任何人都能删掉别人的文件。
符号表示里的大小写有讲究:执行位存在时显示小写 s 或 t,执行位不存在时显示大写 S 或 T,看到大写通常意味着权限设得不完整。至于 777,它几乎总是「不想再排查权限问题了」的产物,也几乎总是错的,尤其是 Web 目录,可写意味着上传的文件可能被改写。
三、端口:占用排查与不该暴露的那几个
端口号按范围分三段,选端口前先知道自己在哪一段:0 到 1023 是系统端口,Linux 下绑定需要 root 权限;1024 到 49151 是注册端口,自建服务应该落在这里;49152 到 65535 是动态与私有端口,客户端发起连接时的临时端口通常从这个范围分配,服务监听到这里可能与临时端口撞车。
「端口被占用」的排查是固定套路:先确认谁在监听,再决定是换端口还是停掉旧进程。
ss -ltnp | grep :3306
netstat -ano | findstr :3306
第一条是 Linux,-l 只看监听、-t 只看 TCP、-n 不做名称解析、-p 显示进程;也可以用 lsof -i:3306。第二条是 Windows,输出最后一列是 PID,再到任务管理器的详细信息里按 PID 找进程。常用端口速查按 Web、远程、邮件、数据库、缓存与消息队列等分类整理了约五十个默认端口,排查命令可以直接复制。
真正需要警惕的是几个数据库与中间件端口:3306、5432、6379、27017、9200。它们不应该直接监听公网地址。Redis 与 Elasticsearch 的未授权访问长期是最常见的入侵入口之一,因为默认配置往往不要求认证,扫到就能读写。正确做法是绑定内网地址、用安全组或防火墙限制来源 IP、开启认证。把 6379 改成 16379 只能减少扫描噪音,不能替代认证与访问控制,攻击者的扫描器不看默认端口表。
四、HTTP 状态码:先看第一位数字
排查接口问题的第一个判断是「该找前端还是找后端」,答案就在第一位数字里。4xx 是客户端错误,请求本身有问题,服务端拒绝了它;5xx 是服务端错误,请求没毛病但服务端处理失败。这一刀切下去,能省掉一半的扯皮。
3xx 里最容易选错的是几个重定向码,区别在于「允不允许把 POST 改写成 GET」:
- 301 永久重定向:历史实现普遍会把 POST 改写成 GET,所以它对非幂等请求不安全。
- 308 永久重定向:明确要求保持原方法与请求体,POST 仍然是 POST。需要永久跳转又涉及表单提交时用它。
- 302 临时重定向:语义含糊,多数客户端会把 POST 改成 GET,这是历史遗留而非规范意图。
- 303:明确要求改用 GET,典型用途是表单提交成功后跳到结果页,避免刷新时重复提交。
- 307 临时重定向:明确要求保持原方法与请求体,是 302 在语义上的严格版本。
4xx 与 5xx 里几组高频混淆:401 是未认证,缺凭证或凭证无效,响应应带 WWW-Authenticate;403 是已认证但没有权限,换个账号可能就能访问。404 是不存在,410 是曾经存在已被永久删除,后者能让搜索引擎更快地把页面从索引里拿掉。502 是网关拿到了上游的无效响应,503 是服务暂时不可用(通常是过载或维护,应带 Retry-After),504 是网关等上游超时。
日志里还会出现几个非标准码,别误以为是应用返回的:499 是 Nginx 记录客户端主动断开连接,520、521 通常来自 CDN。499 和 504 的区分很有用:前者是客户端等不下去先走了,后者是上游超时,优化方向完全不同。HTTP状态码速查按五类整理了约五十个状态码并标注了非标准码来源,还专门列了这些易混淆组的辨析。
设计接口时有一条原则:不要一律返回 200 再在响应体里塞自定义错误码。语义正确的状态码才能被网关、CDN、重试策略和监控告警正确识别,塞在 body 里的错误码它们全都看不见。
五、CIDR:可用主机数是怎么算出来的
192.168.1.0/24 里的 24 是前缀长度,表示前 24 位是网络位,剩下的是主机位。可用主机数就从这里推出来:
可用主机数 = 2 ^ (32 - 前缀长度) - 2
/24 是 2 的 8 次方等于 256 个地址,减 2 得 254。减掉的两个是主机位全 0 的网络地址和全 1 的广播地址,它们不能分配给主机。/26 是 64 个地址、62 个可用,/22 是 1024 个地址、1022 个可用。前缀每加长 1 位,地址数减半。
两个特例不适用这个公式:/31 用于点对点链路,两个地址都可用;/32 表示单个主机,常见于路由表和 ACL 里的精确匹配。见到「可用主机数为负」的计算结果就是工具没处理这两个特例。
云环境里还要再减几个。多数云厂商的 VPC 会额外保留每个子网的前几个地址(网关、DNS 等)和最后一个地址,所以一个 /24 子网实际能分配的往往是 251 个左右而不是 254 个。规划网段时按厂商文档留余量,别卡着算。
IP子网计算器除了这些基础换算,还有两个排查场景特别顺手:一个是子网划分,把 /24 拆成 /26 时直接列出四个子网各自的网络地址、广播地址与可用范围,不用手算边界;另一个是 IP 归属判断,输入一个地址确认它是否落在某个网段内,核对安全组规则和 ACL 时比数二进制位快得多。二进制视图也值得看一眼,掩码是怎么把网络位和主机位切开的,看一遍就不容易再记错。
常见问题
git reset --hard 之后真的一点办法都没有吗?
分两种情况。已经提交过的内容能救:用 git reflog 找到那个提交的哈希,再 git reset --hard <哈希> 或 git checkout <哈希> 回去,Git 默认保留 90 天的可达记录。从未提交过的工作区改动救不回来,Git 从来没有记录过它们。这就是为什么频繁提交或至少 git stash 一下是有价值的,即使提交信息写得潦草。
为什么我给目录加了读权限,还是进不去?
目录缺执行位。对目录而言 x 控制的是「能否进入与遍历」,只有 r 没有 x 时,你连里面有什么文件都列不出来。目录的正确权限是 755(或需要保密时 700),不要用 644。反过来,普通文件不需要执行位,chmod -R 755 把所有文件设成可执行是另一种常见误操作。
改掉数据库的默认端口能提升安全性吗? 只能减少无脑扫描带来的日志噪音,安全性提升几乎为零。端口扫描器会遍历端口并根据握手特征识别服务类型,改端口拦不住它。真正有效的是三件事:绑定内网地址不监听 0.0.0.0、用安全组或防火墙按来源 IP 白名单放行、开启强口令认证。这三件做到了,默认端口也是安全的;没做到,改成什么端口都会被找到。
接口返回 502 和 504,我该先查哪一边? 两者都指向上游服务而不是网关本身,但症状不同。502 说明网关连上了上游却拿到无法解析的响应,常见原因是上游进程崩了、端口没起来、协议不匹配,先看上游服务的进程状态和错误日志。504 说明网关一直等到超时也没拿到响应,先看上游是不是有慢查询、锁等待或线程池耗尽,再对比网关的超时配置是否短于上游的正常处理时间。