某HR:有人说boss上很多公司都把年龄要求改成了 40、45岁,证明大龄打工人就业环境开始变好,但真相是招个销售、工人都在卡年龄
某HR:有人说boss上很多公司都把年龄要求改成了 40、45岁,证明大龄打工人就业环境开始变好,但真相是招个销售、工人都在卡年龄
工人岗位也是,招聘页写着45岁以内,实际到了现场一看,35以上都开始挑。你说人家不招吧,页面确实没写死;你说人家真不介意吧,HR那表情已经把答案写脸上了。
所以别光看年龄栏改没改,那玩意儿有时候就是摆给平台看的。真正卡人的地方,都藏在面试那几句话里。大龄打工人不是没机会,是机会被筛得越来越细,细到你还没开口,系统和人已经先给你打分了。
函数绑上下文,别把简单题写成反射事故
这题第一眼看着像 JavaScript 的 bind。函数本来依赖一个上下文对象,现在要提前把这个对象塞进去,后面调用的人只管传参数。
我一般不急着上反射。反射能做,但味道不对,边界也脏。算法题里真正要考的不是“怎么找到方法”,而是“怎么把一个二参函数压成一参函数”。
原来调用是这样:
R = fn(ctx, arg);
绑定以后变成:
R = bound(arg);
上下文 ctx 被提前固定住了。
Java 里可以直接用函数式接口写,别绕。
import java.util.function.Function;
publicclassBinderDemo{
@FunctionalInterface
interfaceContextFunc<C, T, R> {
R apply(C ctx, T value);
}
static <C, T, R> Function<T, R> bind(ContextFunc<C, T, R> fn, C ctx){
if (fn == null) {
thrownew IllegalArgumentException("bind failed: function is null");
}
return value -> fn.apply(ctx, value);
}
staticclassPriceContext{
int discount;
int minPrice;
PriceContext(int discount, int minPrice) {
this.discount = discount;
this.minPrice = minPrice;
}
}
publicstaticvoidmain(String[] args){
PriceContext vip = new PriceContext(20, 50);
ContextFunc<PriceContext, Integer, Integer> calcPrice = (ctx, originPrice) -> {
int realPrice = originPrice - ctx.discount;
return Math.max(realPrice, ctx.minPrice);
};
Function<Integer, Integer> vipPrice = bind(calcPrice, vip);
System.out.println(vipPrice.apply(100)); // 80
System.out.println(vipPrice.apply(60)); // 50
}
}
这里有个细节,bind 返回的不是计算结果,而是一个新函数。这个新函数里面偷偷保存了 ctx。
所以这题的关键不是循环,不是递归,也不是数据结构,关键是闭包。
Java 的 lambda 会捕获外部变量:
return value -> fn.apply(ctx, value);
这一行就够了。
ctx 在 bind 执行时已经确定,后面无论调用多少次 vipPrice.apply(),用的都是同一个上下文。
如果线上代码里真要用,我会再补一个空值兜底,别让异常飘得太远:
static <C, T, R> Function<T, R> safeBind(ContextFunc<C, T, R> fn, C ctx, R fallback){
return value -> {
try {
return fn.apply(ctx, value);
} catch (Exception e) {
return fallback;
}
};
}
不过算法题别写太重。bind 本身就是一次函数包装。
把上下文固定住,把剩下的参数留给调用方。
这题到这里就收了。