我在创业公司当程序员的那些事

栈顶的鱼
2025-12-13 10:48
阅读 721

外包干了四年,见过的需求比你吃过的盐还多:要给后台加个“一键变美”按钮的、要求用 Excel 做实时协作系统的、甚至还有让我把 Python 写成 C++ 性能的(对,就上周)。本以为自己已经练就了一身“需求免疫”,结果两个月前跳槽进这家 A 轮创业公司,还是被现实狠狠教育了一顿。

刚入职那天,CTO 拍着我肩膀说:“我们这里节奏快,但技术自由度高。” 我当时还暗自窃喜——终于不用再写那些祖传 jQuery 项目了。没想到,“节奏快”是真的快到飞起,“技术自由”是自由地选择用哪个框架重写上周刚上线的功能。


需求?不,那是每日刷新的任务副本

上个月,产品经理在周五下午四点半甩过来一个需求:“我们要做一个动态表单引擎,支持拖拽、条件联动、多级嵌套,下周一上线。”

我盯着 Slack 消息看了足足十秒,心想:这怕不是把我当成 GPT-5 来用了?但转念一想,创业公司嘛,不就是“不可能任务”的代名词?而且我最近正研究开源的低代码平台源码(比如 Formily、React JSON Schema Form),正好拿这个当实战。

于是我咬咬牙接了。毕竟,谁让我是个喜欢钻源码、关注架构设计的老外包呢?虽然现在身份变了,但骨子里那股“代码洁癖”还在。


JavaScript 的“优雅”陷阱

一开始,我想用纯函数式思路搞一套干净的状态管理:每个字段一个 reducer,联动逻辑用 RxJS 处理。结果写到一半发现——产品经理根本没考虑过“循环依赖”的场景。比如:A 字段变化触发 B,B 又反过来影响 A,直接死循环。

本地还好,一上测试环境,页面卡成 PPT。Chrome DevTools 里 Performance 面板拉出来一看,call stack 长得能绕地球一圈:

Uncaught RangeError: Maximum call stack size exceeded
    at Field.update (field.js:42)
    at Field.update (field.js:42)
    // ... 重复几百行

那一刻,我真的想砸电脑。但冷静下来一想:创业公司资源有限,不能指望 PM 把所有边界情况都想清楚。作为开发者,得自己兜底。

于是我把状态管理改成了基于事务队列 + 异步调度的模式,类似 Vue 3 的 nextTick 机制。核心思想是:任何字段变更先入队,批量处理,避免同步递归。代码大概长这样:

class FormEngine {
  updateQueue = [];
  
  scheduleUpdate(field, value) {
    this.updateQueue.push({ field, value });
    if (this.pending) return;
    this.pending = true;
    Promise.resolve().then(() => {
      this.processQueue();
      this.pending = false;
    });
  }

  processQueue() {
    const updates = [...this.updateQueue];
    this.updateQueue = [];
    // 执行更新 + 联动计算,但限制最大迭代次数防死循环
    let count = 0;
    while (updates.length && count < 10) {
      // ...执行逻辑
      count++;
    }
  }
}

虽然糙了点,但至少不会崩。上线后跑得稳稳的,连测试都夸我“这次没出幺蛾子”。


技术分享?先活下来再说

说到技术分享,其实我一直挺想组织团队做内部 workshop 的。之前在外包公司时,我就经常拉着同事讲 V8 引擎原理、Webpack 插件机制,甚至手撕过 React Fiber 的简易版。

但在这儿,现实很骨感。大家每天都在赶 deadline,晨会三句话离不开“进度”“阻塞”“能不能砍功能”。有一次我提议搞个“JS 性能优化小课堂”,结果被反问:“能帮我们提前一天上线吗?”

行吧,理解万岁。但我还是偷偷在团队 Wiki 里建了个《避坑指南》栏目,把踩过的雷都记下来。比如:

不要用 JSON.stringify 做深比较
看似简单,但遇到 circular reference 直接崩。改用 lodash.isEqual 或自定义 diff 算法。

别信“一行代码搞定”
某些开源库号称“轻量级”,结果 bundle 一打进去,体积涨了 300KB。一定要看源码!

慢慢地,居然有新人开始主动来问问题了。上周五晚上加班时,一个实习生跑来问我:“哥,这个闭包内存泄漏怎么排查?” ——那一刻,我觉得值了。


架构 vs 效率:创业公司的永恒悖论

作为有点架构洁癖的人,我特别受不了“屎山代码”。但在这里,MVP(最小可行产品)才是王道。领导说得直白:“先跑起来,再优化。”

于是我们达成了一个微妙的平衡:核心模块写得尽量干净,边缘功能允许“战术性脏代码”

举个例子,我们有个数据看板,初期直接用 ECharts + 手写配置,性能差得一批。但因为只是内部用,没人投诉。直到用户量上来,老板亲自吐槽“加载像蜗牛”,我才被批准重构。

这次我用了 Web Worker + 虚拟滚动 + 数据分片,首屏加载从 8s 降到 1.2s。关键是我提前写了 benchmark 对比表,用数据说话:

方案 首屏时间 Bundle Size 内存占用
原始方案 8.2s 1.8MB 320MB
重构后 1.2s 1.5MB 98MB

有了这张表,老板眼睛都亮了,当场拍板:“以后性能优化都按这个标准来!”


写在最后:外包老兵的自我救赎

说实话,在创业公司这两个月,比我过去两年学得都多。不是技术多高深,而是学会了在混乱中建立秩序

我不再执着于“完美架构”,但也不会放任烂代码蔓延。我会为了 deadline 写点 hack,但一定会在注释里标上 // TODO: refactor after launch。我依然研究开源项目源码,但目的不再是“炫技”,而是找能真正解决问题的轮子。

如果你也刚从大厂或外包跳槽到创业公司,我的建议就一句:别怕脏手,但别丢掉思考

技术分享不是站在台上讲 PPT,而是在 PR 里写好注释,在 Slack 里耐心解答新人问题,在深夜修复线上 bug 后顺手更新文档。

毕竟,我们写的不是代码,是未来的自己。


P.S. 上周那个动态表单,现在已经被 PM 用来生成“员工满意度调查”了。讽刺的是,他自己填的时候卡了三次……我默默在后台加了条日志:console.warn('PM is struggling again')

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