程序员老鬼

老板宣布全员降薪 20%共渡难关,结果大家纷纷摸鱼,工作效率下降不止 20%。。

昨天群里有人转了条帖子,说一个公司老板宣布全员降薪 20%,还说要“共渡难关”。

结果呢,员工听完一句话不说,转头就开始疯狂摸鱼,工作效率直接跳水,老板眼看不对劲儿,急了,马上要求从第二天开始写日报——是那种每半个小时干了啥都要写清楚的那种。我看到那条消息的时候,整个人当场裂开😅。

Image

你说这是员工不讲职业道德吗?我觉得吧,也别只怪员工,人家出卖时间和技能,结果工资打了折,那付出的心气也自然就没了。更何况,现在大家不傻,给多少钱干多少事嘛!

而且写日报这事儿吧,我干程序员十几年了,真心劝老板们别干这种事。日报写多了,干活的时间真就没了,全员把精力花在“写我好努力”上,活反倒没人真干。

说句不好听的,老板其实也就是想“用制度稳住局面”,但真想稳局面,不如发红包。【备注:文末可领最新资料】

算法题:第十行

有时候吧,面试的时候你碰上一道看起来特简单的算法题,结果它藏着一堆“坑”,不踩一脚你都不知道Java还能这么玩。比如说这题:

给定一个字符串 s,请你找出其中不含有重复字符的最长子串的长度。

刚看到的时候你可能一拍脑袋:“哦,这题我高中就做过”,暴力枚举呗,从每个字符开始,一个个往后扫,遇到重复就停,再试下一个起点。但说实话,要真是这么写,估计你简历上的“熟练掌握Java”都得打个折扣。

为啥?因为暴力法在这题里是典型的“能跑但不能看”的解法。复杂度是 O(n²),数据一多直接卡成ppt。想写得漂亮点,还得靠滑动窗口来搞。

这题的精髓就在滑动窗口 + 哈希结构。核心思想其实就一句话:“只要保证窗口里没有重复的字符,我们就可以一直滑动右指针”。

上代码👇:

publicintlengthOfLongestSubstring(String s){
    Set<Character> set = new HashSet<>();
int left = 0, right = 0, maxLen = 0;
while (right < s.length()) {
char ch = s.charAt(right);
if (!set.contains(ch)) {
            set.add(ch);
            maxLen = Math.max(maxLen, right - left + 1);
            right++;
        } else {
            set.remove(s.charAt(left));
            left++;
        }
    }
return maxLen;
}

这个代码的运行轨迹就像你深夜debug项目查内存泄漏——一边往前冲,一边小心翼翼维护窗口内的“纯洁性”。left 指针相当于“清道夫”,遇到重复字符了,就把左边那个挪出去,直到恢复无重复状态。

为啥这题特别喜欢出?一方面滑动窗口是很多实际场景里(比如日志流分析、网络流控制)常用的套路,另一方面,它能测试你对Java集合的熟练程度,比如你是不是下意识就选了 HashSet,又比如你能不能合理维护双指针。

有意思的是,有些面试官会在你写完这题之后问一句:“如果我要求把最长子串本身输出出来呢?”

嗯... 就得稍微变一下逻辑,加个位置记录:

public String longestSubstring(String s){
    Set<Character> set = new HashSet<>();
int left = 0, right = 0, maxLen = 0, start = 0;
while (right < s.length()) {
char ch = s.charAt(right);
if (!set.contains(ch)) {
            set.add(ch);
if (right - left + 1 > maxLen) {
                maxLen = right - left + 1;
                start = left;
            }
            right++;
        } else {
            set.remove(s.charAt(left));
            left++;
        }
    }
return s.substring(start, start + maxLen);
}

输出子串听起来像个小改动,其实是验证你能不能动态维护状态的关键能力点。很多人代码能力还行,但维护状态的时候就容易写炸——变量改来改去最后发现输出的是“最长重复子串”……

哦对了,还有个很常见的“面向面试优化”的错误写法,很多初学者会这么写:

for (int i = 0; i < s.length(); i++) {
for (int j = i; j < s.length(); j++) {
if (!checkDuplicate(s.substring(i, j + 1))) {
            maxLen = Math.max(maxLen, j - i + 1);
        }
    }
}

这个逻辑倒是没毛病,但 s.substring(i, j + 1) 是新对象,每次都 new,新建字符串又调函数,每次还得从头扫一遍,运行时内存飞涨…这样的写法如果进了线上环境,分分钟给你整个GC频率飙升。

所以老实说,现在面试这种基础题,写得快不是重点,思路清晰、空间时间权衡到位、代码风格干净才是亮点。有时候,判断一个候选人能不能胜任,其实就是看他在细节处能不能写出“稳”的代码,而不是玩花活。

最后,我为大家打造了一份deepseek的入门到精通教程,完全免费:https://www.songshuhezi.com/deepseek

-END-

最后给大家分享一份不错的副业资料,感兴趣的同学可以链接我,微信:hls404 找我领取。