在一家創業性的互聯網公司面試經歷(包含面試題)

 

主要問你簡歷上使用的項目和技術。另外,個人感覺互聯網是一個很講究效率和性能的,所以在代碼和算法sql等上很講究 

 

servlet是不是線程安全的?應該注意什麼?

      答:首先說說什麼是線程安全。如果你當前的當前進程中,有多個線程在同時進行,而多個線程可能運行同一段代碼,如果運行結果和單線程運行結果一樣,而且其他變量的值也是和預期一樣就應該是線程安全的,反之,則線程不安全。線程安全的問題都是由全局變量和靜態變量引起的,如果線程只對全局變量和靜態變量進行讀操作,不進行寫操作,一般都是安全的。

           servlet本身就是設計在多線程的基礎上的,所以多線程的類,一般都是線程不安全的。說到這裏,先說說servlet的生命週期:init---service--destroied  .

       init有兩種情況,如果在web.xml中,沒有設置自啓動servlet,那麼,在用戶第一次訪問這個servlet的時候,會創建這個servlet實例,再根據請求類型(get/post)去調用相應的service,邏輯處理,再返回view層,當這個web服務器停止的時候,會調用destroied方法,銷燬servlet實例,否則,當前servlet實例就一直存在。

      說一下servlet的線程安全性和怎麼處理:

            servlet是多線程訪問的,如果我們當前servlet中有全局變量或者靜態變量,在service中又對這個變量進行寫操作,就可能導致這個變量值不是我們預期效果,舉一個例子,假如我們申明一個全局變量userName,每個請求用戶名賦值給userName,並將其輸出到頁面,不完整代碼:

public String userName="";//申明全局變量

userName=request.getUserName("userName");
response.write(userName);

如果用戶A,訪問的時候,我們已經得到了用戶名A並賦值給了userName,還沒有輸出到頁面,就是用戶的請求還沒有來得及響應,用戶B發來了請求,cpu的資源就被B搶佔,將userName寫成了B,此時A奪回cpu資源,響應頁面,結果是什麼?結果A響應的就是用戶B的用戶名:B。

這就造成了多線程訪問的時候,線程不安全。

  怎麼辦?一般是三個方法:實現SingleThreadModel接口,保證同時只能有一個請求訪問service方法,但是性能開銷大,以被servlet規範廢棄;加同步鎖,同樣同一時刻只能有一個線程訪問,其他排隊等候,開銷大,性能低下;避免使用全局變量,摘錄網友的描述(人家描述詳細點,嘿嘿。。):

          如何開發線程安全的Servlet                                                                                                                
 1,變量的線程安全:這裏的變量指字段和共享數據(如表單參數值)。

  a,將 參數變量 本地化。多線程並不共享局部變量.所以我們要儘可能的在servlet中使用局部變量。
   例如:String user = "";
         user = request.getParameter("user");

  b,使用同步塊Synchronized,防止可能異步調用的代碼塊。這意味着線程需要排隊處理。
  在使用同板塊的時候要儘可能的縮小同步代碼的範圍,不要直接在sevice方法和響應方法上使用同步,這樣會嚴重影響性能。

 

 2,屬性的線程安全:ServletContext,HttpSession,ServletRequest對象中屬性
  ServletContext:(線程是不安全的)
   ServletContext是可以多線程同時讀/寫屬性的,線程是不安全的。要對屬性的讀寫進行同步處理或者進行深度Clone()。
   所以在Servlet上下文中儘可能少量保存會被修改(寫)的數據,可以採取其他方式在多個Servlet中共享,比方我們可以使用單例模式來處理共享數據。
  HttpSession:(線程是不安全的)
   HttpSession對象在用戶會話期間存在,只能在處理屬於同一個Session的請求的線程中被訪問,因此Session對象的屬性訪問理論上是線程安全的。
   當用戶打開多個同屬於一個進程的瀏覽器窗口,在這些窗口的訪問屬於同一個Session,會出現多次請求,需要多個工作線程來處理請求,可能造成同時多線程讀寫屬性。
   這時我們需要對屬性的讀寫進行同步處理:使用同步塊Synchronized和使用讀/寫器來解決。

  ServletRequest:(線程是安全的)
   對於每一個請求,由一個工作線程來執行,都會創建有一個新的ServletRequest對象,所以ServletRequest對象只能在一個線程中被訪問。ServletRequest是線程安全的。
   注意:ServletRequest對象在service方法的範圍內是有效的,不要試圖在service方法結束後仍然保存請求對象的引用。

 3,使用同步的集合類:
  使用Vector代替ArrayList,使用Hashtable代替HashMap。

 4,不要在Servlet中創建自己的線程來完成某個功能。
  Servlet本身就是多線程的,在Servlet中再創建線程,將導致執行情況複雜化,出現多線程安全問題。

 5,在多個servlet中對外部對象(比方文件)進行修改操作一定要加鎖,做到互斥的訪問。

 

