在3月1号投完简历,做好测评以后,我是一直等啊等,始终期待着一面的到来。
好不容易在3月8号这天中午12点10左右接到了来自阿里的面试电话。
刚开始,我是一脸的懵逼啊,面试官问我:“你是不是面过了???”我是一脸黑脸问号.jpg。Excuse me?在我一番解释后,终于进入了正题。
首先还是自我介绍。然后下面是问题清单:
1、平时在项目中主要负责哪块技术啊?(我回答数据库方面的代码)好,那么请问,你所知道的数据库方面所需要注意的地方有什么?怎么优化数据库?
引申出来以后,他又我问了我关于left join与right join的区别,(我回答了出来),然后,他又问我那inner join呢?(我当时是忘记了,一脸懵逼啊,绝望放弃回答)?用很多join好吗,有什么 缺点?(效率降低)
![这里写图片描述](http://img.blog.csdn.net/20170308153903094?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2luYXRfMzU1MTIyNDU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)-
关于索引:
-
应该建索引的字段: 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,性能上要更高一些。它们的实现前文都已经提到过,就没什么可分析的了。
我们还需要知道一点,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中动态代理实现机制
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();
}
}
}
}
}
}
}
各种容器的初始化长度是多少?
使用ArrayList初始化时注意事项?(自动扩充机制方面,原理实现)?
好了,一面到此结束,历时一个半小时,泪崩,懵逼!(关键下午还有课!!!迟到了!!!)
###总结一点,阅读源码很重要!(Spring+SpringMVC+Mybatis)
###上面题目的部分答案,欢迎前往历年阿里面试题汇总(2017年不断更新中)、各大公司Java后端开发面试题总结查阅