美团日常一面二面

美团日常一面二面,第1张

美团日常一面二面 一面(11: 00)

1.自我介绍,可以出来实习否

2.说一说你自己做的项目吧。你没有工作过,项目没什么好问的啊

3.讲讲mysql的索引为什么要用B+树

B+树是一个多叉的平衡树,平衡树就是每个节点的叶子节点高度差不超过1,并且在它的非叶子节点存储的是索引,数据全都存储在叶子节点中,用一个链表串联起来,遍历时只需遍历该链表。
B+树的节点只存储索引key值,具体信息的地址存在于叶子节点的地址中。这就使以页为单位的索引中可以存放更多的节点。减少更多的I/O支出。因此,B+树成为了数据库比较优秀的数据结构,MySQL中MyIsAM和InnoDB都是采用的B+树结构。不同的是前者是非聚集索引,后者主键是聚集索引,所谓聚集索引是物理地址连续存放的索引,在取区间的时候,查找速度非常快,但同样的,插入的速度也会受到影响而降低。聚集索引的物理位置使用链表来进行存储。

3.1为什么是多叉并且是平衡呢

多叉且平衡可以使树的高度降低,降低查询时IO的次数。并且索引存在着一定的顺序,支持范围的比较查询。

3.2那么一般数据库表会有多个索引,查询随便一个非主键索引时是如何查询的呢

在数据库中,存在主键(聚集)索引和普通索引。如果没有指定默认会生成一个聚集索引,在查询非聚集索引时,该索引数据结构的底层存储的是主键的值,因此会根据查询到的主键再做一次回表查询,在使用explain关键字时会出现 using index condition。

3.3那么如何避免回表查询呢?

我们可以利用索引覆盖的原理,除了主键索引外,对要查询的其他字段添加普通索引即可。

3.4InnoDB索引和MyISAM索引的区别

一是主索引的区别,InnoDB的数据文件本身就是索引文件。而MyISAM的索引和数据是分开的。
二是辅助索引的区别:InnoDB的辅助索引data域存储相应记录主键的值而不是地址。而MyISAM的辅助索引和主索引没有多大区别。

4.B+树为什么更矮胖?

数据库访问数据要通过页,一个页就是一个B+树节点,访问一个节点相当于一次I/O *** 作,所以越快能找到节点,查找性能越好。
B+树的特点就是够矮够胖,能有效地减少访问节点次数从而提高性能。

4.1B+树与B树的不同

(1)B+树非叶子节点不存在数据只存索引,B树非叶子节点存储数据
(2)B+树查询效率更高。B+树使用双向链表串连所有叶子节点,区间查询效率更高(因为所有数据都在B+树的叶子节点,扫描数据库 只需扫一遍叶子结点就行了),但是B树则需要通过中序遍历才能完成查询范围的查找。
(3)B+树查询效率更稳定。B+树每次都必须查询到叶子节点才能找到数据,而B树查询的数据可能不在叶子节点,也可能在,这样就会造成查询的效率的不稳定
(4)B+树的磁盘读写代价更小。B+树的内部节点并没有指向关键字具体信息的指针,因此其内部节点相对B树更小,通常B+树矮更胖,高度小,查询产生的I/O更少。

5.给一个联合索引,判断一下会不会走索引

(1)单个索引需要注意的事项,组合索引全部通用。比如索引列不要参与计算啊、or的两侧要么都索引列,要么都不是索引列啊、模糊匹配的时候%不要在头部啦等等
(2)最左匹配原则。(A,B,C) 这样3列,mysql会首先匹配A,然后再B,C。如果用(B,C)这样的数据来检索的话,就会找不到A使得索引失效。如果使用(A,C)这样的数据来检索的话,就会先找到所有A的值然后匹配C,此时联合索引是失效的。
(3)把最常用的,筛选数据最多的字段放在左侧。

6.jvm里面怎么判断垃圾呢?

JVM判断垃圾回收有两种方法,一种是引用计数法,另一种是可达性分析法(GC Roots)。

引用计数法:给对象添加一引用计数器,被引用一次计数器值就加 1;当引用失效时,计数器值就减 1;计数器为 0 时,对象就是不可能再被使用的,简单高效,缺点是无法解决对象之间相互循环引用的问题。

可达性分析法:通过一系列的称为 “GC Roots” 的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的。此算法解决了引用计数法循环引用的问题。

7.时间过得好慢,来做两道题吧。算法题:删除倒数第K个节点。

public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode n1 = dummy;
        ListNode n2 = dummy;
        for(int i = 0; i <= n; i++) {
            n2 = n2.next;
        }
        while(n2 != null) {
            n1 = n1.next;
            n2 = n2.next;
        }
        n1.next = n1.next.next;
        return dummy.next;
    }

8.反问:聊了聊一些技术栈的事情。

总结:一面有说有笑,感觉像是聊天。下午就约了二面。

二面(14: 00)

1.自我介绍

2.项目

3.shardingsphere proxy,Java agent,字节码注入?

Sharding-Proxy 定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。目前提供 MySQL 和 PostgreSQL 版本,它可以使用任何兼容 MySQL/PostgreSQL 协议的访问客户端(如:MySQL Command Client, MySQL Workbench, Navicat 等) *** 作数据,对 DBA 更加友好。

