年底裁员新套路,leader找下属说有裁员名额,让你选择自己走,过几天再说裁员名额取消了,一分赔偿不用给!
刚看到个贴子,说年底裁员新套路:leader单独找人谈话,说现在有裁员名额,你要不要自己走,暗示还能体面点。结果人家开始准备交接了,过几天领导一句“名额取消了”,当事人成了主动想走的人,一分赔偿都没有。
我觉得这事吧,恶心就恶心在:公司想省钱可以理解,但别拿人当猴耍。说到底,这是典型的信息差+话术碾压,专挑不懂规则、又怕事的员工下手。换个角度想,真有名额,为什么不书面通知、走正规流程?
从我的角度看,遇到这种情况,记住两点:别口头答应“主动离职”,所有沟通尽量留痕;凡是让你签字的东西,拍照留底、看不懂就别签。
我为大家打造了一份RPA教程, 完全免费: songshuhezi.com/rpa.html 最后给大家分享一份不错的副业资料,点击下方公众号,回复关键字: 副业 领,也可以链 接我微信: hls404
面 试 题 :H2O 生成
昨天晚上十一点多,我已经准备关电脑了,我们组那个小李突然甩给我一句:哥,你给我讲讲那个 H2O 生成的并发题呗,Java 的,我脑袋都要烧了。 我看了下题目,哎,这不是面试高频那个嘛。 简单说下题目哈:系统里会有很多线程在跑,氢原子线程会调用
hydrogen(Runnable releaseHydrogen)
,氧原子线程会调用
oxygen(Runnable releaseOxygen)
,这俩方法被乱七八糟地并发调用。你的任务就是——不管线程怎么来,你最后打印出来的字符串,每 3 个字符必须刚好组成一分子水:两个
H
一个
O
,顺序随意,比如
HHO
、
HOH
都行,但绝对不能出现
HHH
或
OOH
这种妖魔鬼怪。
小李一开始的思路特别典型,直接一个大锁
synchronized
套住,说我保证串行不就完事了吗。这个当然能跑,但是,面试官一看:好家伙,多线程题给你变成单线程题了,那问个啥劲儿,对吧。
我就跟他说,你别先想代码,先脑补一个生活画面:想象有一个小房间,每次最多只能进 3 个人,规定是两位“氢同学”和一位“氧同学”坐满才开饭。那我们需要解决两个小事: 一个是“座位怎么限制”,另一个是“凑够三个人再一起开饭”。
座位这个事,用 Java 里
Semaphore
特别顺手。氢有 2 个名额,氧有 1 个名额:
-
对氢线程:想进来就
acquire()一下氢的座位,没票就乖乖在门口等。 - 对氧线程:同理,抢氧的那个座位。
CyclicBarrier(3)
,意思是:等到 3 个线程都调用了
await()
,大家再一起往下执行。它还能自动“重置”,下一拨 3 个再来一轮,正好对应一分子水。
所以整体套路就出来了:
-
氢线程先抢
hSemaphore的票,再去barrier.await()集合,等人齐;放行后打印H,最后把票还回去。 -
氧线程抢
oSemaphore的票,同样去barrier.await(),放行后打印O,再还票。
barrier
门口,凑够 3 个才一起往下走,打印完了把票还回去,下一轮继续抢座位。
给你看下完整代码,Java 版本的,面试直接抄脑子里这套就行了:
import java.util.concurrent.Semaphore;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
publicclass H2O {
// 氢最多允许两个线程同时参与一轮
privatefinal Semaphore hSemaphore = new Semaphore(2);
// 氧一轮只能来一个
privatefinal Semaphore oSemaphore = new Semaphore(1);
// 每 3 个线程组成一分子水
privatefinal CyclicBarrier barrier = new CyclicBarrier(3);
public H2O() {
}
public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
// 抢氢的名额,抢不到就等下一轮
hSemaphore.acquire();
try {
// 等这一轮的 3 个线程都到齐
barrier.await();
} catch (BrokenBarrierException e) {
// 简单处理下,真实项目里可以打日志之类
thrownew RuntimeException(e);
}
// 真正打印一个 H
releaseHydrogen.run();
// 把名额还回去,给下一轮用
hSemaphore.release();
}
public void oxygen(Runnable releaseOxygen) throws InterruptedException {
// 抢氧的那个唯一名额
oSemaphore.acquire();
try {
barrier.await();
} catch (BrokenBarrierException e) {
thrownew RuntimeException(e);
}
// 打印一个 O
releaseOxygen.run();
oSemaphore.release();
}
}
LeetCode 上的判题器会传进来
releaseHydrogen
和
releaseOxygen
,里头一般就是
System.out.print("H")
或
System.out.print("O")
,所以你只负责把线程节奏控好就行。
这个写法有几个细节,小李当时听完是“哦哦哦”那种恍然大悟的表情:
-
为啥要
barrier.await()在前,run()在后?因为 barrier 负责把这一轮的 3 个线程“锁在同一波”,大家同时往下跑,打印的顺序虽说可能有点乱(比如 O 先打出来也行),但至少保证每一波都是 3 个字符,而且由 2H+1O 组成。 -
为啥
release()要放在run()之后?否则你还没打印完,就提前把票发给下一批线程,理论上也能对,但容易把线程节奏搞得更晃悠,调试的时候你自己会被绕晕。
Semaphore
的初始许可数和
CyclicBarrier
的人数都可以跟着改,这套模型是通用的,只是现在这道题固定是 2:1,所以代码看起来比较“写死”。
行,我就先说到这儿,刚好咖啡也凉了,我去续一杯,你自己把代码敲一遍,别光截图收藏。
-END
-
我为大家打造了一份RPA教程, 完全免费: songshuhezi.com/rpa.html 最后给大家分享一份不错的副业资料,点击下方公众号,回复关键字: 副业 领,也可以链 接我微信: hls404