- 相關(guān)推薦
最新2017阿里巴巴招聘筆試題
以下是CN人才網(wǎng)小編為大家整理的最新2017阿里巴巴招聘筆試題,歡迎閱讀參考。
1、多線程什么情況下執(zhí)行wait?
答:在同步代碼塊中,即對象只有獲得了互斥鎖之后才可以調(diào)用wait()方法。
延伸學(xué)習(xí)(1):
sleep( )和wait( n)、wait( )的區(qū)別:
sleep方法:是Thread類的靜態(tài)方法,當(dāng)前線程將睡眠n毫秒,線程進(jìn)入阻塞狀態(tài)。當(dāng)睡眠時間到了,會解除阻塞,進(jìn)行可運(yùn)行狀態(tài),等待CPU的到來。睡眠不釋放鎖(如果有的話)
wait方法:是Object的方法,必須與synchronized關(guān)鍵字一起使用,線程進(jìn)入阻塞狀態(tài),當(dāng)notify或者notifyall被調(diào)用后,會解除阻塞。但是,只有重新占用互斥鎖之后才會進(jìn)入可運(yùn)行狀態(tài)。睡眠時,釋放互斥鎖。
join( )方法:
當(dāng)前線程調(diào)用,則其它線程全部停止,等待當(dāng)前線程執(zhí)行完畢,接著執(zhí)行。
suspend( )和resume( )方法:
兩個方法配套使用,前者使線程進(jìn)入阻塞狀態(tài),并且不會自動恢復(fù),必須等待resume( )方法被調(diào)用,才能使得線程重新進(jìn)入可執(zhí)行狀態(tài)。
典型用法,用于等待另一個線程產(chǎn)生的結(jié)果的情形,測試發(fā)現(xiàn)結(jié)果還沒有產(chǎn)生后,讓線程阻塞。當(dāng)另一個線程產(chǎn)生了結(jié)果后,調(diào)用resume( )使其恢復(fù)。
yield() 方法:
yield() 使得線程放棄當(dāng)前分得的 CPU 時間,但是不使線程阻塞,即線程仍處于可執(zhí)行狀態(tài),隨時可能再次分得 CPU 時間。調(diào)用 yield() 的效果等價于調(diào)度程序認(rèn)為該線程已執(zhí)行了足夠的時間從而轉(zhuǎn)到另一個線程。
延伸學(xué)習(xí)(2):
線程的的生命周期:創(chuàng)建狀態(tài)、就緒狀態(tài)(可運(yùn)行狀態(tài))、運(yùn)行狀態(tài)、阻塞狀態(tài)、消亡狀態(tài)。
2、Spring容器如何加載?
答:
在應(yīng)用程序web.xml中做了以下配置信息時,當(dāng)啟動Web容器時就會自動加載spring容器。
ContextLoaderListener!!!
org.springframework.web.context.ContextLoaderListener
[html] view plain copy
org.springframework.web.context.ContextLoaderListener
ContextLoaderListener類實(shí)現(xiàn)了javax.servlet.ServletContextListener接口并且繼承了org.springframework.web.context.ContextLoader類。
ServletContextListener事件類是Web容器的一部分,處理Web應(yīng)用的Servlet上下文(context)的監(jiān)聽。實(shí)現(xiàn)ServletContextListener接口中的contextInitialized和contextDestroyed方法。當(dāng)Web容器啟動時會自動調(diào)用contextInitialized方法,進(jìn)行初始化Spring Web應(yīng)用程序上下文,主要加載web.xml中contextConfigLocation的配置文件;當(dāng)Web容器關(guān)閉之前會調(diào)用contextDestroyed方法,進(jìn)行銷毀Spring Web應(yīng)用程序上下文。ContextLoader類實(shí)現(xiàn)了Spring上下文初始化的工作,執(zhí)行initWebApplicationContext方法返回WebApplicationContext。
延伸學(xué)習(xí):
如果要spring-mvc的話,需要在web.xml文件中配置如下:
DispatchServlet!!!
org.springframework.web.servlet.DispatchServlet
[html] view plain copy
simpleSpringMVC/servlet-name>
org.springframework.web.servlet.DispatchServlet
1
simpleSpringMVC
*.htm
3、Servlet生命周期(什么時候destory)?
答:Servlet的生命周期是由Servlet容器(即Web服務(wù)器)來控制的,通過簡單的概括可以分為4步:
(1)Servlet類加載
(2)實(shí)例化Servlet
(3)Servlet提供服務(wù)
(4)銷毀Servlet
當(dāng)Web應(yīng)用被終止時,Servlet容器會先調(diào)用Web應(yīng)用中所有的Servlet對象的destroy( )方法,然后再銷毀Servlet對象。
4、10G數(shù)據(jù),每一條是一個qq號,統(tǒng)計(jì)出現(xiàn)頻率最多的qq號。
答:
首先你要注意到,數(shù)據(jù)存在服務(wù)器,存儲不了(內(nèi)存存不了),要想辦法統(tǒng)計(jì)每一個qq出現(xiàn)的次數(shù)。
比如,因?yàn)閮?nèi)存是1g,首先 你用hash 的方法,把qq分配到10個(這個數(shù)字可以變動,比較)文件(在硬盤中)。
相同的qq肯定在同一個文件中,然后對每一個文件,只要保證每一個文件少于1g的內(nèi)存,統(tǒng)計(jì)每個qq的次數(shù),可以使用hash_map(qq, qq_count)實(shí)現(xiàn)。然后,記錄每個文件的最大訪問次數(shù)的qq,最后,從10個文件中找出一個最大,即為所有的最大。
那若面試官問有沒有更高效率的解法之類的?這時,你可以優(yōu)化一下,但是這個速度很快,hash函數(shù),速度很快,他肯定會問,你如何設(shè)計(jì),用bitmap也行。
5、hashmap實(shí)現(xiàn)原理
HashMap解決hash沖突的過程如下:
HashMap 采用一種所謂的“Hash 算法”來決定每個元素的存儲位置。當(dāng)程序執(zhí)行 map.put(String,Obect)方法 時,系統(tǒng)將調(diào)用String的 hashCode() 方法得到其 hashCode 值——每個 Java 對象都有 hashCode() 方法,都可通過該方法獲得它的 hashCode 值。得到這個對象的 hashCode 值之后,系統(tǒng)會根據(jù)該 hashCode 值來決定該元素的存儲位置。源碼如下:
[java] view plain copy
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry e = table[i]; e != null; e = e.next) {
Object k;
//判斷當(dāng)前確定的索引位置是否存在相同hashcode和相同key的元素,如果存在相同的hashcode和相同的key的元素,那么新值覆蓋原來的舊值,并返回舊值。
//如果存在相同的hashcode,那么他們確定的索引位置就相同,這時判斷他們的key是否相同,如果不相同,這時就是產(chǎn)生了hash沖突。
//Hash沖突后,那么HashMap的單個bucket里存儲的不是一個 Entry,而是一個 Entry 鏈。
//系統(tǒng)只能必須按順序遍歷每個 Entry,直到找到想搜索的 Entry 為止——如果恰好要搜索的 Entry 位于該 Entry 鏈的最末端(該 Entry 是最早放入該 bucket 中),
//那系統(tǒng)必須循環(huán)到最后才能找到該元素。
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
上面程序中用到了一個重要的內(nèi)部接口:Map.Entry,每個 Map.Entry 其實(shí)就是一個 key-value 對。從上面程序中可以看出:當(dāng)系統(tǒng)決定存儲 HashMap 中的 key-value 對時,完全沒有考慮 Entry 中的 value,僅僅只是根據(jù) key 來計(jì)算并決定每個 Entry 的存儲位置。這也說明了前面的結(jié)論:我們完全可以把 Map 集合中的 value 當(dāng)成 key 的附屬,當(dāng)系統(tǒng)決定了 key 的存儲位置之后,value 隨之保存在那里即可.HashMap程序經(jīng)過我改造,我故意的構(gòu)造出了hash沖突現(xiàn)象,因?yàn)镠ashMap的初始大小16,但是我在hashmap里面放了超過16個元素,并且我屏蔽了它的resize()方法。不讓它去擴(kuò)容。這時HashMap的底層數(shù)組Entry[] table結(jié)構(gòu)如下:
Hashmap里面的bucket出現(xiàn)了單鏈表的形式,散列表要解決的一個問題就是散列值的沖突問題,通常是兩種方法:鏈表法和開放地址法。鏈表法就是將相同hash值的對象組織成一個鏈表放在hash值對應(yīng)的槽位;開放地址法是通過一個探測算法,當(dāng)某個槽位已經(jīng)被占據(jù)的情況下繼續(xù)查找下一個可以使用的槽位。java.util.HashMap采用的鏈表法的方式,鏈表是單向鏈表。形成單鏈表的核心代碼如下:
[java] view plain copy
void addEntry(int hash, K key, V value, int bucketIndex) {
Entry e = table[bucketIndex];
table[bucketIndex] = new Entry(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
上面方法的代碼很簡單,但其中包含了一個設(shè)計(jì):系統(tǒng)總是將新添加的 Entry 對象放入 table 數(shù)組的 bucketIndex 索引處——如果 bucketIndex 索引處已經(jīng)有了一個 Entry 對象,那新添加的 Entry 對象指向原有的 Entry 對象(產(chǎn)生一個 Entry 鏈),如果 bucketIndex 索引處沒有 Entry 對象,也就是上面程序代碼的 e 變量是 null,也就是新放入的 Entry 對象指向 null,也就是沒有產(chǎn)生 Entry 鏈。
HashMap里面沒有出現(xiàn)hash沖突時,沒有形成單鏈表時,hashmap查找元素很快,get()方法能夠直接定位到元素,但是出現(xiàn)單鏈表后,單個bucket 里存儲的不是一個 Entry,而是一個 Entry 鏈,系統(tǒng)只能必須按順序遍歷每個 Entry,直到找到想搜索的 Entry 為止——如果恰好要搜索的 Entry 位于該 Entry 鏈的最末端(該 Entry 是最早放入該 bucket 中),那系統(tǒng)必須循環(huán)到最后才能找到該元素。
當(dāng)創(chuàng)建 HashMap 時,有一個默認(rèn)的負(fù)載因子(load factor),其默認(rèn)值為 0.75,這是時間和空間成本上一種折衷:增大負(fù)載因子可以減少 Hash 表(就是那個 Entry 數(shù)組)所占用的內(nèi)存空間,但會增加查詢數(shù)據(jù)的時間開銷,而查詢是最頻繁的的操作(HashMap 的 get() 與 put() 方法都要用到查詢);減小負(fù)載因子會提高數(shù)據(jù)查詢的性能,但會增加 Hash 表所占用的內(nèi)存空間。
6、數(shù)組和鏈表的比較
答:
數(shù)組靜態(tài)分配內(nèi)存,鏈表動態(tài)分配內(nèi)存;
數(shù)組在內(nèi)存中連續(xù),鏈表不連續(xù);
數(shù)組元素在棧區(qū),鏈表元素在堆區(qū);
數(shù)組利用下標(biāo)定位,時間復(fù)雜度為O(1),鏈表定位元素時間復(fù)雜度O(n);
數(shù)組插入或刪除元素的時間復(fù)雜度O(n),鏈表的時間復(fù)雜度O(1)。
7、ArrayList和Linkedlist對比
答:
ArrayList和LinkedList在性能上各有優(yōu)缺點(diǎn),都有各自所適用的地方,總的說來可以描述如下:
1.對ArrayList和LinkedList而言,在列表末尾增加一個元素所花的開銷都是固定的。對ArrayList而言,主要是在內(nèi)部數(shù)組中增加一項(xiàng),指向所添加的元素,偶爾可能會導(dǎo)致對數(shù)組重新進(jìn)行分配;而對LinkedList而言,這個開銷是統(tǒng)一的,分配一個內(nèi)部Entry對象。
2.在ArrayList的中間插入或刪除一個元素意味著這個列表中剩余的元素都會被移動;而在LinkedList的中間插入或刪除一個元素的開銷是固定的。
3.LinkedList不支持高效的隨機(jī)元素訪問。
4.ArrayList的空間浪費(fèi)主要體現(xiàn)在在list列表的結(jié)尾預(yù)留一定的容量空間,而LinkedList的空間花費(fèi)則體現(xiàn)在它的每一個元素都需要消耗相當(dāng)?shù)目臻g
可以這樣說:當(dāng)操作是在一列數(shù)據(jù)的后面添加數(shù)據(jù)而不是在前面或中間,并且需要隨機(jī)地訪問其中的元素時,使用ArrayList會提供比較好的性能;當(dāng)你的操作是在一列數(shù)據(jù)的前面或中間添加或刪除數(shù)據(jù),并且按照順序訪問其中的元素時,就應(yīng)該使用LinkedList了。
程序員們,你答對了幾題,有實(shí)力進(jìn)入阿里巴巴嗎?可以留言與我們討論哦!
【最新阿里巴巴招聘筆試題】相關(guān)文章:
醫(yī)院招聘護(hù)士常見考試題目05-11
幼兒教師招聘考試題庫09-13
最新的抖音主播簡短的招聘文案11-16
最新公共場所從業(yè)人員衛(wèi)生知識培訓(xùn)試題08-10
英語試題08-17
成人高考高升專《語文》模擬試題試題11-12
招聘實(shí)習(xí)總結(jié)08-22
招聘簡歷模板10-30