点击关注后,你不仅获得一个找资源的工具,更获得一个有趣的灵魂 ▶ ▶ ▶
刚看到个贴子,说有人外包离职后,把营销系统的核心代码连同全年营收数据一股脑扔上 GitHub,项目组人都散了,现在基本找不到人。嗯……这事吧,真是看得我脑瓜子嗡嗡的。
网友们的回帖我也瞄了几眼,有骂公司的,有说外包心态崩了的。但我觉得关键在于——信息安全不是闹着玩的,无论是谁,带情绪搞这事,最终伤到的往往是整家公司甚至一整链条的员工。
外包流动性高、强度大,这确实是行业通病,但再怎么压榨、再怎么不满,也不能升级成“同归于尽式”的报复
换个角度看,这事也提醒企业别总把核心系统全塞给外包,人散场就成了“无人接盘工程”,这种风险迟早要爆。
不过话说回来,事情已经出了,追责归追责,该补洞也得赶紧补。
希望行业能多点理性,少点火药味,安全这根弦大家都得绷紧。
面试题:可怜的小猪
这个题我当时第一次看到名字还以为是啥童话故事,结果一看…典型的数学+算法脑筋急转弯。咱慢慢聊,不整那些特别学术的说法。
大概剧情是这样: 有好多桶水,其中一桶有毒,小猪喝了毒水会在 minutesToDie 分钟内死掉。你总共只有 minutesToTest 分钟可以做实验,看能喂几轮。问题是:最少需要几只小猪,才能一定找出哪一桶是毒的?
LeetCode 里函数长这样:
public int poorPigs(int buckets, int minutesToDie, int minutesToTest)
参数就是桶数、死亡时间、总测试时间,返回最少需要的小猪数量。
你就先想最简单的:
- 如果只能做一轮实验(比如 15 分钟死一次,你只有 15 分钟),那小猪只能表现出两种状态: 要么活着,要么死了。 一只猪就是 2 种状态,两只猪就是 2×2=4 种状态,三只就是 2×2×2=8 种…
这时候你其实是在用 二进制 给每一桶水贴标签: 某只猪喝这桶就记为 1,不喝就是 0,最后看哪几只猪死了,就能反推是哪一桶。
那如果能测多轮呢?比如 15 分钟死掉,你有 60 分钟,那就可以测 4 轮:第 0、15、30、45 分钟喝。 一只猪的状态就不再是只有“活/死”两种了,而是:
也就是 rounds + 1 种状态。 其中 rounds = minutesToTest / minutesToDie,能测多少轮就是多少。
所以总结一句话(这个很关键):
一只猪最多能区分的桶数 = rounds + 1p 只猪最多能区分的桶数 =
(rounds + 1)^p
我们要做的,就是找一个最小的 p,让 (rounds + 1)^p >= buckets。
比如:
那 rounds = 60 / 15 = 4,一只猪有 4 + 1 = 5 种状态。 我们算一下:
到了 5 只猪,3125 ≥ 1000,就够了,所以答案是 5。
这里你可以把每只猪看成一个“位”,只是这个位不是二进制,而是 五进制,每桶水都有一个“编码”,猪在第几轮死就等于告诉你这一位是多少。
用对数也能算(p = ceil(log(buckets) / log(rounds+1))),不过考虑到精度问题,我更喜欢用循环一点点乘上去,既好理解又不容易出错。
直接上代码:
public class Solution {
public int poorPigs(int buckets, int minutesToDie, int minutesToTest) {
// 能测多少轮
int rounds = minutesToTest / minutesToDie;
// 一只猪有多少种状态:第几轮死或者不死
int states = rounds + 1;
int pigs = 0;
long capacity = 1; // 当前这些猪最多能区分多少桶
// 不断增加小猪数量,直到能覆盖所有桶
while (capacity < buckets) {
pigs++;
capacity *= states;
}
return pigs;
}
}
简单解释下这段:
states = rounds + 1,一只猪的状态数;capacity 表示当前这几只猪理论上能搞定多少桶,一开始 1(啥都没有也算一种…),每多一只猪,就乘一次 states;- 当
capacity >= buckets 的时候,就说明这些猪足够把所有桶区分开了。
这个题表面上是“可怜的小猪”,实际上是在考:能不能把“多轮实验”联想到“每只猪是一个多进制位”,然后用 (rounds+1)^p >= buckets 这个关系,算出最小的 p。
代码反而是最轻松的那一部分,想明白这个模型,基本就拿下了。