Java中容易被你忽略的細節(一)

1.wKiom1hlFW6jzC6uAAAerC_XgFQ034.jpg-wh_50在一個程序當中代碼段訪問了同一個對象從單獨的併發的線程當中,那麼這個代碼段叫」臨界區」 html

怎麼解決呢:使用同步的機制對臨界區進行保護 java


同步的兩種方式:同步塊和同步方法 web

對於同步來講都是使用synchronized方法算法

每個對象都有一個監視器,或者叫作鎖。數據庫

java用監視器機制實現了進程之間的異步執行瀏覽器


2.Struts框架基於MVC模式安全

Struts的工做流程: 服務器

在web應用啓動時就會加載初始化ActionServlet,ActionServlet從 cookie

struts-config.xml文件中讀取配置信息,把它們存放到各類配置對象 session

當ActionServlet接收到一個客戶請求時,將執行以下流程. 

-(1)檢索和用戶請求匹配的ActionMapping實例,若是不存在,就返回請求路徑無效信息; 

-(2)若是ActionForm實例不存在,就建立一個ActionForm對象,把客戶提交的表單數據保存到ActionForm對象中; 

-(3)根據配置信息決定是否須要表單驗證.若是須要驗證,就調用ActionForm的validate()方法; 

-(4)若是ActionForm的validate()方法返回或返回一個不包含ActionMessage的ActuibErrors對象, 就表示表單驗證成功; 

-(5)ActionServlet根據ActionMapping所包含的映射信息決定將請求轉發給哪一個Action,若是相應的 Action實例不存在,就先建立這個實例,而後調用Action的execute()方法; 

-(6)Action的execute()方法返回一個ActionForward對象,ActionServlet在把客戶請求轉發給 ActionForward對象指向的JSP組件; 

-(7)ActionForward對象指向JSP組件生成動態網頁,返回給客戶; 

爲何要用: 

JSP、Servlet、JavaBean技術的出現給咱們構建強大的企業應用系統提供了可能。但用這些技術構建的系統很是的繁亂,因此在此之上,咱們須要一個規則、一個把這些技術組織起來的規則,這就是框架,Struts便應運而生。 

基於Struts開發的應用由3類組件構成:控制器組件、模型組件、視圖組件


3.HttpServletRequest類主要處理:

1.讀取和寫入HTTP頭

2.取得和設置cookies

3.讀取路徑信息

4.標識HTTP會話


4.==  比較的是兩個對象的地址是否相同

equals 比較的是兩個對象的內容是否相同

==比較的是對象的地址,也就是是不是同一個對象;

equal比較的是對象的值。


凡是new出來的就是對象

凡是new出來的就是不一樣的對象,不管它們長的多麼類似

凡是new出來的都有本身的內存空間


5.構造方法不須要同步化。

定義在接口中的方法默認是public的。

容器保存的是對象的引用。 

構造方法每次都是構造出新的對象,不存在多個線程同時讀寫同一對象中的屬性的問題,因此不須要同步 。

若是父類中的某個方法使用了 synchronized關鍵字,而子類中也覆蓋了這個方法,默認狀況下子類中的這個方法並非同步的,必須顯示的在子類的這個方法中加上 synchronized關鍵字纔可。固然,也能夠在子類中調用父類中相應的方法,這樣雖然子類中的方法並非同步的,但子類調用了父類中的同步方法,也就至關子類方法也同步了。


6.通常關係數據模型和對象數據模型之間有如下對應關係:表對應類,記錄對應對象,表的字段對應類的屬性.


7.自動類型轉換遵循下面的規則:

1.若參與運算的數據類型不一樣,則先轉換成同一類型,而後進行運算。

2.轉換按數據長度增長的方向進行,以保證精度不下降。例如int型和long型運算時,先把int量轉成long型後再進行運算。

3.全部的浮點運算都是以雙精度進行的,即便僅含float單精度量運算的表達式,也要先轉換成double型,再做運算。

4.char型和short型參與運算時,必須先轉換成int型。

5.在賦值運算中,賦值號兩邊的數據類型不一樣時,須要把右邊表達式的類型將轉換爲左邊變量的類型。若是右邊表達式的數據類型長度比左邊長時,將丟失一部分數據,這樣會下降精度。

下圖表示了類型自動轉換的規則:

