面试题随记二

作者: 小白先生哦

面试题随记

从7月2号开始,到7月21号结束,14个工作日,参加了15场面试。其中:

滴滴:面4场

美团:面3场

自如:面2场

小米:面3场

去哪儿:面1场

Boss直聘:面2场

工作3年,终于拿到了心仪的offer,在这里做一个记录。

因平时上班事情比较多,再加上面试比较密集,所以没能及时的对每一次面试做一个复盘,导致面试遇到的好多东西都已经忘了,所以这里就只能捡在微信文件助手里面的几个有意思的记录来写了。

好记性不如烂笔头,写出来一是给自己做一个笔记,二是也希望分享出来能对其他朋友有所帮助。


美团二面 1、如果因为一些原因,线上Redis挂了,然后所有请求打到数据库层导致数据库也挂了,这时该怎么进行恢复? {1、如果因为一些原因,线上redis挂了,然后所有请求打到数据库层导致数据库也挂了,这时该怎么进行恢复?}

就以三年的工作经验来说显然是超出了的范围,没遇到过这样的场景,平时也没怎么想过,然后当时的第一思路就是先做限流,然后逐步恢复Redis和数据库。

很明显,当时这个问题回答的并没有让面试官满意,但是实在所见有限,没有其他思路了,欢迎路过的朋友给一些其他思路。 2、Spring里面的bean id是否允许重复?如果允许重复的话重复了怎么办?如果不允许重复是怎么处理的? {2、spring里面的bean-id是否允许重复?如果允许重复的话重复了怎么办?如果不允许重复是怎么处理的?}

因为在的个人简历里面写了自己深入阅读过Spring源码的,所以这一个问题明显是就这一项的发问,当时自己确实记得是不允许重复的,所以回答的是不允许重复,如果重复了抛出bean重复定义的异常。然后面试官当场给指出来说是允许重复的,如果重复了的话后加载进来的是覆盖前面的,不会做抛错。

针对这个问题,重新翻阅了一下Spring源码,原来记混淆了,会抛出异常的是beanDefinition,处理逻辑如下方法: DefaultListableBeanFactory.registerBeanDefinition

    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {
        // 删掉了一部分代码
        BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
            if (!isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
            }
            else if (existingDefinition.getRole() < beanDefinition.getRole()) {
                if (logger.isInfoEnabled()) {
                    logger.info("Overriding user-defined bean definition for bean '" + beanName +
                            "' with a framework-generated bean definition: replacing [" +
                            existingDefinition + "] with [" + beanDefinition + "]");
                }
            }
            else if (!beanDefinition.equals(existingDefinition)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Overriding bean definition for bean '" + beanName +
                            "' with a different definition: replacing [" + existingDefinition +
                            "] with [" + beanDefinition + "]");
                }
            }
            else {
                if (logger.isTraceEnabled()) {
                    logger.trace("Overriding bean definition for bean '" + beanName +
                            "' with an equivalent definition: replacing [" + existingDefinition +
                            "] with [" + beanDefinition + "]");
                }
            }
            this.beanDefinitionMap.put(beanName, beanDefinition);
        }
        else {
            // 删掉了一部分代码
        }
        // 删掉了一部分代码
    }

