记录学习,沉淀经验 —— IT小栈
个人技术学习笔记:编程学习心得 · 技术方案整理 · 工作经验总结
📒 学习笔记
💻 编程心得
🛠 方案整理
🌱 非经营性个人站点
10篇原创笔记
3个内容栏目
0商业经营内容
2026持续记录中
关于本站
IT小栈(smart-now.top)是一个什么样的网站。
IT小栈是什么
IT小栈(smart-now.top)是我的个人技术学习笔记站点,用于记录编程学习心得、技术方案整理及工作经验总结。站点内容全部来源于个人学习与工作中的真实积累,主要包括:
- 编程语言与框架的学习笔记(Java、JavaScript、SQL 等);
- 日常开发与运维中验证过的技术方案(Docker、Nginx、Git、备份等);
- 工作方法、文档写作、学习效率方面的随笔总结。
写笔记的初衷是把零散的知识沉淀下来,方便自己随时查阅;如果刚好能帮到有同样问题的同行,那就更好了。本站不追求更新频率,只保证每一篇都是自己实践过、验证过的内容。
站点性质声明
本站为个人非经营性网站,仅用于个人技术学习笔记的记录与分享:
- 不涉及任何商业经营活动,无广告、无电商、无收费服务;
- 不提供新闻、出版、教育、医疗保健等需前置审批的信息服务;
- 不设立论坛、留言板等交互式栏目,不发布用户生成内容;
- 站内文章均为站长原创或整理,转载请注明出处。
Java Stream 流式处理的常用写法整理
Java学习笔记发布于 2026-06-18 · 阅读约 4 分钟
Stream 是 Java 8 引入的集合处理工具,核心价值在于把“怎么遍历”交给框架,自己只描述“要做什么”。以下是我日常用得最多的几种写法。
1. 过滤与收集
List<String> names = users.stream()
.filter(u -> u.getAge() >= 18)
.map(User::getName)
.collect(Collectors.toList());
2. 按字段分组统计
Map<String, Long> countByDept = users.stream()
.collect(Collectors.groupingBy(User::getDept, Collectors.counting()));
3. 平铺嵌套集合
当一个对象里嵌着另一个集合时,用 flatMap 把它摊平成一条流,再统一处理,避免双层 for 循环。
个人体会
- Stream 链不宜过长,超过 4~5 个操作就拆成两段,可读性优先;
- 并行流
parallelStream() 在数据量小、逻辑简单时反而更慢,不要默认使用;
- 集合只需要查一次的话,普通 for 循环也完全没问题,不必为了用而用。
MySQL 索引失效的几种典型场景
MySQL数据库发布于 2026-05-27 · 阅读约 5 分钟
起因是一条看似普通的查询在线上跑了 8 秒。用 EXPLAIN 一看,全表扫描。复盘后把索引失效的常见原因整理如下:
- 隐式类型转换:字段是 varchar,查询条件却传了数字,数据库会做类型转换,索引直接失效;
- 索引列被函数包裹:如
WHERE DATE(create_time) = '2026-05-01',应改写为范围查询;
- 违反最左前缀:联合索引 (a, b, c) 却只按 b 或 c 查询;
- 前导模糊匹配:
LIKE '%abc' 无法走索引,'abc%' 可以;
- OR 连接非索引列:OR 两侧有一侧无索引,优化器可能放弃索引。
排查套路
先看 EXPLAIN 的 type 列(出现 ALL 即全表扫描),再看 key 列实际用了哪个索引,最后对照上面清单逐项排除。这次的问题就是手机号字段传了数字导致的隐式转换。
Docker 入门:常用命令与镜像构建笔记
Docker运维发布于 2026-04-09 · 阅读约 4 分钟
高频命令速查
docker ps -a # 查看全部容器
docker images # 查看本地镜像
docker run -d -p 8080:80 --name web nginx
docker logs -f web # 跟踪日志
docker exec -it web bash # 进入容器
docker stop web && docker rm web
一份简单的 Dockerfile
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
踩坑记录
- 容器里的时区默认是 UTC,Java 应用日志时间会差 8 小时,需要挂
/etc/localtime 或设置 TZ=Asia/Shanghai;
- 构建时把
.git、日志目录写进 .dockerignore,镜像体积能小很多。
JavaScript 异步编程:从回调到 async/await
JavaScript前端发布于 2026-03-15 · 阅读约 4 分钟
JS 单线程的模型决定了异步是绕不开的话题。三代方案对比下来,我的结论是:新代码一律用 async/await,但理解 Promise 的原理仍然必要——async/await 本质上就是 Promise 的语法糖。
三种写法对比
// 回调:嵌套深、错误处理分散
getUser(id, function(user){ getOrders(user, function(orders){ ... }); });
// Promise:链式调用,统一 catch
getUser(id).then(getOrders).then(render).catch(handleError);
// async/await:写法最贴近同步思维
const user = await getUser(id);
const orders = await getOrders(user);
容易忽略的点
await 串行等待会拖慢速度,互不依赖的请求要用 Promise.all 并发;
- async 函数抛出的错误等价于 Promise reject,调用方别忘 try/catch。
个人服务器数据备份方案
Linux备份发布于 2026-05-10 · 阅读约 4 分钟
需求很简单:把网站目录和数据库每天备份一次,保留最近 14 天,出问题时能快速恢复。最终方案是 crontab + rsync + mysqldump,零额外成本。
备份脚本(节选)
#!/bin/bash
DATE=$(date +%F)
DEST=/backup/$DATE
mkdir -p $DEST
rsync -a /var/www/html $DEST/site
mysqldump -u root myblog > $DEST/myblog.sql
# 清理 14 天前的备份
find /backup -maxdepth 1 -mtime +14 -exec rm -rf {} \;
验证比备份更重要
备份完一定要做一次恢复演练:把 sql 导入测试库、把站点目录解压到临时路径起个本地服务确认能打开。“没验证过的备份等于没有备份”,这是这次整理最大的收获。
Nginx 反向代理与 HTTPS 配置记录
NginxHTTPS发布于 2026-04-22 · 阅读约 4 分钟
反向代理基本配置
server {
listen 80;
server_name smart-now.top;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
502 排查顺序
- 先看后端服务是否存活:
curl 127.0.0.1:8080;
- 再看 Nginx 错误日志
error.log,是连接被拒还是超时;
- 最后确认防火墙/安全组有没有放行对应端口。
HTTPS 使用免费证书,配合定时任务自动续期即可,个人站点完全够用。
Git 分支管理的小型团队实践
Git协作发布于 2026-02-28 · 阅读约 3 分钟
完整的 Git Flow 对 3~5 人的小团队偏重,我们在实践中简化成三条规则:
- main 分支:永远保持可发布状态,只接受合并,不直接提交;
- feature 分支:一个需求一个分支,命名
feature/简述,完成后合并并删除;
- tag 发版:每次上线打一个 tag(如
v1.3.0),出问题可随时回滚到任意版本。
冲突处理心得
冲突大多源于分支活得太久。功能分支尽量三天内合回主干;合并前先 git rebase main 把冲突在小范围内解决掉,比合并时爆一堆冲突好处理得多。
一次代码评审带来的几点反思
方法论发布于 2026-06-02 · 阅读约 3 分钟
上周提交的功能在评审时被指出了不少问题,记下来引以为戒:
- 命名:方法名
deal() 这种动词太泛,改成 importOrderFile() 后不用看实现也知道在干什么;
- 异常:catch 之后只打印日志不处理,等于把问题埋掉。要么恢复、要么继续抛出,不能“吞掉”;
- 日志:关键分支要有日志,且带上业务主键(如订单号),否则排查问题时无从检索。
之后我给自己定了一条提交前自查清单:命名是否表意、异常是否妥善处理、日志是否可追踪。过了清单再提评审,返工明显少了。
技术文档怎么写,别人才看得懂
文档发布于 2026-03-30 · 阅读约 3 分钟
写文档和写代码一样,读者不是自己。这几年写接口文档和部署文档,总结出三条最管用的原则:
- 先场景后参数:开头用一句话说明“这个接口在什么场景下用”,再列参数表,读者才不会迷失在字段里;
- 最小可运行示例:给一段能直接复制运行的 curl 或代码,比十行文字说明都管用;
- 把坑写进 FAQ:部署时遇到过的每个报错都记进 FAQ 并附解决办法,后来者能省掉大量时间。
判断文档写没写好的标准很简单:换一个不了解背景的人,照着文档能不能独立完成。
工作多年后再谈“如何学习一门新技术”
学习方法发布于 2026-01-16 · 阅读约 3 分钟
刚毕业时学新技术的方法是“找套教程从头看到尾”,结果往往是看完就忘。这些年逐渐迭代出更适合自己的路子:
- 带着问题做 demo:先想一个自己真实需要的小工具(比如批量重命名脚本),边做边查,知识是在解决问题时记住的;
- 输出倒逼输入:学完强迫自己写一篇笔记——能写明白才算真懂,写不下去的地方就是没懂的地方;
- 接受“够用就好”:工作中用不到的高级特性,先知道它存在即可,用到时再深入,避免在低频知识上消耗热情。
这个站点本身就是这条方法的实践:把学过的东西写下来,既沉淀给自己,也希望能帮到路过的人。