美团:2019秋招 后台开发 现场面试

具体问题

  • 使用栈实现一个队列(手写代码),考虑线程安全的实现
    思路:使用2个栈,一个用于存放数据,另外一个用于辅助在取数据或者删除时临时存放。线程安全通过加锁来实现。
    代码:
import java.util.Stack;
import java.util.concurrent.locks.ReentrantLock;
public class StackQueue<T> {
    Stack<T> data = null;
    Stack<T> temp = null;
    ReentrantLock lock = new ReentrantLock();

    public StackQueue() {
        data = new Stack<T>();
        temp = new Stack<T>();
    }

    public T pop() {
        lock.lock();
        if (temp.isEmpty())
            swap(data, temp);
        if (temp.isEmpty()) {
            lock.unlock();
            return null;
        }
        T top = temp.pop();
        lock.unlock();
        return top;

    }

    public T peek() {
        lock.lock();
        if (temp.isEmpty())
            swap(data, temp);
        if (temp.isEmpty()) {
            lock.unlock();
            return null;
        }
        T top = temp.peek();
        lock.unlock();
        return top;
    }

    public void push(T element) {
        lock.lock();
        if (data.isEmpty())
            swap(temp, data);
        data.push(element);
        lock.unlock();
    }
    void swap(Stack<T> src, Stack<T> dest) {
        while (!src.empty()) {
            dest.push(src.pop());
        }
    }
    public boolean isEmpty(){
        return data.isEmpty() && temp.isEmpty();
    }
}
  • java线程模型
    线程实现:
  • 内核级线程:轻量级进程,会消耗一定的内核空间,由内核来完成线程切换
  • 用户线程:完全建立在用户空间上的线程,更加轻量级,开销更低
  • 用户线程和内核线程混合

线程调度:

  • 抢占式:线程的执行时间由线程自己决定,在自己执行完后需要主动通知系统进行进程切换
  • 协同式:线程的切换由系统控制,运行时间由系统分配

线程状态:

  • 就绪态 Ready:等待分配运行时间

  • 运行态 Running:正在运行

  • 阻塞态 Blocking:等待IO等操作

  • 等待态 Waiting、Timed Waiting:CPU调度、手动通过sleep()进入等待

  • 终止态 Terminated:运行结束

  • 线程通信方式

  • 共享变量

  • 关键字:volatilesynchronized

  • 锁:ReentrantLock

  • 管道通信:PipedInputStreamPipedOutputStream

  • 等待与通知:object.wait()/object.notify()

  • 条件变量:Condition

  • 倒计时协调器:CountDownLatch

  • 复用栅栏:CyclicBarrier

  • 信号量:Semaphore

  • 阻塞队列:ArrayBolckingQueue

  • 交换:Exchanger

  • jvm中,edens1s2的作用
    在分代回收的机制中,edens1s2都用于保存新生代的数据(存活时间较短且不会占用很多空间的小对象),其中所分配的空间比例一般为8:1:1。其中,eden用于存储新创建的对象,s1用于保存上一轮回收后存活的对象,s2用于下一次GC时的辅助空间。

所采用的GC算法是复制算法,具体机制为:在发生垃圾回收时,edens1中存活的对象复制到s2中并对edens1进行清理,然后交换s2s1的角色。

在这样的机制下,虚拟机的空间利用率能达到90\%,只有10\%用于下一轮GC的辅助空间会被“浪费”,且由于会在s1s2交替的使用复制算法,所以不会存在较大的内存碎片,整体的空间利用率较高,。

  • 只用eden和s能否解决问题
    能解决问题,但是效率较低。

对比使用edens1s2进行处理的方法,如果去掉其中一个Survivor空间,则每一次GC都只能从eden复制到s中。如果对s本身没有优化处理的话,在s中容易产生内存碎片,导致eden中稍大的存活对象都无法存放于s,最终导致提前触发下一轮GC甚至报错。虽然空间是100\%的用到了,但是整体的效率和可靠性还是较低。

  • TCP的拥塞控制机制
    慢开始、拥塞控制、快重传、快恢复

  • TCP连接为什么要使用三次握手
    用于确认通信双发的接收和发送能力

连接建立阶段 内容 发送方 接收方
1 发送方发送SYN 发送方:
接收方:
发送方:发送能力
接收方:接受能力
2 接收方发送ACKSYN 发送方:接受能力、发送能力
接收方:接受能力、发送能力
发送方:发送能力
接收方:接受能力
3 发送方发送ACNSYN 发送方:接受能力、发送能力
接收方:接受能力、发送能力
发送方:接受能力、发送能力
接收方:接受能力、发送能力
  • 解释一下servlet是什么
    本质上就是一个实现了相关接口的类,运行在Tomcat容器中。

