2017年阿里内推一面面经(不断更新)

在3月1号投完简历,作好测评之后,我是一直等啊等,始终期待着一面的到来。html

好不容易在3月8号这天中午12点10左右接到了来自阿里的面试电话。面试

刚开始,我是一脸的懵逼啊,面试官问我:“你是否是面过了???”我是一脸黑脸问号.jpg。Excuse me?在我一番解释后,终于进入了正题。算法


首先仍是自我介绍。而后下面是问题清单:spring

一、平时在项目中主要负责哪块技术啊?(我回答数据库方面的代码)好,那么请问,你所知道的数据库方面所须要注意的地方有什么?怎么优化数据库?数据库

引伸出来之后,他又我问了我关于left join与right join的区别,(我回答了出来),而后,他又问我那inner join呢?(我当时是忘记了,一脸懵逼啊,绝望放弃回答)?用不少join好吗,有什么 缺点?(效率下降)编程

这里写图片描述
这里写图片描述

  • 关于索引:后端

    • 应该建索引的字段:
      1.常常做为查询条件的字段
      2.外键
      3.常常须要排序的字段
      4.分组排序的字段安全

    • 应该少建或者不建索引的字段有:
      1.表记录太少
      2.常常须要插入,删除,修改的表,
      3.表中数据重复且分布平均的字段bash


二、HTTP的特色,TCP/UDP特色以及区别?服务器

1.支持客户/服务器模式。

2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法经常使用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不一样。因为HTTP协议简单,使得HTTP服务器的程序规模小,于是通讯速度很快。

3.灵活:HTTP容许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。

4.无链接:无链接的含义是限制每次链接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开链接。采用这种方式能够节省传输时间。

5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺乏状态意味着若是后续处理须要前面的信息,则它必须重传,这样可能致使每次链接传送的数据量增大。另外一方面,在服务器不须要先前信息时它的应答就较快。


三、HashMap、HashTable、ConCurrentHasgMap的区别以及实现原理?
ConCurrentHasgMap调用get()方法的时候有锁吗?

对于put和remove操做,是使用锁同步来进行的,不过是用的ReentrantLock而不是synchronized,性能上要更高一些。它们的实现前文都已经提到过,就没什么可分析的了。

友情连接:ConCurrentHasgMap源码分析

咱们还须要知道一点,ConcurrentHashMap的迭代器不是Fast-Fail的方式,因此在迭代的过程当中别其余线程添加/删除了元素,不会抛出异常,也不能体现出元素的改动。但也没有关系,由于每一个entry的成员除了value都是final修饰的,暴漏出去也不会对其余元素形成影响。

  • 为何hashmap扩容是是扩大成原来的2倍,而不是3倍?

友情连接:深刻理解HashMap(及hash函数的真正巧妙之处)


四、怎么实现并发编程?请详细描述?

锁机制(Lock)、CAS无锁算法、Synchronized区别


五、类加载机制(若是本身写几个Jar包,应该放哪里?)


六、String、StringBuffer、StringBuilder的区别?

若是StringBuilder后增长一个字符串常量,而且这时候是多线程运行,那这时候StringBuilder是线程安全的吗?

字符串常量就是不能改变该对象,然后者是但是改变的字符串对象,他不像String同样,须要每次建立,后二者是在原有的字符串对象进行操做的。


七、JDK七、8的区别?

在JMM方面的区别:

永久代
在JDK8以前的HotSpot实现中,类的元数据如方法数据、方法信息(字节码,栈和变量大小)、运行时常量池、已肯定的符号引用和虚方法表等被保存在永久代中,32位默认永久代的大小为64M,64位默认为85M,能够经过参数-XX:MaxPermSize进行设置,一旦类的元数据超过了永久代大小,就会抛出OOM异常。

虚拟机团队在JDK8的HotSpot中,把永久代从Java堆中移除了,并把类的元数据直接保存在本地内存区域(堆外内存),称之为元空间。

这样作有什么好处?
有经验的同窗会发现,对永久代的调优过程很是困难,永久代的大小很难肯定,其中涉及到太多因素,如类的总数、常量池大小和方法数量等,并且永久代的数据可能会随着每一次Full GC而发生移动。

而在JDK8中,类的元数据保存在本地内存中,元空间的最大可分配空间就是系统可用内存空间,能够避免永久代的内存溢出问题,不过须要监控内存的消耗状况,一旦发生内存泄漏,会占用大量的本地内存。

ps:JDK7以前的HotSpot,字符串常量池的字符串被存储在永久代中,所以可能致使一系列的性能问题和内存溢出错误。在JDK8中,字符串常量池中只保存字符串的引用。


八、JMM在初始化堆内存时,新生代与老年代的默认比例是多少?

永久代不属于堆内存,堆内存只包含新生代和老年代。

默认的,新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值能够经过参数 –XX:NewRatio 来指定 ),即:新生代 ( Young ) = 1/3 的堆空间大小。
老年代 ( Old ) = 2/3 的堆空间大小。其中,新生代 ( Young ) 被细分为 Eden 和 两个 Survivor 区域,这两个 Survivor 区域分别被命名为 from 和 to,以示区分。
默认的,Edem : from : to = 8 : 1 : 1 ( 能够经过参数 –XX:SurvivorRatio 来设定 ),即: Eden = 8/10 的新生代空间大小,from = to = 1/10 的新生代空间大小。
‍JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务,因此不管何时,老是有一块 Survivor 区域是空闲着的。
所以,新生代实际可用的内存空间为 9/10 ( 即90% )的新生代空间。

  • Java内存模型的描述?

