程序员老鬼

国企外包突然让离项,说被甲方看见我玩手机,以后就不用来了

外包这身份,真是说轻就轻啊。

离下班还有半个多小时,一个电话打过来,说甲方看到你玩手机了,以后不用来了。不是沟通,不是提醒,也不是问一下情况,直接“已经决定了”。

关键你说玩手机这事吧,职场里谁敢保证自己一整天眼睛都焊在电脑上?当然摸鱼被抓不好看,但因为这一眼,外包公司连坐班、换项目、过渡安排都不提,直接让人离场,这就有点把人当临时零件了。

Image

更离谱的是手续还没办完,人已经被通知不用来了。那工资怎么算,考勤怎么算,离项原因怎么写,这些可不是一句“甲方不满意”就糊过去的。

外包最难受的地方就在这,活是你干,锅你背。甲方一句话,供应商一个电话,人就悬空了,真挺现实。

面试题:检查是否是类的对象实例

对象明明是 ArrayList,校验却被挡在门外。

日志里只有一行:

param type check failed, expect=java.util.List, actual=java.util.ArrayList

这类题看着简单,实际很容易写成“只比较类名”。一比较类名,继承、接口、父类全废了。

错误写法大概是这样:

staticbooleanbadCheck(Object obj, Class<?> clazz){
return obj != null && obj.getClass() == clazz;
}

这段代码判断 new ArrayList<>() 是不是 ArrayList,没问题。

但判断它是不是 List,直接 false。

这地方我一般不信 ==。对象实例判断,看的不是“它当前类名是不是完全一样”,而是“它这条继承链上,或者它实现的接口里,有没有目标类型”。

Java 自己有 instanceof,但算法题通常不会让你直接一句写完。我们可以手动把这件事拆开。

import java.util.*;

publicclassTypeChecker{

publicstaticbooleanisObjectInstance(Object value, Class<?> targetType){
if (value == null || targetType == null) {
returnfalse;
        }

        Class<?> current = value.getClass();

while (current != null) {
if (current == targetType) {
returntrue;
            }

if (hasInterface(current, targetType)) {
returntrue;
            }

            current = current.getSuperclass();
        }

returnfalse;
    }

privatestaticbooleanhasInterface(Class<?> sourceType, Class<?> targetType){
        Queue<Class<?>> queue = new ArrayDeque<>();
        Collections.addAll(queue, sourceType.getInterfaces());

while (!queue.isEmpty()) {
            Class<?> item = queue.poll();

if (item == targetType) {
returntrue;
            }

            Collections.addAll(queue, item.getInterfaces());
        }

returnfalse;
    }

publicstaticvoidmain(String[] args){
        Object data = new ArrayList<String>();

        System.out.println(isObjectInstance(data, ArrayList.class)); // true
        System.out.println(isObjectInstance(data, List.class));      // true
        System.out.println(isObjectInstance(data, Collection.class)); // true
        System.out.println(isObjectInstance(data, HashMap.class));   // false
        System.out.println(isObjectInstance(null, List.class));      // false
    }
}

这里有两个点别漏。

第一个,null 不是任何类的实例。这个判断要放最前面,不然后面 value.getClass() 直接炸。

第二个,接口不能只看当前类。比如 ArrayList 实现的是 List,List 又继承了 Collection。如果只扫一层接口,判断 Collection 时就会漏掉。

这题真正考的不是反射 API,而是你有没有把 Java 类型关系想完整:

当前类
  -> 父类
  -> 父类的父类
  -> 当前类实现的接口
  -> 接口继承的接口

所以判断流程就很朴素:先看当前类,再看接口,再往父类走。

当然,线上代码真要写,我不会自己造这个轮子,直接用:

targetType.isInstance(value)

算法题才手写。工程里硬写一套,后面遇到代理类、类加载器、泛型擦除这些边角问题,排起来没什么意思。能用 JDK 的,就别装勤快。