找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4673

积分

0

好友

608

主题
发表于 1 小时前 | 查看: 2| 回复: 0

这面试官是不是有点上头了。

面试了一位某为出来的员工,一道 LeetCode 中等题,归并排序 没写出来,然后直接一句“拜拜吧”。乍一看挺爽,像是技术面试铁面无私,其实细想挺尴尬的。

归并排序会不会,当然能看点基本功。但拿一道题直接判死刑,也挺粗暴。人家在公司里到底干啥,是写业务、搞架构、扛线上、还是天天被需求追着跑,这些完全没看出来。结果就因为现场没憋出代码,整个人被打成“某为员工也不过如此”。

更好笑的是,很多面试到最后都变成背题大赛。平时写代码靠脑子、靠经验、靠排查问题,现场倒计时手写排序,写不出来就像犯了大错。

当然,基础太差肯定不行。但只靠一道题判断一个人行不行,HR看了都得沉默一下。面试不是抽卡鉴定血统啊。

今日面试题

员工薪水这题,第一眼别急着写循环累加。 我见过不少人上来就按月份扫一遍,结果一碰到“只统计最近 3 个月”“还要排除最新月份”,代码马上拧成一团。

题目大概是这个意思:给一批员工月薪记录,每条记录有员工 id、月份 month、薪水 salary。要查每个员工每个月的累计薪水,累计范围是当前月往前最多 3 个月。还有一个坑:每个员工最新的那个月不参与输出。

比如某员工有这些数据:

id=1, month=1, salary=20
id=1, month=2, salary=30
id=1, month=3, salary=40
id=1, month=4, salary=60

那 month=4 是最新月份,不输出。

month=3 的累计薪水就是:

month 1 + month 2 + month 3 = 90

month=2 是:

month 1 + month 2 = 50

month=1 是:

20

这题真正要注意的不是累加,而是顺序。

我一般会先按员工分组,每个员工内部再按月份排序。然后用一个滑动窗口维护最近 3 个月的薪水。窗口里超过 3 条,就把最早那条踢出去。

Java 实现起来大概是这样的:

import java.util.*;

public class EmployeeSalaryQuery {

    static class SalaryRow {
        int id;
        int month;
        int salary;

        SalaryRow(int id, int month, int salary) {
            this.id = id;
            this.month = month;
            this.salary = salary;
        }
    }

    static class SalaryResult {
        int id;
        int month;
        int totalSalary;

        SalaryResult(int id, int month, int totalSalary) {
            this.id = id;
            this.month = month;
            this.totalSalary = totalSalary;
        }

        @Override
        public String toString() {
            return "id=" + id + ", month=" + month + ", totalSalary=" + totalSalary;
        }
    }

    public static List<SalaryResult> queryCumulativeSalary(List<SalaryRow> rows) {
        Map<Integer, List<SalaryRow>> group = new HashMap<>();

        for (SalaryRow row : rows) {
            group.computeIfAbsent(row.id, k -> new ArrayList<>()).add(row);
        }

        List<SalaryResult> ans = new ArrayList<>();

        for (Map.Entry<Integer, List<SalaryRow>> entry : group.entrySet()) {
            List<SalaryRow> list = entry.getValue();

            list.sort(Comparator.comparingInt(a -> a.month));

            int latestMonth = list.get(list.size() - 1).month;

            Deque<SalaryRow> window = new ArrayDeque<>();
            int sum = 0;

            for (SalaryRow row : list) {
                window.addLast(row);
                sum += row.salary;

                while (window.size() > 3) {
                    SalaryRow removed = window.removeFirst();
                    sum -= removed.salary;
                }

                if (row.month != latestMonth) {
                    ans.add(new SalaryResult(row.id, row.month, sum));
                }
            }
        }

        ans.sort((a, b) -> {
            if (a.id != b.id) {
                return a.id - b.id;
            }
            return b.month - a.month;
        });

        return ans;
    }

    public static void main(String[] args) {
        List<SalaryRow> rows = Arrays.asList(
                new SalaryRow(1, 1, 20),
                new SalaryRow(1, 2, 30),
                new SalaryRow(1, 3, 40),
                new SalaryRow(1, 4, 60),
                new SalaryRow(2, 1, 50),
                new SalaryRow(2, 2, 60)
        );

        List<SalaryResult> result = queryCumulativeSalary(rows);

        for (SalaryResult item : result) {
            System.out.println(item);
        }
    }
}

输出大概是:

id=1, month=3, totalSalary=90
id=1, month=2, totalSalary=50
id=1, month=1, totalSalary=20
id=2, month=1, totalSalary=50

这里有个细节,别忽略。

如果一个员工只有两个月数据,最新月份也要排除,所以只能输出老的那个月。如果只有一个月数据,那这个员工就没有结果。很多人样例能过,边界用例就挂在这里。

这题也可以暴力做:每个员工每个月都往前找 3 个月,然后相加。数据少的时候没问题,但这种写法有点不干净。

滑动窗口更像线上处理日志、账单、月度统计那种写法。数据来了,按时间排好,窗口往前滚,该进的进,该出的出。逻辑短,也不容易把月份条件写乱。

这题最后排序也要看清楚,一般要求按员工 id 升序,员工内部按月份降序。这个地方不影响累计结果,但会影响提交答案。很多错不是算法错,是输出顺序错。




上一篇:做项目经理,这4种性格缺陷不改,早晚要吃大亏
下一篇:Autoresearch:让 Claude Code 和 Codex 挂一晚自动迭代改代码
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-8-12 21:10 , Processed in 1.377989 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表