程序员老鬼

48岁老程序员被大厂裁员,存款~万,社保也交够20年了,回县城吃利息等60岁领退休金

48岁,被大厂一脚“优化”回家,结果网友一看:存款800万,社保交满20年,回县城吃利息,等60岁领退休金。评论区先酸了,这哪叫裁员,这叫提前下班。

Image

我看这事,扎心就扎心在对比。普通人听到“被裁员”三个字,脑子里是房贷、孩子学费、下个月社保。到他这儿,变成了县城养老剧本,连BGM都轻松了。大厂这行就是这样,年轻时拿命换钱,真换到了,撤得比谁都快;没换到的,才是真的悬。

所以网友一边吐槽,一边又有点羡慕。嘴上说“太惨了”,心里想的估计是:这种裁员,什么时候轮到我。

面试题:删除注释

代码跑得好好的,一提交就挂,很多时候不是算法没想明白,是字符串处理写得太想当然。

“删除注释”这题就有点这个味道。看题面像体力活:扫一遍代码,把 // 和 /* ... */ 干掉就完了。真写起来,最容易翻车的地方不是删,而是状态切换。尤其是块注释跨行的时候,上一行没收干净,下一行还得接着吞,脑子里如果没有这个状态,代码八成写乱。

这题我一般不搞花活,老老实实按字符扫,外面挂一个 inBlock 表示当前是不是在块注释里。 不在块注释里时,只看三种情况:

  1. 遇到 //,这一行后面直接不要了。
  2. 遇到 /*,进入块注释状态。
  3. 其他字符,正常塞进当前行缓冲区。

在块注释里就更简单,盯着 */,看见了再出来,别的都跳过。

Java 代码我会写成这样,短一点,逻辑也不绕:

classSolution{
public List<String> removeComments(String[] source){
        List<String> ans = new ArrayList<>();
boolean inBlock = false;
        StringBuilder line = new StringBuilder();

for (String s : source) {
if (!inBlock) {
                line.setLength(0);
            }

for (int i = 0; i < s.length(); i++) {
if (inBlock) {
if (i + 1 < s.length() && s.charAt(i) == '*' && s.charAt(i + 1) == '/') {
                        inBlock = false;
                        i++;
                    }
                } else {
if (i + 1 < s.length() && s.charAt(i) == '/' && s.charAt(i + 1) == '/') {
break;
                    } elseif (i + 1 < s.length() && s.charAt(i) == '/' && s.charAt(i + 1) == '*') {
                        inBlock = true;
                        i++;
                    } else {
                        line.append(s.charAt(i));
                    }
                }
            }

if (!inBlock && line.length() > 0) {
                ans.add(line.toString());
            }
        }
return ans;
    }
}

这题有两个细节很容易漏。

一个是块注释可能把多行拼成一行。比如第一行注释前有内容,后面几行都是块注释,最后一行注释结束后还有内容,那这些内容其实要拼到同一个 StringBuilder 里,所以只有在“不处于块注释”并且一整行处理完之后,才决定要不要塞进结果集。

另一个是空行别乱加。注释删完如果这一行啥也不剩,别硬塞个空串进去,不然结果就脏了。

这题时间复杂度没什么悬念,就是把所有字符扫一遍,O(n)。难点纯粹在细节,尤其是 i + 1 越界、状态切换和跨行拼接。面试里这种题不算难,但特别适合看代码基本功。写得顺的人,状态会很稳;写得乱的人,通常会在 if-else 里绕半天,最后自己都不敢测。