short/char--->int--->unsigned--->long---> double <---float


8.trowable 的子類 error 和 Exception

Exception 包括 非檢查性異常 RuntimeException, 及其子類,即運行時的異常,運行時的異常是代碼的BUG,

和檢查性異常,即非運行時異常,程序在編譯的時候會發現的異常 如: IOException之類,在處理相似文件流的時候,java強制規定必須處理可能遇到的文件流異常。

runtimeException是運行時的異常,在運行期間拋出異常的超類,程序能夠選擇是否try-catch處理。

其餘的檢查性異常(非運行時的異常,如IOException),是必須try-catch的,不然程序在編譯的時候就會發現錯誤。


9.Java共有六個包裝類,分別是Boolean、Character、Integer、Long、Float和Double,從字面上咱們就可以看出他們分別對應於 boolean、char、int、long、float和double。而String和Date自己就是類,所以沒有包裝類。.


10stringbuffer與stringbuilder的區別:

1.  在執行速度方面的比較:StringBuilder >  StringBuffer   

2.  StringBuffer與StringBuilder,他們是字符串變量,是可改變的對象,每當咱們用它們對字符串作操做時,其實是在一個對象上操做的,不像String同樣建立一些對象進行操做,因此速度就快了。

3.  StringBuilder:線程非安全的

  StringBuffer:線程安全的

    當咱們在字符串緩衝去被多個線程使用是,JVM不能保證StringBuilder的操做是安全的,雖然他的速度最快,可是能夠保證StringBuffer是能夠正確操做的。固然大多數狀況下就是咱們是在單線程下進行的操做,因此大多數狀況下是建議用StringBuilder而不用StringBuffer的,就是速度的緣由。


對於三者使用的總結:

1.若是要操做少許的數據用 = String

2.單線程操做字符串緩衝區下操做大量數據 = StringBuilder

3.多線程操做字符串緩衝區下操做大量數據 = StringBuffer


11.類中聲明的變量有默認初始值;方法中聲明的變量沒有默認初始值,必須在定義時初始化,不然在訪問該變量時會出錯。

boolean類型默認值是false


12.無論是靜態方法仍是非靜態方法,都須要調用後執行,其執行的次序和在類裏聲明的次序無關,區別是靜態方法是「class.method"方式執行,非靜態方法是"object.method"方式執行,即後者須要建立一個對象。

靜態成員變量(也稱類變量)先於非靜態成員變量初始化,靜態成員變量在類第一次加載時初始化,全部對象共享一份靜態成員變量,非靜態成員變量則在對象建立時初始化.

Java中常常有一些靜態塊,這是用來在生成類以前進行的初始化,不管java還C++語言中的static,都是最早初始化好的。結構以下: 