說說Java中的集合主要結構:
    我們大概知道:collection是頂層接口,下有set和list,set分hashset和treeSet,list分arrayList和linkedList,Map分hashMap和treeMap這個結構就行了
   。 Map中能不能用java對象做爲key值呢?這個是可以的,具體相關問題,本人也很少用到,具體瞭解請自行查詢。


   hashcode:
   http://blog.csdn.net/chinayuan/article/details/3345559
   hashcode是一種算法,hashcode想到,equals不一定相等,equals相等,hashcode一定相等。創建一個對象,肯定創建一個hashcode,當時hashcode
   也有重複的時候,重複的話,就放在同一個hashcode鏈上,所以不能用hashcode簡單比較兩個對象,還要用equals比較。那麼直接比較equals不就行了,
   爲什麼還要比較hashcode呢?hashcode是一個鏈式key/value的形式存在的,給定一個hashcode,就相當於給定了一個key就能找到快速定位找到value,
   由於hashcode有相同的情況存在,所以還需要比較equals方法,比較兩個對象的內存地址。兩個對象是這樣比較的:先比較hashcode,如果不等,equals肯定
   不等,這對象就不等(因爲hashcode是鏈式的,可以快速定位找到hashcode這個key對應的value,所以提高了效率),hashcode相等,再比較equals兩個對象
   的內存地址,所以在覆寫hashcode方法的時候,儘量保證寫的算法得到的的值不一樣的

   序列化和反序列化:
      實現Serializable接口,只是做一個標示,沒有方法,作用:將類轉換成字節流,方便存儲和傳輸,反序列化,就是對序列化的方向操作,
      從字節流重構成一個對象,java對象在序列化的時候,會把他的所有屬性和關聯對象都序列化,但是static修飾的不能,因爲static修飾的是
      代表類了

   數據庫索引:
      create index  索引名 on 表名(列名)
      索引是放在某個列上的,索引可以增加查詢速度,增加分頁和排序速度,但是索引需要存儲空間,在增刪改的時候需要去維護索引,所以索引不是
      越多越好,應該在經常查詢的字段上創建,經常where或者排序分組的字段上創建
    索引失效的情況:在直接使用導入方法導入數據庫的時候,可能會使索引失效,在sql左邊做了運算的時候,可能會失效,比如:
    select  * from table where id-1=9,應該使用 select * from table where id=10

    hibernate的髒數據,事物行,spring的aop和ioc

 

string和stringbuffer怎麼選擇使用,有什麼區別:

String是final類,不可變的,所以每拼一個都是在創建一個對象

    String str="select * from table_name" ;

   str=str+" where id>10 "//這時候會再創建一個str對象,意思這個sql就用了兩個string對象了

但是StringBuffer  sb=new StringBuffer( " select * from table_name" ); sb.append(" where id>10"); 這就是隻有一個對象,stringbuffer是可變字符串

所以,最好選用stringBuffer,減少系統消耗,提高性能

 

jdk1.5後,引入了stringBuilder,這個是單線程,速度更快,但是線程不安全,所以單從速度上將:stringbuilder>stringBuffer>string 也要考慮線程安全性

 


         

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章