首页 > 笔经面经 > 字节后端实习一二面面经

字节后端实习一二面面经

头像
肥羊E_hirta
编辑于 2020-03-04 19:17:36 APP内打开
赞 9 | 收藏 110 | 回复14 | 浏览4146
一面:
自我介绍
JVM是做什么的?你的理解?
接口和抽象类的区别
有种东西叫抽象接口类,在抽象类中实现接口,你实现过这样的代码吗,有什么用(我:强制子类也实现接口)
设计模式,我讲了单例:饿汉懒汉、双检锁、静态内部类
写代码:实现一个抽象类,要求继承它的子类可以不用自己再实现单例模式,而自动可以利用父类的机制来获取到单例
我在父类里弄了个饿汉式,子类直接调用super的getInstance()返回单例实例
面试官:一般单例不是不应该允许new去创建新实例的吗,那样就破坏单例了,怎么实现这个限制?
我:那就把子类的构造方法设成private
面试官:那父类呢?要是创建了父类对象怎么办?
我:那就父类也设成private
然后运行发现报错了
面试官:为什么会这样?
我:(思考)因为子类默认构造函数要调用父类构造函数,然后父类只有一个private的构造函数,它对子类不可见
后面不记得了。。记得折腾了一番最后没继续往下问了

数据结构:堆、栈、队列、链表、数组,有没有哪个没听过的?(我:没有)
算法题:两个栈实现最大栈,要求pop, push, get_max都为O(1)(很经典了)
我依稀记得有两种做法,一种辅助栈仅压入比栈顶大的元素(单调栈),一种是辅助栈每次都要压入,压入的是当前累计最大值
我用的第一种,注意一下判断边界条件,如辅助栈为空的时候无需比较直接压入、栈为空的时候pop()应该返回None或其他特殊值、主栈要压入的元素等于辅助栈栈顶元素时,辅助栈是否要压入等

数据库,你觉得自己学到了什么程度?
我:CRUD,索引多少了解一点
面试官:那索引为什么能使查询变快?你描述一下索引是做什么的
我:B+树,类似于如果数组无序,我们只能遍历,但如果建了多叉树(B+树),我们就可以快速搜索,复杂度log(m)n,m为分叉数
面试官:复杂度是log(m)n?你怎么得出来的
我:就像二叉树logn一样嘛
面试官:你要注意在每个内部节点里面,决定走哪个分叉的时候,你平均情况下要检查m/2个值的,复杂度O(m),所以总共并不是log(m)n
我:是的,我算错了
——3.1更新,感谢评论区老哥给出的思路,我自己尝试推了一遍,大家感兴趣可以戳 https://zhuanlan.zhihu.com/p/110202102

面试官:性别上建索引会怎么样?
我:可选项太少,查完之后只能排除一半,还要继续扫描。如果用在联合索引里面,应该放最右边
面试官:解释一下最左匹配原则(略)
思考题:如果有A,B两个字段,两个都很常用,你是建联合索引(A,B)好,还是单独建(A)、(B)好?

10分钟后二面
二面:
介绍一下你在上一家公司做的项目
你用到了Elasticsearch,底层了解吗?(不了解)
ES底层是什么引擎你知道吗?(Lucene)
我实在是不懂ES,没有继续聊下去

算法题:马踏棋盘
有4*4的棋盘,给定马的起点坐标i,j,可走步数N(起点算0步),走过的点可以重复走,求长度为N的所有可能路径数
我:递归深搜,暴力
写了十几分钟,成功运行了
面试官:分析复杂度?
我:如果不管棋盘大小,是O(8^N),如果4*4,那么每个点最多只能有四个位置可走,O(4^N)
面试官:为什么这么高复杂度?(我:有重复解)如何优化?
我:可能剪枝或者DP吧,没想出来
(实际上应该可以保存走过的状态,如对于(p, q, k)表示(p,q)这个坐标上还剩k步时这个子问题的解,后面可以复用)

Python *args **kwargs区别?
我说我Java比Python熟
写代码:Java中如何实现一个swap函数,交换数组中两个整数的值(略)
原地实现?(a=a+b, b=a-b, a=a-b)
你这个原地实现有一个缺陷,你知道是什么吗(两数相加可能会溢出)
如何解决溢出?(没想到)
——3.1更新 感谢评论区老哥提示,可以用异或交换整型或字符类型等可以表示为二进制串的变量,且不需要额外空间(原地)
思路类似上面的原地交换,首先a和b异或(第一步肯定是这么干,不然没别的操作可做了),
然后试图由a^b反推a:如果异或后的位是1,那么a的原位肯定和b的原位不一样;异或后为0,一定和b原位一样
所以可以反推a,赋值给b
最后再反推b的原值,赋值给a
为什么用异或:位操作中,只有异或可以做到由异或后的值和其中一个原值反推另外一个原值(可以想想为什么)

如果是泛型,如何实现(我一开始只把类型换了,其他按原样)
面试官:如果是两个Integer呢,你能成功交换它们的值么,运行试试
我:发现并没有交换成功
面试官:为什么(复制了引用,赋值修改的是引用,没能动到原来的值)
面试官:怎么解决?(没想到)
——2.29更新,用反射通过参数里的引用强行访问私有字段,可以实现参数为对象引用类型的swap。不过还有一个问题:如果对象字段除了基本类型外,还含有其他类型的对象呢?写一个深搜去递归拷贝?用序列化/clone方法?大家有想法可以贴在评论区
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Integer[] arr = new Integer[]{1, 2};
        StringDemo.swap(arr[0], arr[1]);
        System.out.println(Arrays.toString(arr));    //[2,1],交换成功
    }
    private static void swap(Integer a, Integer b) throws NoSuchFieldException, IllegalAccessException {
        Class c = Integer.class;
        Field f = c.getDeclaredField("value");
        f.setAccessible(true);
        f.setInt(a, 2);
        f.setInt(b, 1);
    }

Java中使用枚举类有什么好处?
我当时只讲了方便管理常量,比如一个表示星期几的枚举类
enum Week{Monday, …, Sunday}
可以通过Week week = Week.Monday的形式来调用,如果自己去定义final Monday=1的话,无法对week的取值作出限制,如果取了week=9可能会出现难以检查的错误,而枚举类的话不允许取枚举集合以外的值(除了null)

Java在运行时有几个进程?
提示一下吧,你说说Java线程,Java进程,Java在运行时在Linux中体现为什么进程,JVM又体现为什么?
我:讲了一下线程和进程的区别,说没试过top去看执行java命令后会有哪些进程
面试官:你说线程共享进程地址空间,这地址空间里面有什么?(我只想到了堆和方法区)
进程通信的方式?(我:信号、管道、共享内存、socket)
你说了信号,那信号有哪几种?分别怎么用?不知道,那你kill的时候用的是什么信号?

over,你有什么想问我的吗?
我:求反馈和建议,您觉得我哪里不足该多学学
面试官:你想学什么就去学,多学没坏处
(2333)

两个面试官都挺和善的,我觉得要是挂了也有个教训,看面经不能光背答案,得看深看扎实一点
等通知ing,感觉二面有点悬啊

3.3更新:已凉orz

14条回帖

回帖
加载中...
话题 回帖

相关热帖

笔经面经近期热帖

近期精华帖

热门推荐