破防!十面字节仍被挂,新称号“挂面” ,一直面,一直挂…
刚看到个贴子,说有同学秋招连着冲了字节四个岗位、十次面试,结果还在原地踏步,网友们都给他整出个外号“挂面”,一直面一直挂,属实有点破防。
我觉得人家能坚持十次已经是强心脏了。
从我的角度看,连续被挂不一定说明能力不行,更多时候是节奏、岗位需求、团队优先级这些因素乱七八糟地叠一起,就像排队买奶茶,前面的人突然全点大杯加料,你就只能干等着,并不代表你点单不行。
不过话说回来,这位同学的坚持确实值得夸。十次还敢继续冲,说实话已经比不少朋友强太多了。秋招这种东西,有时候拼的就是厚脸皮和续航力。
总的来说吧,别被一次次挂心态打崩,机会有时候拐个弯就来了。【备注:文末可领最新资料】
面试题:验证IP地址
我先直接上结论:验证 IP 地址这种题,本质就是字符串分类 + 规则校验,别被“网络”“协议”这些词吓到,其实就是拆字符串、看格式。
你想象一下,后端有个接口,前端传一个白名单 IP,上来就直接塞数据库里,结果有同事手一抖传了个 999.999.999.999,或者传个 "abcd",你再拿这些去做防火墙配置、限流规则,基本等于白忙活。
所以通常我们会写一个 validIPAddress(String queryIP),返回:
"IPv4""IPv6""Neither"
然后在业务里根据结果决定要不要接受这条配置。
不用背标准,只要记住常见的那版(跟面试/刷题常见版本对齐):
IPv4:
形如: x.x.x.x一共 4 段,每段都要是十进制数字 每段范围 0 ~ 255不能有前导零(除了单独一个 "0"),比如01、001都是不合法的不能有空段: 1..1.1这种拆出来有空串,直接判错
IPv6:
形如: x:x:x:x:x:x:x:x一共 8 段,每段 1~4 个字符 字符只能是十六进制: 0-9、a-f、A-F可以有前导零,比如 0001是 OK 的为了简单(也跟很多题目一致),不支持压缩写法:像 ::1、2001:db8::1都当成非法
逻辑就变成一句话:先看是点多还是冒号多,猜它想当 IPv4 还是 IPv6,然后按相应规则“挑刺”,一旦有一条不符合就判死刑。
Java 实现:一眼能看懂的那种
直接给一个完整的类,你可以丢到 LeetCode 468 那题里跑:
publicclassIPAddressValidator{
public String validIPAddress(String queryIP){
if (queryIP == null || queryIP.isEmpty()) {
return"Neither";
}
if (queryIP.indexOf('.') >= 0 && queryIP.indexOf(':') == -1) {
return isIPv4(queryIP) ? "IPv4" : "Neither";
}
if (queryIP.indexOf(':') >= 0 && queryIP.indexOf('.') == -1) {
return isIPv6(queryIP) ? "IPv6" : "Neither";
}
return"Neither";
}
privatebooleanisIPv4(String ip){
// 注意:split 的参数是正则,“.” 要转义,而且要用 limit=-1 保留空段
String[] parts = ip.split("\\.", -1);
if (parts.length != 4) {
returnfalse;
}
for (String part : parts) {
// 不能为空
if (part.length() == 0) {
returnfalse;
}
// 长度不能超过 3
if (part.length() > 3) {
returnfalse;
}
// 不能有前导零,除非就是 "0"
if (part.length() > 1 && part.charAt(0) == '0') {
returnfalse;
}
// 必须全是数字
int num = 0;
for (int i = 0; i < part.length(); i++) {
char c = part.charAt(i);
if (c < '0' || c > '9') {
returnfalse;
}
num = num * 10 + (c - '0');
}
// 范围 0~255
if (num < 0 || num > 255) {
returnfalse;
}
}
returntrue;
}
privatebooleanisIPv6(String ip){
String[] parts = ip.split(":", -1);
if (parts.length != 8) {
returnfalse;
}
for (String part : parts) {
// 每一段 1~4 个字符
int len = part.length();
if (len < 1 || len > 4) {
returnfalse;
}
for (int i = 0; i < len; i++) {
char c = part.charAt(i);
boolean isDigit = c >= '0' && c <= '9';
boolean isLowerHex = c >= 'a' && c <= 'f';
boolean isUpperHex = c >= 'A' && c <= 'F';
if (!isDigit && !isLowerHex && !isUpperHex) {
returnfalse;
}
}
}
returntrue;
}
// 小 main,自己本地玩一玩
publicstaticvoidmain(String[] args){
IPAddressValidator v = new IPAddressValidator();
System.out.println(v.validIPAddress("172.16.254.1")); // IPv4
System.out.println(v.validIPAddress("2001:0db8:85a3:0:0:8A2E:0370:7334")); // IPv6
System.out.println(v.validIPAddress("256.256.256.256")); // Neither
System.out.println(v.validIPAddress("1e1.4.5.6")); // Neither
}
}
这个题看着简单,其实面试里很多人会栽在细节里:
String.split的坑:ip.split(".")是错的,因为.在正则里代表“任意字符”。必须写成"\\."。 还有就是默认split会丢掉末尾的空串,比如"1.1.1."用默认split("\\.")出来只有 3 段,你以为长度对了,其实不对。所以加上-1这个 limit,告诉它“空的也给我保留”。前导零:
0合法,00、01都不行,这个很多人一开始没注意。IPv6 压缩写法: 如果你是刷题,就按题目的简单版本来,直接
8段死判。 真要做线上工具,再去支持::这种压缩,那就是另一个难度了。
整体思路就是:不要试图用一个正则一口气把 IPv4、IPv6 全搞定,分两种情况慢慢检查,逻辑清楚、好调试,线上出了问题也方便打日志定位。你先把这版写熟,后面再想扩展别的花活也不迟。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html