static { 

靜態語句代碼塊 


非靜態語句代碼塊 

異同點 

相同點:都是在JVM加載類時且在構造方法執行以前執行,在類中均可以定義多個,通常在代碼塊中對一些static變量進行賦值。 

不一樣點:靜態代碼塊在非靜態代碼塊以前執行(靜態代碼塊-->非靜態代碼塊-->構造函數)。 

靜態代碼塊只在第一次new(或者只要訪問了就)執行一次,以後不在執行,而非靜態代碼塊在每new一次都會執行一次,跟構造函數同樣。非靜態代碼塊能夠在普通方法中定義(我的感受做用不大);而靜態代碼塊不行。 



一、靜態代碼塊是在類加載時自動執行的,非靜態代碼塊在建立對象自動執行的代碼,不建立對象不執行該類的非靜態代碼塊。 順序: 靜態代碼塊--》非靜態代碼塊--》類構造函數。 

二、在靜態方法裏面只能直接調用同類中其餘的靜態成員(包括變量和方法),而不能直接訪問類中的非靜態成員。由於對於非靜態的方法和變量,須要先建立類的實例對象後方可以使用,而靜態方法在使用前不用建立任何對象。 

三、若是某些代碼必需要在項目啓動時候就執行,咱們能夠採用靜態代碼塊,這種代碼是主動執行的;須要在項目啓動的時候就初始化.


在不建立對象的狀況下,其餘程序來調用的時候,須要使用靜態方法,此時代碼是被動執行的。 

區別:靜態代碼塊是自動執行的; 

靜態方法是被調用的時候才執行的; 

做用:靜態代碼塊能夠用來初始化一些項目最經常使用的變量和對象;靜態方法能夠用做不建立對象也能夠能須要執行的代碼。


13.abstract class和interface的區別:

1.抽象類能夠有構造方法,接口中不能有構造方法。

2.抽象類中能夠有普通成員變量,接口中沒有普通成員變量。

3.一個類能夠實現多個接口,但只能繼承一個抽象類。

抽象類

特色:

抽象類中能夠構造方法

抽象類中能夠存在普通屬性,方法,靜態屬性和方法。

抽象類中能夠存在抽象方法。

若是一個類中有一個抽象方法,那麼當前類必定是抽象類;抽象類中不必定有抽象方法。

抽象類中的抽象方法,須要有子類實現,若是子類不實現,則子類也須要定義爲抽象的。

接口

特色:

在接口中只有方法的聲明,沒有方法體。

在接口中只有常量,由於定義的變量,在編譯的時候都會默認加上

public static final 

在接口中的方法,永遠都被public來修飾。

接口中沒有構造方法,也不能實例化接口的對象。

接口能夠實現多繼承

接口中定義的方法都須要有實現類來實現,若是實現類不能實現接口中的全部方法

則實現類定義爲抽象類。


14.1.線程經過調用對象的synchronized方法可得到對象的互斥鎖定。

2.線程調度算法是平臺獨立的。

3.經過繼承Thread類或實現Runnable接口來建立線程。

線程調度分爲協同式調度和搶佔式調度,Java使用的是搶佔式調度,也就是每一個線程將由操做系統來分配執行時間,線程的切換不禁線程自己來決定(協同式調度)。這就是平臺獨立的緣由。


15.方法的重寫(override)兩同兩小一大原則:

方法名相同,參數類型相同

子類返回類型小於等於父類方法返回類型,

子類拋出異常小於等於父類方法拋出異常,

子類訪問權限大於等於父類方法訪問權限。


16.一、boolean類型只有兩個直接量值:true和false. 

二、除成員變量會有默認初始值外,其餘變量必須在第一次使用以前初始化

boolean類型的默認值是false;

其他的7種基本類型默認值:

byte是 (byte)0;

short是 (short)0;

int是 0;

long是 0L;

float 是0.0f;

double 是0.0d;

char是 \u0000;

String是null;


17.servlet中init,service,destroy方法描述:

init方法:是在servlet實例建立時調用的方法,用於建立或打開任何與servlet相關的資源和初始 化servlet的狀態,Servlet規範保證調用init方法前不會處理任

何請求.init()方法是servlet生命的起點。

一旦加載了某個servlet,服務器將當即調用它的init()方法.

service方法:是servlet真正處理客戶端傳過來的請求的方法,由web容器調用, 根據HTTP請求方法(GET、POST等),將請求分發到doGet、doPost等方法 

destory方法:是在servlet實例被銷燬時由web容器調用。

Servlet規範確保在destroy方法調用以前全部請求的處理均完成,

須要覆蓋destroy方法的狀況:釋聽任何在init方法中打開的與servlet相關的資源存

儲servlet的狀態。destroy()方法標誌servlet生命週期的結束。


18.類加載過程

類從被加載到虛擬機內存中開始,到卸載出內存爲止,它的整個生命週期包括:加載(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸載(Unloading)7個階段。其中準備、驗證、解析3個部分統稱爲鏈接(Linking)。

加載、驗證、準備、初始化和卸載這5個階段的順序是肯定的,類的加載過程必須按照這種順序循序漸進地開始,而解析階段則不必定:它在某些狀況下能夠在初始化階段以後再開始,這是爲了支持Java語言的運行時綁定(也稱爲動態綁定或晚期綁定)。

來源:http://www.importnew.com/18548.html


19.java不容許單獨的方法,過程或函數存在,須要隸屬於某一類中。

java語言中的方法屬於對象的成員,而不是類的成員。不過,其中靜態方法屬於類的成員。

Java語言中的方法一定隸屬於某一類(對象),調用方法與過程或函數相同。


20.Java 提供的事件處理模型是一種人機交互模型。它有三個基本要素:

1) 事件源(Event Source):即事件發生的場所,就是指各個組件,如按鈕等,點擊按鈕其實就是組件上發生的一個事件;

2) 事件(Event):事件封裝了組件上發生的事情,好比按鈕單擊、按鈕鬆開等等;

