刚看到一个帖子在讨论,说是有位网友分享了一件事:他朋友所在的团队里,一位30岁、年薪85万的高级工程师,因为不愿意参与流程管理和团队协作优化,被调离了核心项目。
这位工程师的Leader给出了一个评价:他是能跑的马,但不愿意拉车。

对公司而言,支付这样一份薪水,购买的远不止是你的技术能力,还包括你解决团队层面问题的能力。你可以不喜欢开会、不喜欢跨部门拉通、也不喜欢写繁琐的流程文档,但直接拒绝参与这些事务,本质上是在拒绝承担更大范围的责任。那么,从业务决策的角度看,被移出核心项目也算是一个合理的结果。
当然,公司这边也不能总是用“拉车”来对员工进行道德绑架。如果流程本身过于冗杂、创造不了实际价值,员工的抗拒心理完全可以理解。所以,关键还是得想清楚自己的定位——要么就安心做一个顶级的“技术工具人”,把单一领域的技术钻研到极致;要么就接受“拉车”这部分工作,学会带人、搭建机制,承担起更综合的职责。
一道面试题:颜色分类
昨晚十一点多,我在公司楼下抽烟,手机“叮”地响了一声。组里的小李发消息问我:“哥,那道‘颜色分类’的题你是怎么写的?我写着写着数组就乱套了…”
我说你别急,我这会儿脑子也困,但这个题其实特别像线上排查时的场景——比如“日志分ERROR、INFO、DEBUG三种级别,先把所有ERROR挪到最前面,再把INFO放中间,剩下的DEBUG自然就在后面”。你们懂吧?看着元素挺乱,其实就固定的三类。
颜色分类问题,数组里只有0、1、2三种数字。当然,你可以直接用排序算法搞定,但那感觉就像为了一个本地函数回调而去部署一套消息中间件(MQ),绕了远路。这道题最经典的解法就是“三指针”,也叫“荷兰国旗问题”(这名字我老记不住)。核心思路就是:左边固定放0,右边固定放2,中间自然就剩下1了。
关键点在于,你别一上来就想着“我从头扫到尾就行”。你得在脑子里先给自己划好地盘,就像值班时给不同级别的告警分区处理一样。
我的思路通常是这样设定的:
[0..low-1] 这个区域保证全是0。
[high+1..end] 这个区域保证全是2。
- 中间
[low..mid-1] 可以先看作是已经整理好的1。
- 然后
mid 就是你当前正在检查的那个“元素”(或者想象成一条待处理的日志)。
你每次只需要看 nums[mid] 的值:
- 看到0:那就把它和
low 指针位置的元素交换,然后 low++,mid++。因为交换到 mid 位置来的那个元素,原本就在“中间区”(已经被检查过),所以不用担心。
- 看到1:啥也别动,
mid++ 继续检查下一个。
- 看到2:把它和
high 指针位置的元素交换,然后 high--。这里要注意,mid 指针先别动!因为你从右边 high 位置换过来的那个数字,你还没检查过呢,它可能是0也可能是2。如果你把 mid 也往后移了,这个新换来的数就被漏掉了——线上很多诡异的bug就是这么产生的,我可见过太多了。
来,我用Java给你写个清晰的版本,你直接参考就行。别整那些花里胡哨的Stream API,在这种题目里越花哨越容易出错:
import java.util.Arrays;
public class ColorSort {
public static void sortColors(int[] nums) {
int low = 0; // 下一个0应该放的位置
int mid = 0; // 当前扫描指针
int high = nums.length - 1; // 下一个2应该放的位置
while (mid <= high) {
int v = nums[mid];
if (v == 0) {
swap(nums, low, mid);
low++;
mid++;
} else if (v == 1) {
mid++;
} else { // v == 2
swap(nums, mid, high);
high--;
// mid 不动,继续检查换过来的值
}
}
}
private static void swap(int[] a, int i, int j) {
if (i == j) return;
int t = a[i];
a[i] = a[j];
a[j] = t;
}
// 随手写个main方法跑一下,省得你们感觉对了但过不了测试用例
public static void main(String[] args) {
int[] nums = {2, 0, 2, 1, 1, 0};
sortColors(nums);
System.out.println(Arrays.toString(nums)); // 输出:[0, 0, 1, 1, 2, 2]
}
}
你看,这个过程就像整理你的工位:low 那边是“必须保持干净的区域”,high 那边是“专门堆放杂物的区域”。你从中间扫过去,遇到垃圾(2)就往右边杂物区扔,遇到重要文件(0)就往左边干净区塞,至于那些普通文件(1),你不用管它,它自然会留在合适的位置。
对了,小李还问我“为啥交换2的时候 mid 不加”。我当时差点笑出声,因为这就像你抓包分析网络流量,一个数据包刚读进来,你还没解析它的内容呢,就把读取指针往后挪了——那不就等着数据错位、解析出问题吗?
行吧,我这边电梯到了,等会儿还得回去看看那个压测曲线怎么又波动了。关于这道LeetCode经典题和它背后的协作思维,就聊这么多。如果你对这类融合了技术实践与职场思考的内容感兴趣,欢迎来云栈社区和更多开发者一起交流探讨。