程序员老鬼

同事35岁,上午被裁,还没到午饭时间就退了群,午休后更删光了所有同事。一时间办公室哗然,这是不打算再往来了?

刚看到个贴子,说有个35岁的同事上午刚被裁,饭点都没到就退群,午休后更是把所有同事都删了。办公室顿时炸开锅,大家议论纷纷,这是不是要彻底断联了?

Image

我觉得这事吧,挺能理解的。换位想一下,35岁被裁,本身就是个打击,留在群里难免被各种问候和探听,反而更刺心。不如干脆利落一点,删掉就是给自己一个缓冲。网友里有的觉得“太绝情”,但在我看来,这就是成年人处理关系的方式——能量有限,把注意力留给未来比纠结旧关系更重要。

从职场角度讲,人际关系本来就建立在价值和交换上。离开了那个圈子,强行维系也未必有意义。删掉不是仇恨,而是止损。说到底,工作只是生活的一部分,人走茶凉也是常态。【备注:文末可领最新资料】

算法题:最大数量高于平均水平的订单

昨晚十一点多,我在公司楼下抽根烟哈,手机叮一下,小李问:“哥,那个…最大数量高于平均水平的订单,这题到底想考啥?”我脑袋一热:这不就是业务里常见的“看看有多少订单比平均单量/客单价高”的那点事嘛。别紧张,思路就一条线,写出来也就几行,但坑还是有的,别踩。

你给我一堆订单数值(可以是订单金额、件数,随便),问题是:有多少条严格大于整体平均值。注意是“> 平均”,不是“≥”。还有,平均是算全体的平均,不是分组。

就是那个…先求和再求平均,然后再扫一遍数:谁比平均大就数一个。时间 O(n),内存 O(1)。唯一要小心的是整型溢出和精度,sum 用 long,平均用 double/BigDecimal,看你数据多大。

publicclassOrdersAboveAvg{
// 返回严格大于平均值的订单数量
publicstaticintcountAboveAverage(int[] orders){
if (orders == null || orders.length == 0) return0;
long sum = 0L;
for (int v : orders) sum += v;              // 防溢出
double avg = sum / (double) orders.length;  // 精度够用,大多数业务 OK

int cnt = 0;
for (int v : orders) if (v > avg) cnt++;
return cnt;
    }

// 金额是分/厘,特别大?可以用 BigDecimal
publicstaticintcountAboveAverageBD(java.math.BigDecimal[] orders){
if (orders == null || orders.length == 0) return0;
        java.math.BigDecimal sum = java.math.BigDecimal.ZERO;
for (var v : orders) sum = sum.add(v);
var avg = sum.divide(new java.math.BigDecimal(orders.length), 8, java.math.RoundingMode.HALF_UP);
int cnt = 0;
for (var v : orders) if (v.compareTo(avg) > 0) cnt++;
return cnt;
    }

// 一嘴流式写法,图个利索
publicstaticlongcountAboveAverageStream(int[] orders){
if (orders == null || orders.length == 0) return0;
double avg = java.util.Arrays.stream(orders).average().orElse(Double.NaN);
return java.util.Arrays.stream(orders).filter(v -> v > avg).count();
    }
}

昨天那会儿脑子迷糊我还写错过… 1)溢出:sum 千万别用 int,百万订单、金额以分为单位,很容易爆。 2)精度:比较时用同一种数制,double 就 double,别拿 int 去比,强转别乱来。 3)空数组:直接 0,别抛 NPE。 4)全相等:比如全是 100,平均也是 100,结果就是 0,别怀疑这是对的。 5)负数也行:有退货、冲减为负?平均一样照算,不要特判。

就是那个…很多时候不是全量,而是“最近7天”“本月每店铺一组”。这时加一层分组再套同样逻辑就好:

  • 内存版:对每个分组先求和+计数,得到平均,再二扫计数。

  • SQL 嘴快版(金额列 amount):

    WITH base AS (
    SELECT store_id, amount,
    AVG(amount) OVER (PARTITIONBY store_id) AS avg_amt
    FROM orders
    WHERE order_time >= CURRENT_DATE - INTERVAL'7'DAY
    )
    SELECT store_id, COUNT(*) AS cnt_above_avg
    FROM base
    WHERE amount > avg_amt
    GROUPBY store_id;

流式场景(Kafka/Flink)就用两阶段聚合:先做 Sum、Count 得 group 平均,再在窗口里二次过滤计数,或者把第一阶段的平均当广播状态用,别在每条上重复全表扫描…我上周就因为这个被同事吐槽,哎。

行了我先去泡杯茶…哦对,有人问“≥ 平均要不要算”,不算,这题是严格大于,改成 >= 你自己心里有数就行。

-END-

我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

最后给大家分享一份不错的副业资料,点击下方公众号,回复关键字: 副业 领取,也可以链接我领取,微信:hls404