面了个要28K的候选人,简历写精通Linux/Shell。 我让他现场写个命令:乡统计Nginx日志里访问量Top10的IP。他憋了半天,写了个cat
刚看到个贴子,说有公司面了个开口就要28K的候选人,简历上写着“精通Linux/Shell”。面试官随手让他现场写个命令,统计一下Nginx日志里访问量Top10的IP,结果这哥们憋半天,只敲出一个cat,awk不会,sort不会,uniq也不会,现场直接尴尬静音。
我觉得这事关键不在28K,也不在题难不难,而是在“精通”这俩字上。要价高可以,只要你真有货;但要是平时就只会敲几句常用命令,还非要在简历上写“精通”,那不叫自信,叫给自己挖坑。
换个角度讲,面试官出这类题也正常,毕竟公司是花钱买能力的,不是买PPT上的形容词。与其在简历上堆“精通”“专家”,不如老老实实打好基本功。
面试题:整数转罗马数字
昨天晚上十一点多,我在公司楼下等外卖,正刷手机呢,我们组那个小李突然发语音过来:
“东哥东哥,那个……整数转罗马数字你会不,会的话赶紧救救我,明天面试要考的那种,语言用 Java 的……”
我一看这玩意儿,典型面试常客嘛,不过确实,第一次写的时候很多人都会写得乱七八糟。
简单记几个符号就行,不要死背表:
I = 1 V = 5 X = 10 L = 50 C = 100 D = 500 M = 1000
有两个“怪脾气”的规则,一定得记清:
4 不是
IIII,而是IV(小在左边表示减)9 不是
VIIII,而是IX同理:
40 = XL 90 = XC 400 = CD 900 = CM
一般面试题默认输入范围是 1 ~ 3999,超过的先别管,老老实实写好这一段就行。
当时我就跟小李说:你别想着写一坨 if-else:
if (num >= 1000) ...
elseif (num >= 900) ...
...
这种最后自己都看不下去。
更舒服一点的写法,是把“值”和“符号”配成两行数组,从大到小,一个个往下减,属于典型贪心思路:
每次能用最大的符号就一直用它,用完再换小一点的。
比如 1994:
先用 1000 -> M,剩下 994 能用 900 -> CM,剩下 94 能用 90 -> XC,剩下 4 能用 4 -> IV,结束,拼出来就是 MCMXCIV
这个套路跟线上拆包、拆任务其实一个味道:一段一段往下啃。
我当时就把这段丢给小李,你可以直接照着写、再自己敲几遍记下手感:
publicclassIntToRoman{
// 从大到小排好,包含那些“特殊值”:900、400、90、40、9、4
privatestaticfinalint[] VALUES = {
1000, 900, 500, 400,
100, 90, 50, 40,
10, 9, 5, 4, 1
};
privatestaticfinal String[] SYMBOLS = {
"M", "CM", "D", "CD",
"C", "XC", "L", "XL",
"X", "IX", "V", "IV", "I"
};
/**
* 把 1~3999 的整数转成罗马数字
*/
public String intToRoman(int num){
StringBuilder sb = new StringBuilder();
// 一路从大到小贪心
for (int i = 0; i < VALUES.length && num > 0; i++) {
int value = VALUES[i];
String symbol = SYMBOLS[i];
// 能减多少次就减多少次
while (num >= value) {
num -= value;
sb.append(symbol);
}
}
return sb.toString();
}
// 随便写个 main 自测一下
publicstaticvoidmain(String[] args){
IntToRoman solution = new IntToRoman();
System.out.println(solution.intToRoman(3)); // III
System.out.println(solution.intToRoman(4)); // IV
System.out.println(solution.intToRoman(9)); // IX
System.out.println(solution.intToRoman(58)); // LVIII
System.out.println(solution.intToRoman(1994)); // MCMXCIV
}
}
这个实现几个点你心里有数就行:
时间复杂度其实算 O(1):因为 VALUES长度是固定的 13,最多 while 里循环几次而已不用管“连续最多三个 I、X、C、M 之类”的规则,因为我们数组本身就是按规范设计的,不会生成非法串 StringBuilder一定要用,别在循环里无脑+拼字符串,面试官会叹气的
行,我这会儿也困得不行了,就先写到这。你把这段 Java 多敲几遍,关掉编辑器,自己默写一遍思路:
“从大到小枚举所有合法数值,能减就减,减完拼字符串”
能把这句话说顺溜,这题基本就拿下了。剩下的,你就自己开 IDE 玩去,我先去冲杯咖啡再干活了。