jdk1.5以后引入了javaAgent技术,javaAgent是运行方法之前的拦截器。我们利用javaAgent和ASM字节码技术,在JVM加载class二进制文件的时候,利用ASM动态的修改加载的class文件,在监控的方法前后添加计时器功能,用于计算监控方法耗时,同时将方法耗时及内部调用情况放入处理器,处理器利用栈先进后出的特点对方法调用先后顺序做处理,当一个请求处理结束后,将耗时方法轨迹和入参map输出到文件中,然后根据map中相应参数或耗时方法轨迹中的关键代码区分出我们要抓取的耗时业务。最后将相应耗时轨迹文件取下来,转化为xml格式并进行解析,通过浏览器将代码分层结构展示出来,方便耗时分析。

4.数据库分布式怎么搞?

5.垂直拆分有什么问题?

6.问问Java基础吧,ArrayList和linkedList的区别

(1)ArrayList是实现了基于动态数组的数据结构,linkedList基于链表的数据结构。

(2)对于随机访问get和set,ArrayList觉得优于linkedList,因为linkedList要移动指针。

(3)对于新增和删除 *** 作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
<这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于linkedList。但若是批量随机的插入删除数据,linkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。 >

(4)查找 *** 作indexOf,lastIndexOf,contains等,两者差不多。

(5)随机查找指定节点的 *** 作get,ArrayList速度要快于linkedList.
<这里只是理论上分析,事实上也不一定,ArrayList在末尾插入和删除数据的话,速度反而比linkedList要快。>

7.HashMap全套

8.ConcurrentHashMap全套

9.syncronized全套

10.jvm内存模型。

11.怎么判断哪些是垃圾

12.垃圾回收算法?你用过哪些垃圾收集器?

13.你用过的机器内存有多大,碰到过哪些问题?

14.innodb事务的隔离级别

隔离级别脏读(Dirty Read)不可重复读(NonRepeatable Read)幻读(Phantom Read)未提交读(Read uncommitted)可能可能可能已提交读(Read committed)不可能可能可能可重复读(Repeatable read)不可能不可能可能可串行化(Serializable )不可能不可能不可能

未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据

提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)

可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读

串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

15.可重复读解决了什么问题?

16.索引调优思路?

对数据库的优化有俩个方面:优化查询(使用索引、使用连接查询代替子查询)和优化数据库表结构

优化查询包括:使用MySQL自带的关键字explain或describe(desc)可以对查询语句进行分析、使用索引进行查询、优化子查询(使用连接查询(join)代替子查询可以提高查询效率)

优化数据库表结构包括:将字段较多的表分解成多个表、增加中间表、增加冗余字段、优化插入记录的速度、分析、检查和优化表、优化MySQL的参数

17.讲一讲Java的线程

(1)newCachedThreadPool:这是第一种可缓存线程池,线程池为无限大,当执行当前任务时上一个任务已经完成,会复用执行上一个任务的线程,而不用每次新建线程

(2)newFixedThreadPool:这是个可重用固定个数的线程池,当当前线程数大于总数则会进行等待,等待线程池内的线程执行完,相对来说比较少占内存,如果等待线程过多也是相对消耗资源的

(3)ScheduledThreadPool:这是个可重用固定个数的线程池,当前线程数大于总数则会进行等待,并且可以设置线程延迟执行时间

(4)newSingleThreadExecutor:单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。缺点就是单线程执行,当线程多的时候执行速度比较慢

(5)自定义线程池(ThreadPoolExecutor和BlockingQueue连用)
BlockingQueue是双缓冲队列。BlockingQueue内部使用两条队列,允许两个线程同时向队列一个存储。,一个取出 *** 作。在保证并发安全的同时,提高了队列的存取效率。

18.分布式中间件会吗?比如zookeeper?

19.springmvc流程?

具体步骤:

第一步:发起请求到前端控制器(DispatcherServlet)

第二步:前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找)

第三步:处理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象,多个HandlerInterceptor拦截器对象),通过这种策略模式,很容易添加新的映射策略

第四步:前端控制器调用处理器适配器去执行Handler

第五步:处理器适配器HandlerAdapter将会根据适配的结果去执行Handler

第六步:Handler执行完成给适配器返回ModelAndView

第七步:处理器适配器向前端控制器返回ModelAndView (ModelAndView是springmvc框架的一个底层对象,包括 Model和view)

第八步:前端控制器请求视图解析器去进行视图解析 (根据逻辑视图名解析成真正的视图(jsp)),通过这种策略很容易更换其他视图技术,只需要更改视图解析器即可

第九步:视图解析器向前端控制器返回View

第十步:前端控制器进行视图渲染 (视图渲染将模型数据(在ModelAndView对象中)填充到request域)

第十一步:前端控制器向用户响应结果

20.做道题吧:力扣143. 重排链表

public void reorderList(ListNode head) {
        if(head == null || head.next == null || head.next.next == null) {
            return;
        }
        ListNode slow = head;
        ListNode fast = head;
        while(fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode newHead = slow.next;
        slow.next = null;
        newHead = reverseList(newHead);
        while(newHead != null) {
            ListNode temp = newHead.next;
            newHead.next = head.next;
            head.next = newHead;
            head = newHead.next;
            newHead = temp;
        }
    }
    private ListNode reverseList(ListNode head) {
        if(head == null) {
            return null;
        }
        ListNode curr = head;
        head = head.next;
        curr.next = null;
        while(head != null) {
            ListNode temp = head.next;
            head.next = curr;
            curr = head;
            head = temp;
        }
        return curr;
    }

21.反问

总结:面Java厂还是比较舒服的,没怎么问计算机基础(暑假深入学了网络和系统都没问)。美团的算法题也比较简单,比较注重实战能力。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5695726.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存