关于技术探索与实践的一些经验:一个双休不加班国企程序员的碎碎念
大家好,我是老张(真名就不说了,免得被领导认出来),在某家“效率优先、快乐工作”的大型国企做前端开发。说来惭愧,入行快两年了,没加过几次班,周五下午五点半准时关机走人已经成了我的职场信仰。虽然工资比不上大厂兄弟,但胜在稳定、清闲、还有年假能休满——毕竟我们组的口号是:“能拖到下周的需求,绝不今天上线”。
不过别误会,躺平归躺平,技术这东西我还是挺上心的。尤其是最近半年,组里开始搞一些“创新试点项目”,名义上是为了数字化转型,实际上嘛……大概率是为了写进年终汇报PPT里显得高大上。但正所谓“上有政策,下有对策”,既然任务落到了头上,那就得想办法把它做得漂亮点,顺便还能学到点新东西,何乐而不为?
今天这篇文章,就是想聊聊我在这些“被迫创新”过程中积累的一些关于技术探索与实践的经验。关键词?安排上了:资源、区块链、工具。别急,不是要你去炒币,也不是要你手搓智能合约,而是实实在在地、在有限资源下怎么把活干明白。
起因:一个“看起来很酷”的需求
去年年底,产品部的老王(对,又是他)在周会上抛出一个想法:“咱们能不能做个‘数字资产确权平台’?用户上传文件后,系统自动生成一个唯一标识,证明这个文件是他最早上传的。”
我一听就懵了:这不就是区块链干的事儿吗?但问题是——我们是个搞政务服务平台的国企团队,主力业务是表单填报、流程审批、数据报表,连数据库都还在用 Oracle 11g。突然整这么个“Web3.0 风格”的功能,是不是有点太超前了?
但老王振振有词:“领导看了某篇行业白皮书,说‘区块链赋能数字治理’,我们必须跟上趋势!”
运维小李当场翻白眼:“服务器都没几台,还区块链?”
然而,架不住 PPT 好看啊。于是这个需求就这么定了下来,Deadline 是春节前上线试运行——也就剩六周时间。
第一步:认清现实:资源永远不够
首先得承认,我们团队的资源极其有限:
- 开发人员:3 人(我 + 两个刚毕业的实习生)
- 服务器:2 台老旧虚拟机(4C8G,跑着 Tomcat + Nginx)
- 预算:0(“创新项目不额外申请经费”)
- 技术栈:Vue 2 + Java 8 + MyBatis
在这种条件下搞联盟链?公链?别闹了。别说以太坊,就算用 Fabric 或者 FISCO BCOS,光部署节点就得占掉一台服务器,还得配专人维护。而我们连 Docker 都还没全面普及。
所以,我做的第一件事不是查文档,而是砍需求。
我和老王反复拉扯了三次会,最终达成共识:
用户上传文件 → 系统计算 SHA256 → 将哈希值 + 时间戳 + 用户 ID 写入一个“不可篡改”的存储 → 提供查询接口证明“该哈希曾在某时由某人提交”。
注意,这里的关键字是“不可篡改”,而不是“去中心化”。我们不需要全网共识,只需要内部可信记录。于是,区块链的核心价值——防篡改 + 可追溯——可以用更轻量的方式实现。
技术选型:不追风口,只解决问题
既然不能上真·区块链,那有没有“类区块链”的方案?
我调研了几个方向:
| 方案 | 优点 | 缺点 | 是否可行 |
|---|---|---|---|
| 自建私有链(如 Ethereum PoA) | 真正的区块链特性 | 资源消耗大、运维复杂 | ❌ |
| 使用 IPFS + 区块链锚定 | 分布式存储+可信 | 需外部服务、成本高 | ❌ |
| 中心化数据库 + Merkle Tree 日志 | 实现简单、性能好 | 非真正去中心化 | ✅ |
| 直接用云服务商 BaaS(如阿里云区块链) | 快速上线 | 要钱、不符合信创要求 | ❌ |
最终我选择了 Merkle Tree + 时间戳日志 的混合方案。原理很简单:
- 每次用户上传,生成文件哈希
H - 将
(H, timestamp, user_id)存入常规数据库 - 同时,将
H加入当日的 Merkle Tree 叶子节点 - 每天凌晨,计算整棵树的根哈希
Root_Hash,并将其写入一个“只追加、不可删改”的日志表(用数据库触发器+权限控制保证不可篡改) - 对外提供 API:输入
H,返回其所在区块(日期)和对应的Root_Hash,用户可自行验证
这样既实现了“一旦写入无法抵赖”的效果,又完全运行在现有技术栈上,零新增依赖。
小插曲:实习生小刘一开始还想手写 Merkle Tree 算法,被我拦住了。我说:“兄弟,npm 上有现成的
merkletreejs,MIT 协议,直接用。”
他一脸崇拜:“哥,你咋知道这么多?”
我苦笑:“不是我知道多,是踩过的坑多。”
工具链:Mac + VS Code + 一点点仪式感
说到工具,我必须吹一下自己的开发环境。
虽然公司发的是 Windows 笔记本(用来连内网 OA 和测试 IE 兼容性),但我日常开发全靠自己的 MacBook Pro。为什么?因为:
- Terminal 好用(zsh + oh-my-zsh)
- Docker for Mac 流畅
- VS Code 插件生态丰富
- Homebrew 一键装环境
这次项目里,我主要用了这几个工具组合:
# 初始化项目
npm init vue@2
npm install merkletreejs crypto-js dayjs
# 本地模拟“不可篡改日志”
sqlite3 immutable_log.db "CREATE TABLE logs (date TEXT PRIMARY KEY, root_hash TEXT);"
# 单元测试
npm install -D jest @vue/test-utils
前端部分,我用 Vue 写了个简单的上传组件,配合 crypto.subtle.digest()(浏览器原生 API)计算 SHA256,避免传大文件到后端再算哈希,减轻服务器压力。
后端 Java 服务则负责:
- 接收哈希值
- 插入业务表
- 更新当日 Merkle Tree(内存缓存 + 定时落盘)
为了防止“自己人作假”,我还加了两条防护:
- 数据库日志表只允许 INSERT,禁止 UPDATE/DELETE(通过 DB 权限控制)
- 每日凌晨生成的
Root_Hash同时邮件发送给三位负责人(包括我自己),形成外部见证
真实场景吐槽:上周五晚上 6 点,我正准备关机去吃火锅,测试妹子突然喊:“上传接口报 500!”
我一看日志:java.security.InvalidKeyException: Illegal key size
原来是 JCE 无限制策略没装!赶紧远程登录服务器,scp 传 policy 文件,重启 Tomcat……
火锅凉了,但系统稳了。那一刻我深刻体会到:工具再好,也敌不过环境配置的玄学。
区块链?不如叫“信任链”
说实话,做完这个项目,我对“区块链”三个字祛魅了不少。
很多人一听到区块链就想到比特币、NFT、DeFi,觉得非得上链才算数。但在实际业务中,信任的本质不是技术,而是机制设计。
我们这个系统没有 P2P 网络,没有共识算法,没有 Token,但它满足了客户的核心诉求:提供一份不可抵赖的时间证明。从这个角度看,它就是一条“信任链”——哪怕只存在于一台服务器的日志表里。
而且,在资源受限的国企环境中,过度设计才是最大的技术债。要是当初真上了 Hyperledger,现在估计还在调 peer 节点通信,而需求早就黄了。
经验总结:三句大白话
资源决定技术边界
别被 buzzword 带节奏。先看自己有几台机器、几个人、多少时间。在国企,稳定 > 新颖,可维护 > 高大上。工具是杠杆,不是目的
我爱 Mac,但不代表 Windows 没用;我用 npm,但不代表不能抄 Stack Overflow。关键是快速验证想法,别在环境搭建上耗三天。区块链不是银弹,但“防篡改”是刚需
很多场景根本不需要去中心化,只需要一个“谁也改不了”的记录。这时候,一个设计良好的日志系统 + 权限控制 + 外部见证,比硬上链更靠谱。
最后:关于“双休不加班”的真相
可能有人会问:“你天天摸鱼,怎么还能搞这些创新?”
其实答案很简单:因为我把时间花在刀刃上。
我不参与无效会议(能线上绝不线下),不写没人看的文档(接口用 Swagger 自动生成),不重复造轮子(能 npm install 的绝不手写)。省下来的时间,用来研究真正有价值的技术。
而且,我们组有个不成文的规定:任何新技术引入,必须回答三个问题:
- 它解决了什么具体问题?
- 它带来了多少额外维护成本?
- 如果明天离职,新人能不能半小时看懂?
如果答不上来,那就别碰。
所以你看,所谓的“双休不加班”,不是躺平,而是用最小成本交付最大价值。技术探索也一样——不是为了炫技,而是为了让系统更可靠、让用户更安心。
附录:核心代码片段(简化版)
前端计算哈希(浏览器原生)
async function hashFile(file) {
const buffer = await file.arrayBuffer();
const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
后端 Merkle Tree 构建(伪代码)
// 每日缓存的叶子节点列表
List<String> dailyHashes = new CopyOnWriteArrayList<>();
public void addHash(String fileHash) {
dailyHashes.add(fileHash);
}
@Scheduled(cron = "0 0 0 * * ?") // 每天午夜
public void sealDay() {
MerkleTree tree = new MerkleTree(dailyHashes);
String rootHash = tree.getRoot();
// 写入不可变日志表(数据库 INSERT ONLY)
logDao.insertImmutableLog(LocalDate.now(), rootHash);
// 清空缓存
dailyHashes.clear();
// 发送邮件通知
emailService.sendToAdmins("今日根哈希: " + rootHash);
}
写完这篇,已经是周五晚上 5:20。
关机,走人。
下周再说吧。

评论 0