3) 事件監聽器(Event Listener):負責監聽事件源上發生的特定類型的事件,當事件到來時還必須負責處理相應的事件;


21.在WEB開發中實現會話跟蹤的技術有:session,cookie,地址重寫,隱藏域。

1.Cookies

      Cookies是使用最普遍的會話跟蹤機制,Cookies是有服務器建立,並把Cookies信息保存在用戶機器上的硬盤上,下次用戶再次訪問該站點服 務器的時候,保存在用戶機器上硬盤的Cookies信息就被送回給服務器。通常Cookies通常很少於4KB,且用戶的敏感信息如信用卡帳號密碼不該該 保存在Cookies中。

2.URL重寫

       URL重用戶在每一個URL結尾附加標識回話的數據,與標識符關聯的服務器保存有關與會話的數據,如咱們訪問某個新聞的時候,在地址欄咱們通常會看到這樣的 信息:http://www.XXX.com/news?id=??,一般的話id後面的問號表示該條新聞在後臺數據庫中的新聞表的id。URL重寫可以 在客戶端停用cookies或者不支持cookies的時候仍然可以發揮做用。

3.隱藏表單域

      一般,在表單中咱們使用隱藏表單域的時候會有這麼一句代碼:<input type=」hidden」 name=」XXX」  value=」XXX」/>。經過給type屬性賦值爲hidden值來實現隱藏,這樣用戶在瀏覽的時候看不到這行代碼的數據,可是當用戶經過查看 源代碼仍是能夠看到的。

4.Session機制

       這個機制要慎用,特別是對於訪問量很大的站點,由於這種機制是吧Session信息保存在服務器端。若是訪問量特別大的話,對於服務器的承受力的要求有多高是可想而知的。


Cookie(結合session使用)

可使用 cookie 存儲購物會話的 ID;在後續鏈接中,取出當前的會話 ID,並使用這個 ID 從服務器上的查找表(lookup table)中提取出會話的相關信息。 以這種方式使用 cookie 是一種絕佳的解決方案,也是在處理會話時最常使用的方式。可是,sevlet 中最好有一種高級的 API 來處理全部這些任務,以及下面這些冗長乏味的任務:從衆多的其餘cookie中(畢竟可能會存在許多cookie)提取出存儲會話標識符的 cookie;肯定空閒會話何時過時,並回收它們;將散列表與每一個請求關聯起來;生成唯一的會話標識符。

URL 重寫

採用這種方式時,客戶程序在每一個URL的尾部添加一些額外數據。這些數據標識當前的會話,服務器將這個標識符與它存儲的用戶相關數據關聯起來。 URL重寫是比較不錯的會話跟蹤解決方案,即便瀏覽器不支持 cookie 或在用戶禁用 cookie 的狀況下,這種方案也可以工做。URL 重寫具備 cookie 所具備的一樣缺點,也就是說,服務器端程序要作許多簡單可是冗長乏味的處理任務。即便有高層的 API 能夠處理大部分的細節,仍須十分當心每一個引用你的站點的 URL ,以及那些返回給用戶的 URL。即便經過間接手段,好比服務器重定向中的 Location 字段,都要添加額外的信息。這種限制意味着,在你的站點上不能有任何靜態 HTML 頁面(至少靜態頁面中不能有任何連接到站點動態頁面的連接)。所以,每一個頁面都必須使用 servlet 或 JSP 動態生成。即便全部的頁面都動態生成,若是用戶離開了會話並經過書籤或連接再次回來,會話的信息也會丟失,由於存儲下來的連接含有錯誤的標識信息。

隱藏的表單域

HTML 表單中能夠含有以下的條目:<input type="hidden" name="session" value="a1234">

這個條目的意思是:在提交表單時,要將指定的名稱和值自動包括在 GET 或 POST 數據中。這個隱藏域能夠用來存儲有關會話的信息,但它的主要缺點是:僅當每一個頁面都是由表單提交而動態生成時,才能使用這種方法。單擊常規的超文本連接並不產生表單提交,所以隱藏的表單域不能支持一般的會話跟蹤,只能用於一系列特定的操做中,好比在線商店的結帳過程。

相關文章
相關標籤/搜索