维基百科:Servlet(Server Applet),全称Java Servlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。

  • servlet单例吗?为什么
    不一定。
    默认的情况是单例,如果在web.xml中,给对一个Servlet类进行多个配置,则会有多个实例。但是大部分情况下,只会配置一个,所以是单例的。

对于映射到同一个Servlet类的多个请求,通过创建一个Servlet实例,多个线程执行这个Servletservice方法的实现。所以在Servlet中,实例变量都不是线程安全的,只有局部变量(requestsession等)才是线程安全的。

  • servlet在处理请求前,tomcat在底层做了些啥,或者说实现一个Tomcat的大致思路
    Tomcat的结构主要分为ServerServiceConnectorContainer四部分。
    Server Tomcat服务器本身
    Service服务,默认的是Catalina
    Connector用于处理网络连接,监听端口封装网络协议,屏蔽连接与处理的细节
    Container管理Servlet并处理请求,由EngineHostContextWarrper四个部分(层级)组成。

参考:

  • 数据库索引
    B+树索引和哈希索引

  • B+树
    非叶子节点中可以保存多个指针数据,每一个数据都是一个指向其子节点的指针。
    叶子节点用于保存真正的数据,与非叶子节点相同,每个叶子节点也能保存多个数据,且相邻叶子节点之间存在指针连接。

  • 聚簇索引与非聚簇索引
    二者的数据结构都是B+树
    聚簇索引:叶子节点保存实际的数据,所以索引的顺序决定了数据的顺序
    非聚簇索引:叶子节点保存指向实际数据的指针,所以数据的顺序与索引无关

  • 非聚簇索引怎么指向具体数据
    首先需要明确的是,非聚簇索引(也叫 二级索引 )中,叶子节点里面指向数据的“指针”,并不是真正意义上的指针,即 不是指向物理位置的指针
    在非聚簇索引中,数据和索引是分开存储的,索引的叶子节点保存的是索引列和数据列的主键值。在根据保存的主键,在聚簇索引中进行第二次查找。

参考自《高性能MySQL》第三版:
这意味着通过二级索引查找行,存储引擎需要找到二级索引的叶子节点获得对应的主键值,然后更具这个值去聚簇索引中查找到对应的行。

  • 什么时候需要建立索引
    考虑如下因素:

  • 查询频度:对于查询频度高或常用于连接查询的字段或组合字段,建立索引能提高查询的效率

  • 删改频度:每一次删改都有可能需要对索引进行调整,频繁的删改会影响性能

  • 重复程度:对于重复度较高的数据,其索引也具有较高的重叠性,对效率的提高不明显却要占用空间

  • 数据类型:像blobclob等用于保存较大对象的特殊类型,不适合建立索引;较大的文本字段,建立索引也会占用较大的空间且效率不高

  • 表的规模:在表中数据较多时,使用索引一般能提高检索效率,表规模较小时,索引对效率的影响不大

  • 存储介质:当数据保存在内存中时,索引对效率的提升不会很明显

  • 如何不使用递归遍历一颗二叉树
    中序遍历思路:对于每一个节点,优先遍历左孩子,一直到最左边的节点遍历完。处理右边的节点,栈中保存的是左子树正在被遍历的节点。当一个节点的子树遍历完后,从栈中取一个节点(该节点的父节点),遍历其右子树。

非递归中序遍历二叉树

中序遍历代码:


    public static void iterate(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = root;
        while (true){
            // 不断往左下方遍历,中间的节点保存在栈中
            while (node.left != null) {
                stack.push(node);
                node = node.left;
            }
            // 处理最左边的节点
            process(node);

            // 从栈中取出父节点,并处理其右子树
            while (!stack.isEmpty() && node.right == null) {
                node = stack.pop();
                process(node);
            }
            if (node.right != null) {
                // 有右孩子,则处理右孩子
                node = node.right;
            } else {
                // 栈空,所有节点处理完毕
                break;
            }
        }
    }

    public static void process(TreeNode node) {
        System.out.print(node.val+ " ");
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容

  • Java基础 类加载的时机和类初始化的时机(引出tomcat类加载器)JVM和绝大多数用户自定义的类在JVM启动的...
    fanyank阅读 2,232评论 0 33
  • 小编费力收集:给你想要的面试集合 1.C++或Java中的异常处理机制的简单原理和应用。 当JAVA程序违反了JA...
    八爷君阅读 4,585评论 1 114
  • 包含的重点内容:JAVA基础JVM 知识开源框架知识操作系统多线程TCP 与 HTTP架构设计与分布式算法数据库知...
    消失er阅读 4,317评论 1 10
  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,301评论 0 9
  • 今天是一个特别的日子――你的生日。难怪,昨晚窗外还下着淅淅沥沥的小雨,今早就出晴了。一大早就听见叽叽喳喳清脆的鸟叫...
    DearQueen阅读 213评论 0 0