程序员老鬼

如果月入15000的工资,早9晚6,周末双休每天闲的发霉,没人和你说话,一直不开心还要坚持下去吗?

月入15000,早9晚6,双休,活少得能数天花板裂缝,结果人先抑郁了。这事看着像“别人梦中情岗”,真坐进去才知道,班不是累死人的,班是闷死人的。

Image

评论区有人说,这不就是带薪养老,忍忍得了。还有人说,工作不就是拿钱换时间,别太矫情。话是这么说,可人一天八九个小时像被塞进保鲜盒,没人搭理,没事可干,连吐槽对象都没有,时间久了脑子真会发木。那种空,不比加班轻松多少。

钱当然重要,15000也不是风刮来的。但要是天天上班像去坐牢,回家还缓不过来,那就不是“清闲”了,表面稳定,实际消耗你。真让我选,我可以忙点累点,但别把人晾成办公室盆栽,HR看完估计都得装没看见。

面试题:IP 到 CIDR

IP 到 CIDR 这题,乍一看像字符串处理,真写起来,很多人会死在“每次到底该切多大网段”上。 尤其是把 255.0.0.7 这种地址往后覆盖 n 个 IP 时,脑子里一边想着二进制对齐,一边还得防止网段切大了把不该吃进去的地址也包了。这个地方我第一眼就不太信那种“先转一转再试一试”的写法,线上代码这么搞,八成后面自己都不敢改。参考你给我的几篇技术文,那种从现象直接落到判断、代码只贴关键几行的路子更适合这题。

这题核心就两步:

先把 IP 转成一个 32 位整数,后面所有判断都别再碰字符串。 然后每次取一个既满足起始地址对齐,又不超过剩余 n 的最大 CIDR 块。

举个现场感强一点的例子。 假设当前 IP 对应的整数是 x,如果它二进制末尾有 3 个 0,那说明它天然可以对齐到 2^3=8 个地址的块。 但这不代表你就一定能取 /29,还得看 n 剩多少。要是只剩 5 个,那你最多只能取 4 个。

所以每轮其实就是取:

  • lowbit = x & -x,算当前地址最多能按多大块对齐
  • 再和 n 比,防止块太大
  • 吃掉这一块,继续往后推

代码我按 Java 常规面试可交的写,不搞那些花里胡哨的流式操作:

import java.util.ArrayList;
import java.util.List;

publicclassSolution{

public List<String> ipToCIDR(String ip, int n){
        List<String> ans = new ArrayList<>();
long cur = ipToLong(ip);

while (n > 0) {
long lowbit = cur & -cur;
if (lowbit == 0) {
                lowbit = 1L << 32; // 处理 0.0.0.0 这种边界
            }

long block = lowbit;
while (block > n) {
                block >>= 1;
            }

int mask = 32;
long size = block;
while (size > 1) {
                mask--;
                size >>= 1;
            }

            ans.add(longToIp(cur) + "/" + mask);
            cur += block;
            n -= block;
        }

return ans;
    }

privatelongipToLong(String ip){
        String[] arr = ip.split("\\.");
long num = 0;
for (String part : arr) {
            num = (num << 8) + Integer.parseInt(part);
        }
return num;
    }

private String longToIp(long num){
return ((num >> 24) & 255) + "." +
               ((num >> 16) & 255) + "." +
               ((num >> 8) & 255) + "." +
               (num & 255);
    }
}

这里有两个坑,面试里特别容易写歪。

第一个,int 不稳,最好全程用 long。 因为 255.255.255.255 转成十进制已经顶到 32 位无符号上限了,Java 的 int 是有符号的,继续位运算很容易把自己绕进去。

第二个,x & -x 这个 lowbit 技巧不是随便背公式,它表示当前数二进制里最低位那个 1 单独拎出来后的值。放到这题里,就是“从当前地址出发,按对齐规则,最大能切多大块”。