程序员老鬼

骑车撞到某为员工,对方三天误工费要7500。。

看到一个吐槽,有网友说他骑车不小心撞到了一位某为的员工,结果对方说三天误工费要7500块。

Image

7500?!三天?!我当时脑子都没转过来,还以为自己看错了,赶紧往下看,结果对方真的掏出了工资流水。。

我当时就坐直了。说实话,我干程序员十来年了,也算是混过几个互联网公司,自认不算最底层的那种打工人,但看到这数字我还是沉默了三秒钟……

居然在赔偿金额面前感到一种“羡慕”?这不是讽刺是啥?

更离谱的是,底下评论区一堆人说:“这不是误工,是发财机会。”我不禁开始怀疑人生,我这边写需求写到半夜两点,那边误工三天顶我俩月工资……

唉,说多了都是泪。还是早点回去写代码吧,万一哪天我也能靠误工发财呢?【备注:文末可领最新资料】

算法题:部门工资最高的员工

这个题其实你一眼看过去会觉得没啥技术含量嘛,就一个“找每个部门工资最高的员工”,说白了就是个分组+排序+筛选的操作。但实际你要在面试里写出一个写得好、效率高、还能让面试官满意的SQL(或者代码逻辑),没那么简单,真有点门道在里面 🤔。

说个背景,我当年在一个金融数据项目里,就遇到类似的需求——要找出每个基金经理手下业绩最好的基金组合。那个场景一模一样,按人分组,找最大值,然后把对应记录拉出来。我们当时用的是Java配MySQL,SQL是后端写的,业务逻辑里还要再兜一层来“兜底”数据不一致的问题,真的是处理得头都大。

回到正题,我们来看一下这道题,官方的解法是给你一个Employee表,字段是 id, name, salary, departmentId,然后Department表是 id, name。任务是找出每个部门工资最高的员工。

最直接的思路是,先找出每个部门的最高工资,然后再从Employee表里挑出这些工资的人。这个逻辑翻译成SQL是这样的:

SELECT d.name AS Department, e.name AS Employee, e.salary AS Salary
FROM Employee e
JOIN (
SELECT departmentId, MAX(salary) AS maxSalary
FROM Employee
GROUPBY departmentId
) m ON e.departmentId = m.departmentId AND e.salary = m.maxSalary
JOIN Department d ON e.departmentId = d.id;

看起来挺优雅的对吧?但你要是面试官,他可能会问你——你觉得这个性能好吗?适合大数据量吗?👀

说实话,这个方案在百万级数据下还是能跑的,但别太指望它能scale到十亿级。为什么?第一,这个 MAX + GROUP BY 是全表扫描分组;第二,你再回头联一次Employee表,是一个小规模的回表;第三,加上Department只是为了名字,没啥性能压力。

不过,如果你用Java代码来处理,其实也能搞,但代码可比SQL啰嗦多了。你要先按departmentId分组,然后再找最大值,然后再输出对应字段。用Java 8 Stream可以写得稍微好看点:

Map<Integer, Optional<Employee>> topSalaries = employees.stream()
    .collect(Collectors.groupingBy(
        Employee::getDepartmentId,
        Collectors.maxBy(Comparator.comparing(Employee::getSalary))
    ));

当然了,这个写法在生产上你要看清楚:Optional不一定有值,而且你得兜好空值、脏数据的情况。

我还见过一种“奇技淫巧”的写法,是用窗口函数来搞。前提是数据库支持,比如PostgreSQL、SQL Server、甚至新版的MySQL:

SELECT Department, Employee, Salary
FROM (
SELECT d.name AS Department, e.name AS Employee, e.salary AS Salary,
RANK() OVER (PARTITIONBY e.departmentId ORDERBY e.salary DESC) as rnk
FROM Employee e
JOIN Department d ON e.departmentId = d.id
) tmp
WHERE rnk = 1;

这个的好处是不用回表、结构更清晰,但坏处是你得数据库支持窗口函数,而且要注意RANK和DENSE_RANK的区别——万一有并列第一的员工,是不是都要显示出来?

顺带一提,我当时在某个厂的SQL测试题里还真被卡过这个问题,他们在数据里偷偷放了一个“两个员工工资一样高”的情况,看你是不是写了LIMIT 1或者用了ROW_NUMBER导致只返回了一个。细节决定生死啊!

最后,如果你真的遇到这个题的Java版本实现,不要上来就暴力嵌套for循环查最大值,那是写给自己挖坑的做法。正确做法还是分组Map<Integer, List>,然后再对每个List求max,代码清晰还能说服面试官你不是在胡写 👍。

顺嘴问一句——你们组的“工资最高”是按哪个表算的?产品那边是不是又想改需求了 😂

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

-END-

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