最新阿里巴巴招聘笔试题.docx
- 文档编号:15799595
- 上传时间:2023-07-07
- 格式:DOCX
- 页数:6
- 大小:18.40KB
最新阿里巴巴招聘笔试题.docx
《最新阿里巴巴招聘笔试题.docx》由会员分享,可在线阅读,更多相关《最新阿里巴巴招聘笔试题.docx(6页珍藏版)》请在冰点文库上搜索。
最新阿里巴巴招聘笔试题
最新2017阿里巴巴招聘笔试题
以下是CN人才网小编为大家整理的最新2017阿里巴巴招聘笔试题,欢迎阅读参考。
1、多线程什么情况下执行wait?
答:
在同步代码块中,即对象只有获得了互斥锁之后才可以调用wait()方法。
延伸学习
(1):
sleep()和wait(n)、wait()的区别:
sleep方法:
是Thread类的静态方法,当前线程将睡眠n毫秒,线程进入阻塞状态。
当睡眠时间到了,会解除阻塞,进行可运行状态,等待CPU的到来。
睡眠不释放锁(如果有的话)
wait方法:
是Object的方法,必须与synchronized关键字一起使用,线程进入阻塞状态,当notify或者notifyall被调用后,会解除阻塞。
但是,只有重新占用互斥锁之后才会进入可运行状态。
睡眠时,释放互斥锁。
join()方法:
当前线程调用,则其它线程全部停止,等待当前线程执行完毕,接着执行。
suspend()和resume()方法:
两个方法配套使用,前者使线程进入阻塞状态,并且不会自动恢复,必须等待resume()方法被调用,才能使得线程重新进入可执行状态。
典型用法,用于等待另一个线程产生的结果的情形,测试发现结果还没有产生后,让线程阻塞。
当另一个线程产生了结果后,调用resume()使其恢复。
yield()方法:
yield()使得线程放弃当前分得的CPU时间,但是不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得CPU时间。
调用yield()的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程。
延伸学习
(2):
线程的的生命周期:
创建状态、就绪状态(可运行状态)、运行状态、阻塞状态、消亡状态。
2、Spring容器如何加载?
答:
在应用程序web.xml中做了以下配置信息时,当启动Web容器时就会自动加载spring容器。
ContextLoaderListener!
!
!
org.springframework.web.context.ContextLoaderListener
[html]viewplaincopy
org.springframework.web.context.ContextLoaderListener
ContextLoaderListener类实现了javax.servlet.ServletContextListener接口并且继承了org.springframework.web.context.ContextLoader类。
ServletContextListener事件类是Web容器的一部分,处理Web应用的Servlet上下文(context)的监听。
实现ServletContextListener接口中的contextInitialized和contextDestroyed方法。
当Web容器启动时会自动调用contextInitialized方法,进行初始化SpringWeb应用程序上下文,主要加载web.xml中contextConfigLocation的配置文件;当Web容器关闭之前会调用contextDestroyed方法,进行销毁SpringWeb应用程序上下文。
ContextLoader类实现了Spring上下文初始化的工作,执行initWebApplicationContext方法返回WebApplicationContext。
延伸学习:
如果要spring-mvc的话,需要在web.xml文件中配置如下:
DispatchServlet!
!
!
org.springframework.web.servlet.DispatchServlet
[html]viewplaincopy
simpleSpringMVC/servlet-name>
org.springframework.web.servlet.DispatchServlet
1
simpleSpringMVC
*.htm
3、Servlet生命周期(什么时候destory)?
答:
Servlet的生命周期是由Servlet容器(即Web服务器)来控制的,通过简单的概括可以分为4步:
(1)Servlet类加载
(2)实例化Servlet
(3)Servlet提供服务
(4)销毁Servlet
当Web应用被终止时,Servlet容器会先调用Web应用中所有的Servlet对象的destroy()方法,然后再销毁Servlet对象。
4、10G数据,每一条是一个qq号,统计出现频率最多的qq号。
答:
首先你要注意到,数据存在服务器,存储不了(内存存不了),要想办法统计每一个qq出现的次数。
比如,因为内存是1g,首先你用hash的方法,把qq分配到10个(这个数字可以变动,比较)文件(在硬盘中)。
相同的qq肯定在同一个文件中,然后对每一个文件,只要保证每一个文件少于1g的内存,统计每个qq的次数,可以使用hash_map(qq,qq_count)实现。
然后,记录每个文件的最大访问次数的qq,最后,从10个文件中找出一个最大,即为所有的最大。
那若面试官问有没有更高效率的解法之类的?
这时,你可以优化一下,但是这个速度很快,hash函数,速度很快,他肯定会问,你如何设计,用bitmap也行。
5、hashmap实现原理
HashMap解决hash冲突的过程如下:
HashMap采用一种所谓的“Hash算法”来决定每个元素的存储位置。
当程序执行map.put(String,Obect)方法时,系统将调用String的hashCode()方法得到其hashCode值——每个Java对象都有hashCode()方法,都可通过该方法获得它的hashCode值。
得到这个对象的hashCode值之后,系统会根据该hashCode值来决定该元素的存储位置。
源码如下:
[java]viewplaincopy
publicVput(Kkey,Vvalue){
if(key==null)
returnputForNullKey(value);
inthash=hash(key.hashCode());
inti=indexFor(hash,table.length);
for(Entrye=table[i];e!
=null;e=e.next){
Objectk;
//判断当前确定的索引位置是否存在相同hashcode和相同key的元素,如果存在相同的hashcode和相同的key的元素,那么新值覆盖原来的旧值,并返回旧值。
//如果存在相同的hashcode,那么他们确定的索引位置就相同,这时判断他们的key是否相同,如果不相同,这时就是产生了hash冲突。
//Hash冲突后,那么HashMap的单个bucket里存储的不是一个Entry,而是一个Entry链。
//系统只能必须按顺序遍历每个Entry,直到找到想搜索的Entry为止——如果恰好要搜索的Entry位于该Entry链的最末端(该Entry是最早放入该bucket中),
//那系统必须循环到最后才能找到该元素。
if(e.hash==hash&&((k=e.key)==key||key.equals(k))){
VoldValue=e.value;
e.value=value;
returnoldValue;
}
}
modCount++;
addEntry(hash,key,value,i);
returnnull;
}
上面程序中用到了一个重要的内部接口:
Map.Entry,每个Map.Entry其实就是一个key-value对。
从上面程序中可以看出:
当系统决定存储HashMap中的key-value对时,完全没有考虑Entry中的value,仅仅只是根据key来计算并决定每个Entry的存储位置。
这也说明了前面的结论:
我们完全可以把Map集合中的value当成key的附属,当系统决定了key的存储位置之后,value随之保存在那里即可.HashMap程序经过我改造,我故意的构造出了hash冲突现象,因为HashMap的初始大小16,但是我在hashmap里面放了超过16个元素,并且我屏蔽了它的resize()方法。
不让它去扩容。
这时HashMap的底层数组Entry[]table结构如下:
Hashmap里面的bucket出现了单链表的形式,散列表要解决的一个问题就是散列值的冲突问题,通常是两种方法:
链表法和开放地址法。
链表法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位;开放地址法是通过一个探测算法,当某个槽位已经被占据的情况下继续查找下一个可以使用的槽位。
java.util.HashMap采用的链表法的方式,链表是单向链表。
形成单链表的核心代码如下:
[java]viewplaincopy
voidaddEntry(inthash,Kkey,Vvalue,intbucketIndex){
Entrye=table[bucketIndex];
table[bucketIndex]=newEntry(hash,key,value,e);
if(size++>=threshold)
resize(2*table.length);
}
上面方法的代码很简单,但其中包含了一个设计:
系统总是将新添加的Entry对象放入table数组的bucketIndex索引处——如果bucketIndex索引处已经有了一个Entry对象,那新添加的Entry对象指向原有的Entry对象(产生一个Entry链),如果bucketIndex索引处没有Entry对象,也就是上面程序代码的e变量是null,也就是新放入的Entry对象指向null,也就是没有产生Entry链。
HashMap里面没有出现hash冲突时,没有形成单链表时,hashmap查找元素很快,get()方法能够直接定位到元素,但是出现单链表后,单个bucket里存储的不是一个Entry,而是一个Entry链,系统只能必须按顺序遍历每个Entry,直到找到想搜索的Entry为止——如果恰好要搜索的Entry位于该Entry链的最末端(该Entry是最早放入该bucket中),那系统必须循环到最后才能找到该元素。
当创建HashMap时,有一个默认的负载因子(loadfactor),其默认值为0.75,这是时间和空间成本上一种折衷:
增大负载因子可以减少Hash表(就是那个Entry数组)所占用的内存空间,但会增加查询数据的时间开销,而查询是最频繁的的操作(HashMap的get()与put()方法都要用到查询);减小负载因子会提高数据查询的性能,但会增加Hash表所占用的内存空间。
6、数组和链表的比较
答:
数组静态分配内存,链表动态分配内存;
数组在内存中连续,链表不连续;
数组元素在栈区,链表元素在堆区;
数组利用下标定位,时间复杂度为O
(1),链表定位元素时间复杂度O(n);
数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O
(1)。
7、ArrayList和Linkedlist对比
答:
ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下:
1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。
对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。
2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。
3.LinkedList不支持高效的随机元素访问。
4.ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间
可以这样说:
当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。
程序员们,你答对了几题,有实力进入阿里巴巴吗?
可以留言与我们讨论哦!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 最新 阿里巴巴 招聘 笔试
![提示](https://static.bingdoc.com/images/bang_tan.gif)