可以看出,beanDefinition重复是否会抛出异常也是结合配置来说的。而对于实例id重复,那么直接是覆盖了,如代码:

    protected void addSingleton(String beanName, Object singletonObject) {
        synchronized (this.singletonObjects) {
            this.singletonObjects.put(beanName, singletonObject);
            this.singletonFactories.remove(beanName);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }

当然,这个问题的前置还有Spring的bean生命周期系列,回答完后问到这里的。 3、G1对宿主机有什么要求?

这个当时回答不上来,然后也没找到什么有用的资料; 4、堆设置有什么注意事项?

留出可用空间的20%给元空间。


小米一面 1、手写Dubbo的加权随机算法

背景是简历上面写了深入了解Dubbo,对Dubbo源码有深入了解,然后面试官就问出了这个问题。比较简单,写出的代码如下:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class WeightedRandom {
    private static Random random = new Random();
    public static void main(String[] args) {
        List<Node> list = new ArrayList();
        list.add(new Node("节点一(5)",5));
        list.add(new Node("节点二(3)",3));
        list.add(new Node("节点三(2)",2));
        for (int i = 0;i < 10000;i++) {
            Node cur = selected(list);
            // 统计操作
        }
        // 打印结果
    }
    private static Node selected(List<Node> list) {
        if (list == null || list.size() == 0) {
            return null;
        } else if (list.size() == 1) {
            return list.get(0);
        }
        int totalWeight = 0;
        boolean sameWeight = true;
        int firstWeight = 0;
        for (int i = 0;i < list.size();i++) {
            if (i == 0) {
                totalWeight += list.get(0).weight;
                firstWeight = list.get(0).weight;
                totalWeight += list.get(i).weight;
                if (list.get(i).weight != firstWeight) {
                    sameWeight = false;
                }
            }
        }
        if (!sameWeight) {
            int curVal = random.nextInt(totalWeight);
            for (int i = 0;i < list.size();i++) {
                curVal -= list.get(i).weight;
                if (curVal < 0) {
                    return list.get(i);
                }
            }
        }
        return list.get(random.nextInt(list.size()));
    }
    private static class Node {
        String name;
        int weight;
        public Node(String name,int weight) {
            this.name = name;
            this.weight = weight;
        }
    }
}

2、Spring获取代理对象解决事务失效的问题。

调Spring对应的api,这样做会把框架代码耦合在自己的业务代码中;

自己注入自己,需要注意死循环的问题;

尽量避免这种同一个Service中非事务方法调用事务方法的情况。


滴滴二面 1、一个升序数组,随机选择一个旋转节点。右边的有序段放到左边,依然保持有序;左边的有序段放到右边,依然保持有序。然后从这个数组中查找某个数。 {1、一个升序数组,随机选择一个旋转节点。右边的有序段放到左边,依然保持有序;左边的有序段放到右边,依然保持有序。然后从这个数组中查找某个数。}

这个问题本质还是找那个旋转点,当知道那个旋转点后,无非就是在左边或者右边进行二分查找。

当时回答这个问题的主要思路就是从一个数组两头开始,分别作为left和right,然后计算中间位置mid,然后在left和mid之间找新的left,在mid和right之间找新的right,不断逼近从而找出那个旋转节点,旋转节点满足条件:arr[index - 1] > arr[index] > arr[index + 1]。


美团一面 1、Spring和Mybatis是怎么结合的?

这个问题当时没有理解面试官的意图,然后回答它们之间有一个整合包,这个整合包充当了一个适配器的角色,然后面试官就没有再问了。 2、mysql explain有哪些项?

常规问题,比如涉及的表、访问方法、可能索引、实际使用的索引等。 3、dubbo协议

这一个也是针对简历来问的,听到后心里有点凉快,然后就老实回答自己对于一些核心流程代码确实看过,但是对于这样底层的东西确实没有怎么了解过。 4、单链表找循环节点。 leetcode上的常规题了,几分钟就搞定了。


小米二面 1、顺序读取一亿个整数,找出前100万大的数字,内存限定大小为10M,后内存限定大小为5M。 {1、顺序读取一亿个整数,找出前100万大的数字,内存限定大小为10m,后内存限定大小为5m。}

首先回答1个整型在内存中占4个字节,100万个整数占用4M,然后在内存中加载200万个整数分为2个组,排序然后合并选出前100万大的数字,然后重新读取100万个数字继续同样的操作。

这时,面试官说将内存限制为5M。

很明显,就是想问问大顶堆而已,然后就回答使用大顶堆,毕竟返回结果不要求严格有序,只要前100万大就可以了。

小米二面面完后,还有三面的,但是实在忍受不了那个三面面试官那牛逼哄哄的样子,所以面到一半就直接退出会议室了,面了这么多场,遇到了一些态度很好的面试官,也遇到一些态度很差的面试官,就数小米这三面面试官的态度最他么恶心。

在小米三面的时候就已经拿到自己想要的offer了,所以那天面试也就是抱着聊的好玩的心态聊,并没想去小米,结果着实把恶心了。


去哪儿一面 1、stream和foreach区别?

有使用,但是没有太多了解,就没有回答出什么。 2、zookeeper和nacos区别?nacos符合CP还是AP?

这个问题印象特别深,原本是没有看过nacos官方对这一个介绍的,但是看过CAP理论,然后想到即使nacos挂了,nacos客户端仍然可以通过本地缓存列表继续工作,所以果断回答了AP。

原文创作:小白先生哦

更多推荐

更多
  • Java测试驱动开发-十二、通过实现连续交付利用 TDD 案例研究可怕的赌博公司,探索代码库,释放程序,部署到生产环境,增加测试覆盖率,结论,可能的改进,实施持续集成,走向持续交付,詹金斯装置,自动化构建,第一次执行,下一步是什么?,这仅仅是开始,这不一定是结束, “没有什么比结果更能说
  • Java测试驱动开发-一、为什么我应该关心测试驱动的开发? 为什么是 TDD?,理解 TDD,红绿重构,速度是关键,这与测试无关,测试,黑盒测试,白盒试验,质量检查和质量保证之间的区别,更好的测试,嘲笑,可执行文件,无调试, 这本书是由开发人员为开发人员编写的。因此,大部分学习将通过代码进
  • Java测试驱动开发-十一、把它们放在一起 简而言之,TDD,最佳做法,命名约定,过程,开发实践,工具, “如果你总是做你一直做的事,那么你将永远得到你一直得到的。”——阿尔伯特·爱因斯坦我们经历了大量的理论和更多的实践。整个旅程就像一列高速行驶的火车,我们几乎没有
  • Java测试驱动开发-零、前言 这本书是给谁的,充分利用这本书,下载示例代码文件,下载彩色图像,使用的惯例, 测试驱动开发已经有一段时间了,很多人还没有采用它。这背后的原因是 TDD 很难掌握。尽管这个理论很容易掌握,但要真正精通它需要大量的实践。本书的作者多年
  • Java测试驱动开发-四、单元测试—关注你做了什么,而不是已经做了什么 单元测试什么是单元测试?,为什么要进行单元测试?,代码重构,为什么不专门使用单元测试呢?,用 TDD 进行单元测试,TestNG,TestNG 与 JUnit 摘要,遥控船舶要求,遥控船舶的研制,项目设置,助手类,需求–起点和方向,规格
  • Java测试驱动开发-五、设计—如果它不可测试,那么它就设计得不好 我们为什么要关心设计?,设计原则,你不会需要它的,不要重复你自己,保持简单和直接,奥卡姆剃刀,坚实的原则,连接 4,要求,测试 Connect 4 的最后一个实现,要求 1–游戏的棋盘,要求 2–介绍光盘,要求 3–球员轮换,要求 4–
  • Java测试驱动开发-二、工具、框架和环境 吉特,虚拟机,Vagrant,Docker,构建工具,综合发展环境,创意演示项目,单元测试框架,朱尼特,TestNG,Hamcrest 和 AssertJ,汉克雷斯特,资产,代码覆盖工具,杰科科,模拟框架,Mockito,轻松的,模拟的
  • Java测试驱动开发-六、模拟—删除外部依赖项 嘲笑,为什么嘲笑?,术语,模拟对象,Mockito,Tic Tac Toe v2 要求,开发 TicTacToe v2,要求 1–门店移动,规范–数据库名称,实施,规范–Mongo 集合的名称,实施,重构,规范–将项目添加到 Mongo
  • Java测试驱动开发-九、重构遗留代码—使其再次年轻 遗留代码,遗留代码示例,识别遗留代码的其他方法,遗留代码更改算法,应用遗留代码更改算法,确定变化点,寻找测试点,打破依赖关系,写作测试,卡塔演习,卡塔遗产酒店,描述,技术意见,添加新功能,黑盒或峰值测试,初步调查,如何找到重构的候选对象
  • Java测试驱动开发-八、BDD—与整个团队合作 不同规格,文档,编码员的文档,非编码人员的文档,行为驱动开发,叙述,情节,书店 BDD 故事,杰伯哈夫,JBehave 转轮,未决步骤,Selenium 和 Selenide,JBehave 步骤,最终验证, “我不是一个优秀的程
  • 近期文章

    更多
    文章目录

      推荐作者

      更多