2017年阿里内推一面面经

来源:互联网 发布:触摸屏 手势软件 编辑:程序博客网 时间:2024/05/22 00:22

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

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

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


首先还是自我介绍。然后下面是问题清单:

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

引申出来以后,他又我问了我关于left join与right join的区别,(我回答了出来),然后,他又问我那inner join呢?(我当时是忘记了,一脸懵逼啊,绝望放弃回答)?用很多join好吗,有什么 缺点?(效率降低)

left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 
right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录 
inner join(等值连接) 只返回两个表中联结字段相等的行 

参考:sql之left join、right join、inner join的区别

  • 关于索引:

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

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


2、HTTP的特点,TCP/UDP特点以及区别?

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

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

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

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

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


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

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

友情链接:ConCurrentHasgMap源码分析

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

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

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


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

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


5、类加载机制(如果自己写几个Jar包,应该放哪里?)


6、String、StringBuffer、StringBuilder的区别?

如果StringBuilder后增加一个字符串常量,并且这时候是多线程运行,那这时候StringBuilder是线程安全的吗?

字符串常量就是不能改变该对象,而后者是可是改变的字符串对象,他不像String一样,需要每次创建,后两者是在原有的字符串对象进行操作的。


7、JDK7、8的区别?

在JMM方面的区别:

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

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

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

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

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


8、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内存模型的描述?

9、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,不再需要我们处理复杂的事务传播行为。


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

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

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

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


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

12、JVM虚拟机?请详细描述?

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

14、问了两道智力题!!!!!

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

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

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

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

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

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

19、说说自己的优缺点?学习时间的分配?

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();                          }                      }                  }              }          }      }  }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

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

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

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

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


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

转载:http://blog.csdn.net/sinat_35512245/article/details/60873196
原创粉丝点击