当前位置:首页>跳槽>大厂P8,跳槽去小厂当副总,薪资涨了 20%,结果3个月后,人没了~

大厂P8,跳槽去小厂当副总,薪资涨了 20%,结果3个月后,人没了~

  • 2026-08-17 10:23:15
大厂P8,跳槽去小厂当副总,薪资涨了 20%,结果3个月后,人没了~

最近圈里有人吐槽:某大厂P8跳去小厂当“副总级”CTO,结果三个月就被“优化”了。

入职时老板全员邮件拍胸口——“技术方向听他的”,听着像给你发了最高权限,实际可能是把锅也一并交接。

网友们也挺损:有人说“欢迎邮件=背锅预告”;有人补刀“期权像未上线的需求,听着很香,交付前先改三版”;还有人总结“从带30人到带情绪”。

我觉得大厂P8去小厂,最怕的不是技术难,是老板今天想做AI、明天想做电商,路线跟产品PRD一样随缘。三个月就走人,多半不是你不行,是公司先把‘未来’删库了。

非递减数列

非递减数列这个事儿啊,我是前两天刚被人半夜电话拎起来问的,语气特别急:“东哥东哥,那个啥,数组是不是只改一个就能变成不下降的,怎么写?”我人都还在床上呢,脑子一片浆糊,只能一边翻身一边想算法。

你先脑补个场景吧,就像考试成绩单那种数组:[4, 2, 3],老师说我只愿意给你改一次分,看能不能把这串分数改成“后面不比前面低”的,那就是所谓“非递减数列”。也就是说得满足 nums[i] <= nums[i+1],全程不能出现下坡,只能持平或者上坡。

一开始我也想过那种比较蠢的办法:暴力枚举,每个位置都试着改一改,看最后是不是非递减。想想就知道完蛋,面试官当场给你请出门口那种,时间复杂度直接炸。后来清醒一点,拿纸随便写了几个例子,我念给你听:

  • [4, 2, 3] 这种,改一个 4 变成 2 或者改 2 变成 4,都能搞定,答案 true。
  • [3, 4, 2, 3] 就有点恶心了,你无论改哪个,都会还有一个地方是下坡,所以要 false。

关键点就一个:你从左往右扫数组,找到“下坡”的地方,也就是 nums[i] < nums[i-1] 的位置,看这种情况出现几次。如果多于一次,铁定就不行了,只能改一个嘛。

但是只数次数还不够,难点在于:出现这一次下坡的时候,你到底是“怪前面”还是“怪后面”?也就是你究竟改 nums[i-1] 还是改 nums[i]

那天我在工位上给同事讲,直接在 IDEA 里敲了个最小版的 Java 写法,大概长这样:

publicbooleancheckPossibility(int[] nums){int changed = 0// 记录你动手改的次数for (int i = 1; i < nums.length; i++) {if (nums[i] < nums[i - 1]) { // 出现“下坡”            changed++;if (changed > 1) {returnfalse// 下坡超过一次,直接GG            }if (i - 2 >= 0 && nums[i] < nums[i - 2]) {// 说明当前这个太小,拉它上去                nums[i] = nums[i - 1];            } else {// 否则就把前面的压下来                nums[i - 1] = nums[i];            }        }    }returntrue;}

你感受一下这个 if 里那段分支,其实就是人脑在纠结:“这锅到底谁背”。举个更具体的:

  • 比如 [3, 4, 2, 3],当你走到 i = 2 这一位,也就是数值 2,发现 2 < 4,这里有个“下坡”。 这时候再往前看一眼 nums[i-2] 是 3。 如果你把 4 改小,改成 2,那数组变 [3, 2, 2, 3],前面又变成了 3 > 2,前面直接崩掉。 所以这里就得让 2 抬起来,抬到和 4 一样大,改成 [3, 4, 4, 3]。虽然后面还有问题,但至少不会让前面的历史更糟。

  • 换个例子 [4, 2, 3],当你走到 i = 1 的时候,前面没有 i-2 了,那就简单粗暴,把前面的 4 改成 2 就好了,变成 [2, 2, 3],一切和谐。

所以那句判断:

if (i - 2 >= 0 && nums[i] < nums[i - 2]) {    nums[i] = nums[i - 1];else {    nums[i - 1] = nums[i];}

背后小心思是这样的: 如果当前这个数 nums[i] 小到连再往前一个 nums[i-2] 都顶不住,那说明“现在的人问题大”,只好把它拉高; 否则就说明“前任太高调”,把 nums[i-1] 拉低一点,和当前对齐就行。

我当时还顺手写了个小 main 跑一跑,免得嘴上说的都对,代码一跑寄了:

publicstaticvoidmain(String[] args){int[][] tests = {        {423},        {3423},        {1233},        {5718}    };    NonDecreasingArray s = new NonDecreasingArray();for (int[] arr : tests) {        System.out.println(Arrays.toString(arr) + " -> " + s.checkPossibility(arr.clone()));    }}

打印出来大概就是这种感觉:

  • [4, 2, 3] -> true
  • [3, 4, 2, 3] -> false
  • [1, 2, 3, 3] -> true
  • [5, 7, 1, 8] -> true (把 7 改成 1 就行)

这里有个小细节,注意我调用的时候用了 arr.clone(),因为算法里是会真的修改数组的。在面试里如果不 clone,考官可能还会问你一句“为啥要改原数组”,你就又得扯一堆“节省空间”“O(1) 额外空间”这种官方话术。这个和数据库那些默认配置不改就翻车的感觉很像,你以为“反正能跑”,结果线上一压测直接跪⌄⌄⌄

这题整体复杂度挺亲民的,就是单次 for 循环,时间 O(n),空间上只用几个临时变量,算是那种写着写着很顺手的题,比我当年选 MySQL 还是 Postgres 纠结半天要幸福多了。

顺带提醒一句,写这种一遍扫描的题,日志别乱打,我之前排查 TCP 那个 1024 卡包的坑,一堆打印害得我眼睛都花了,看半天才发现问题其实就卡在一个字节上,你数组越界、索引写错一个,一样能给你搞出玄学 bug。

反正这个非递减数列你要是能把“只允许一次犯错,然后聪明地补救”这个思路吃透,后面遇到那种“最多改 K 次”的、或者“删掉一个数让它变好看”的题,脑子里套路都是一样的。行了,我先去喝口水,眼睛有点花,剩下的你自己多敲两遍代码就记住了。

最新文章

随机文章