程序员老鬼

一句话,一年多了12k,很多人在薪资谈判上吃亏,不是因为能力不够,是因为不敢开口。

刚刷到这个,真有点替人肉疼。

面试谈薪那一下,很多人其实不是输在能力上,是自己先怂了。HR说预算到25k,你一听就点头,后面一年每个月少三千,想想都血压上来。

Image

这事最关键的地方就在那句“能不能再帮我确认一下空间”。不吵不闹,也不是硬刚,就正常把自己的预期摆出来。结果人家去跟leader聊一圈,钱还真有。

所以别把HR第一次报的数当圣旨。公司当然想控成本,这没毛病,但你也得替自己说句话。尤其是手里有别的机会,或者你觉得自己值这个价,就大大方方讲。

打工人最怕的就是,活干得挺硬,谈钱的时候声音小得像欠人家一样。薪资这东西,你不开口,没人主动给你加满。多少人差的不是水平,是那一下没敢问。

今日面试题

这题第一眼别急着写排序,先看清楚它到底要什么:统计各专业学生人数。

只要题目没要求按人数排名,也没要求按专业字典序输出,那就别给自己加戏。统计类题目,我一般先盯两个东西:一个是“分类字段”,一个是“计数容器”。这道题里的分类字段就是专业,计数容器用 Map 就够了。

输入大概可以抽象成这样:

5
张三 计算机
李四 软件工程
王五 计算机
赵六 自动化
钱七 软件工程

要输出的不是每个学生的信息,而是每个专业出现了几次:

计算机 2
软件工程 2
自动化 1

这里我不建议一上来用数组硬扛。专业名称不是固定数字编号,用数组就得先做映射,绕了一圈最后还是回到 Map。写题的时候,绕远路不加分。

Java 代码可以这样写:

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;

publicclassMain{

publicstaticvoidmain(String[] args){
        Scanner in = new Scanner(System.in);

int n = in.nextInt();

        Map<String, Integer> majorCount = new LinkedHashMap<>();

for (int i = 0; i < n; i++) {
            String studentName = in.next();
            String major = in.next();

int oldCount = majorCount.getOrDefault(major, 0);
            majorCount.put(major, oldCount + 1);
        }

for (Map.Entry<String, Integer> item : majorCount.entrySet()) {
            System.out.println(item.getKey() + " " + item.getValue());
        }
    }
}

这里有个小细节,我用了 LinkedHashMap,不是普通的 HashMap。

HashMap 当然也能统计,但它不保证输出顺序。你本地跑出来可能是计算机、自动化、软件工程,到了评测机上顺序可能变了。很多题虽然没明说,但样例一般按首次出现顺序输出,这种时候用 LinkedHashMap 更稳一点。

核心代码其实就这一句:

majorCount.put(major, majorCount.getOrDefault(major, 0) + 1);

它干了两件事。

第一次遇到某个专业,比如“计算机”,原来没有记录,就按 0 处理,然后加 1。

后面再遇到“计算机”,取出原来的次数,再加 1。

这就是统计题最常见的写法,比你写一堆 if else 干净。

有些同学会这么写:

if (majorCount.containsKey(major)) {
    majorCount.put(major, majorCount.get(major) + 1);
} else {
    majorCount.put(major, 1);
}

这也没错,就是啰嗦。比赛或者笔试里,代码越长,越容易手滑。尤其是这种题,本来就不该复杂。

这道题的时间复杂度是 O(n),每个学生只处理一次。空间复杂度是 O(k),k 是专业数量。学生再多,只要专业种类没那么多,Map 里存的东西也不会太夸张。

如果题目要求按专业名称排序,把 LinkedHashMap 换成 TreeMap 就行:

Map<String, Integer> majorCount = new TreeMap<>();

如果题目要求按人数从多到少输出,那就得把 entrySet 拿出来排序。没这个要求就别排,排序是额外复杂度,也容易把简单题写炸。

这类题没什么玄学,别想复杂。读一条,取专业,Map 里加一次。最后遍历输出。真正容易丢分的地方,反而是输出顺序和输入字段读错。