程序员老鬼

某HR:有个候选人本来已经准备给他发 offer了,结果他大嘴巴离职前到处说,导致他同事打电话到我们公司说他人品很差,最终被放弃了

这哥们儿也太沉不住气了。

事情大概是这样,一个候选人面试都快走完了,HR那边本来已经准备给他发 offer。结果他还没正式离职呢,就在原公司到处嚷嚷,说自己要走了,可能还带点“我找到下家了”的那种劲儿。

然后离谱的来了,他同事不知道是有仇还是实在看不惯,直接打电话到新公司,说这个人人品不行。HR一听,得,那 offer 也别发了,人直接放弃。

Image

这事听着像瓜,但其实挺职场的。很多人一拿到点风声,就开始提前庆祝,觉得自己已经上岸了。问题是,offer 没到手,入职没完成,甚至背调都没结束,你就别把嘴开那么大

有些话真不是不能说,是别太早说。尤其离职前那几天,低调点,安静点,把交接做好,比啥都强。毕竟你也不知道,办公室里谁正憋着一口气呢。

面试题:大样本统计

大样本统计,别把样本还原成数组

count[i] 里面放的是数字 i 出现了多少次。

这题我第一眼就不太信那种“先把所有样本塞回数组,再排序统计”的写法。题目都叫大样本了,说明数据量可能很大。你真去展开,内存先不答应,时间也没必要浪费。

真正要看的东西就这几个:

最小值、最大值、平均值、中位数、众数。

除了中位数稍微绕一点,其他都能一遍扫出来。

比如 count[7] = 3,意思不是有一个 7,而是有三个 7。平均值要加的是 7 * 3,总数要加的是 3。这个地方写错,后面结果全歪。

我一般会先把基础统计扫出来:

classSolution{
publicdouble[] sampleStats(int[] count) {
int min = -1;
int max = -1;
int mode = 0;

long total = 0;
long sum = 0;
int modeCnt = 0;

for (int v = 0; v < count.length; v++) {
int c = count[v];
if (c == 0) {
continue;
            }

if (min == -1) {
                min = v;
            }
            max = v;

            total += c;
            sum += (long) v * c;

if (c > modeCnt) {
                modeCnt = c;
                mode = v;
            }
        }

double mean = sum * 1.0 / total;
double median = findMedian(count, total);

returnnewdouble[]{
                min,
                max,
                mean,
                median,
                mode
        };
    }

privatedoublefindMedian(int[] count, long total){
if ((total & 1) == 1) {
return findKth(count, total / 2 + 1);
        }

long left = total / 2;
long right = left + 1;

return (findKth(count, left) + findKth(count, right)) / 2.0;
    }

privateintfindKth(int[] count, long k){
long seen = 0;

for (int v = 0; v < count.length; v++) {
            seen += count[v];

if (seen >= k) {
return v;
            }
        }

return -1;
    }
}

这里中位数我用的是第 k 个数,不展开数组,只靠累计次数往前走。

举个简单点的例子:

count[1] = 2;
count[3] = 1;
count[5] = 2;

真实样本其实是:

1, 1, 3, 5, 5

但代码里不会真的生成这个数组。

找第 3 个数时,从小到大扫:

1 出现 2 次,累计到 2,还不够。

3 出现 1 次,累计到 3,够了。

所以第 3 个数就是 3,中位数也是 3。

这题容易翻车的地方有两个。

一个是平均值别用 int 算。v * count[v] 看着小,样本量一大就可能溢出,所以我这里直接转成 long。

另一个是偶数个样本的中位数。不是随便找一个位置,而是找中间两个位置,再取平均值。

这类题别想着炫技巧。桶都已经给你了,就顺着桶统计。少搬一次数据,代码反而更稳。