九、Spring中控制反转定义?相比于建立对象的好处?AOP编程的优势?

友情连接:三大框架的原理及优缺点

原来咱们的程序咱们控制的是具体的实现,写程序直接写实现,如今咱们控制的是它的接口它的抽象,原来咱们依赖的是它的实现,如今咱们依赖的是它的抽象。从具体的实现反转到抽象的概念上,咱们针对的是接口编程。

1)下降组件之间的耦合度,实现软件各层之间的解耦。
Controller——>Service——>DAO
2)可使用容器提供的众多服务,如:事务管理服务、消息服务等等。当咱们使用容器管理事务时,开发人员就再也不须要手工控制事务.也不需处理复杂的事务传播。
3)容器提供单例模式支持,开发人员再也不须要本身编写实现代码。
4)容器提供了AOP技术,利用它很容易实现如权限拦截、运行期监控等功能。
5)容器提供的众多辅做类,使用这些类可以加快应用的开发,如: JdbcTemplate、 HibernateTemplate。
6)Spring对于主流的应用框架提供了集成支持,如:集成Hibernate、JPA、Struts等,这样更便于应用的开发。
7) 使用spring容器能够提供的服务:事务管理服务,JMS服务,Spring Core核心服务,持久化服务等。
8)若是使用Spring, 咱们就再也不须要手工控制事务,例如在Hibernate中控制事务的语句 session.beginTransaction();session.getTransaction().commit();
9)使用Spring,再也不须要咱们处理复杂的事务传播行为。


十、SpringMVC中动态代理的实现机制,源码?

友情连接:Spring AOP动态代理原理与实现方式 (转)

友情连接:Java的动态代理机制和Spring的实现方式

友情连接:Java中动态代理实现机制


十一、读过哪些源码,请详细描述一个你最熟悉的?(我回答ArrayList)

十二、JVM虚拟机?请详细描述?

1三、Java GC回收机制?请详细描述?

1四、问了两道智力题!!!!!

(1)有8个产品,其中有一个次品(有可能偏重,有可能偏轻),那么如何用天平秤三次找出那个次品?

(2)忘记了。。。。关于买卖问题

1五、看过GitHub上的开放源码吗(好比阿里,腾讯优秀团队的)?

1六、使用过哪些代码管理工具?(Git,Maven)熟练使用吗?会不会使用GitHub上传代码?

1七、使用过哪些写代码的工具?(Myeclipse和IDE),列出你经常使用的快捷键?

1八、学习编程的方法、渠道?(看博客,网站)?上哪些网站?

1九、说说本身的优缺点?学习时间的分配?

20、漏了一个问题,怎么实现让两个线程交替执行?(用代码实现?)

通常来讲线程锁能够用:Synchronized、Lock。
这个题目的难点不在于同步块,而在于怎么样设计这个两个线程的交替实现。因为线程争用cpu的随机性,就须要A线,B线程执行,在B执行完一次进入等待以前唤醒A,如此往复,那么这里就要用上notify和wait了。

public class Thread1 {  
    public static void main(String args[]) {  
        final Bussiness business = new Bussiness();  
        Thread a=new Thread(new Runnable(){  
            @Override  
            public void run(){  
                business.SubThread();  
            }  
        });  
        Thread b=new Thread((new Runnable() {  
            @Override  
            public void run() {  
                business.MainThread();  
            }  
        }));  
        a.start();  
        b.start();  
    }  
}  



class Bussiness {  
    private static Object LOCK = new Object();  
    volatile boolean bShouldSub = true;//这里至关于定义了控制该谁执行的一个信号灯  

    public void MainThread() {  
        for (int i = 0; i < 50; i++) {  
            synchronized (LOCK) {//notify和wait的对象必定要和synchronized的对象保持一致  
                for (int j = 0; j < 10; j++) {  
                    System.out.println(Thread.currentThread().getName() + "+MainThread:i=" + i + ",j=" + j);  
                }  
                if (bShouldSub) {  
                    bShouldSub = false;  
                    LOCK.notify();  
                    if(i<49){  
                        try {  
                            LOCK.wait();  
                        }catch (InterruptedException e) {  
                            // TODO Auto-generatedcatch block  
                            e.printStackTrace();  
                        }  
                    }  
                }  
            }  
        }  
    }  


    public void SubThread() {  
        for (int i = 0; i < 50; i++) {  
            synchronized (LOCK){  
                for (int j = 0; j < 5; j++) {  
                    System.out.println(Thread.currentThread().getName() + "+SubThread:i=" + i + ",j=" + j);  
                }  
                if (!bShouldSub) {  
                    bShouldSub = true;  
                    LOCK.notify();  
                    if(i<49){  
                        try {  
                            LOCK.wait();  
                        } catch (InterruptedException e) {  
                            // TODO Auto-generatedcatch block  
                            e.printStackTrace();  
                        }  
                    }  

                }  
            }  
        }  
    }  

}复制代码

各类容器的初始化长度是多少?

使用ArrayList初始化时注意事项?(自动扩充机制方面,原理实现)?

好了,一面到此结束,历时一个半小时,泪崩,懵逼!(关键下午还有课!!!迟到了!!!)

总结一点,阅读源码很重要!(Spring+SpringMVC+Mybatis)


上面题目的部分答案,欢迎前往历年阿里面试题汇总(2017年不断更新中)各大公司Java后端开发面试题总结查阅



更多内容,可关注个人我的公众号

相关文章
相关标签/搜索