最近的幾十年內(nèi),計(jì)算模型發(fā)生了巨大的變化,由于這些變化,出現(xiàn)了對(duì)大規(guī)模電子商務(wù)與電子交易系統(tǒng)應(yīng)用程序安全的更大需求,這正如最近對(duì)幾個(gè)受歡迎站點(diǎn)的大量拒絕服務(wù) (DoS) 攻擊所表明的那樣。
尤其是對(duì)于 Java 團(tuán)體,隨著 Java 作為因特網(wǎng)編程的 事實(shí)上的 標(biāo)準(zhǔn)平臺(tái)出現(xiàn),安全移動(dòng) Java 代碼的能力已成為基本要求。 本文是系列文章中的第一篇,討論計(jì)算機(jī)安全和密碼學(xué)的一般概念。
雖然可移動(dòng)代碼并不是一個(gè)革命性的概念,但是 Java 和因特網(wǎng)給計(jì)算機(jī)安全帶來(lái)了一些不同尋常的挑戰(zhàn)。Java 體系結(jié)構(gòu)的演化及其對(duì)安全的影響、不同的安全 API 和工具軟件以及 applet 安全,等等,將在隨后的文章中討論。
此安全性論文系列并不打算提供計(jì)算機(jī)安全問(wèn)題的綜合指南。計(jì)算機(jī)安全是一個(gè)多層面的問(wèn)題,它涉及若干學(xué)科、部門(mén)和文化。
技術(shù)投資后,接著就應(yīng)該著手培訓(xùn)、嚴(yán)格的策略強(qiáng)制執(zhí)行和總體安全策略的定期審查。 注:有關(guān)算法進(jìn)展的詳細(xì)信息,請(qǐng)參閱專(zhuān)題“ 二十一世紀(jì)的加密算法”;有關(guān)密鑰長(zhǎng)度在安全性中的重要性的討論,請(qǐng)參閱專(zhuān)題“ 密鑰的長(zhǎng)度是否重要?”。
什么是計(jì)算機(jī)安全? 要從總體上理解什么是計(jì)算機(jī)安全,有必要考慮一下安全在日常生活中意味著什么。我們將看到,日常生活中的一般安全規(guī)則同樣適用于計(jì)算機(jī)安全。
計(jì)算機(jī)安全的局限性 有沒(méi)有絕對(duì)計(jì)算機(jī)安全這樣的事情?一句話(huà),沒(méi)有這樣的事情。術(shù)語(yǔ) 安全系統(tǒng)是一個(gè)不恰當(dāng)?shù)拿Q(chēng),因?yàn)樗凳玖讼到y(tǒng)要么是安全的,要么是不安全的。
安全實(shí)際上是一種平衡。如果提供的資源是無(wú)限的,則任何形式的安全都能遭到破壞。
盡管攻擊者可用來(lái)實(shí)施攻擊的資源越來(lái)越多,但在現(xiàn)實(shí)世界中,這些資源仍然是有限的。考慮到這一點(diǎn),我們應(yīng)該這樣來(lái)設(shè)計(jì)所有系統(tǒng):讓攻擊者為破壞這些系統(tǒng)所付出的,遠(yuǎn)遠(yuǎn)大于破壞之后他們所能得到的。
端到端的安全 什么是端到端的安全?在一個(gè)多層系統(tǒng)中,每一層都應(yīng)該有其自身的安全,并且與其他層協(xié)調(diào)一致。為匯集在一起的不同系統(tǒng)和中間件設(shè)計(jì)安全,是一個(gè)相當(dāng)大的挑戰(zhàn)。
簡(jiǎn)單地說(shuō),系統(tǒng)安全的程度僅相當(dāng)于最弱的一環(huán)的安全程度;除非您按端到端的觀點(diǎn)考慮安全,否則安全隨時(shí)可以遭到破壞。 簡(jiǎn)單性 一個(gè)復(fù)雜的安全設(shè)計(jì)會(huì)起作用嗎?乍看起來(lái),制止未授權(quán)用戶(hù)訪問(wèn)系統(tǒng)的最佳方法也許是,設(shè)計(jì)一個(gè)非常復(fù)雜的安全方案,但事實(shí)并非如此。
不僅設(shè)計(jì)復(fù)雜的安全系統(tǒng)的高成本使人不敢問(wèn)津,而且,要是這種安全系統(tǒng)太復(fù)雜了,恐怕連合法用戶(hù)也難以進(jìn)入。另一方面,簡(jiǎn)單系統(tǒng)更容易理解,也更容易分析。
好的系統(tǒng)設(shè)計(jì)需要安全 有可能對(duì)安全進(jìn)行翻新嗎?答案是,這幾乎是不可能的。在很多情況下,翻新安全而不必重新設(shè)計(jì)系統(tǒng)的實(shí)質(zhì)性部分,可能是不現(xiàn)實(shí)的。
在幾乎所有的情況下,翻新的成本非常昂貴。因此,安全從來(lái)不應(yīng)是事后考慮的事情 -- 從一開(kāi)始它就必須是系統(tǒng)設(shè)計(jì)的不可分割的一部分。
計(jì)算機(jī)安全的基礎(chǔ)知識(shí) 了解這樣一些內(nèi)容是有用的:計(jì)算機(jī)安全的防御對(duì)象、相應(yīng)的防御機(jī)制,以及與計(jì)算機(jī)安全有關(guān)的不同術(shù)語(yǔ)。 威脅 威脅 -- 對(duì)計(jì)算機(jī)安全的攻擊 -- 大致可以分為以下幾類(lèi): 機(jī)密性攻擊:利用加密算法中的弱點(diǎn)或以其他方式,試圖竊取機(jī)密信息。
完整性攻擊:出于自私或惡意而試圖修改信息。應(yīng)該注意的是,完整性攻擊也可以是偶然的。
可用性攻擊:試圖中斷系統(tǒng)的正常運(yùn)行。可用性攻擊又稱(chēng)為 拒絕服務(wù) (DoS) 攻擊,后者是最近流行的術(shù)語(yǔ)。
對(duì)付高嚴(yán)重性暴露的技巧請(qǐng)遵循下列建議以避免高嚴(yán)重性靜態(tài)安全性暴露:限制對(duì)變量的訪問(wèn) 讓每個(gè)類(lèi)和方法都成為 final,除非有足夠的理由不這樣做 不要依賴(lài)包作用域 使類(lèi)不可克隆 使類(lèi)不可序列化 使類(lèi)不可逆序列化 避免硬編碼敏感數(shù)據(jù) 查找惡意代碼 限制對(duì)變量的訪問(wèn)如果將變量聲明為 public,那么外部代碼就可以操作該變量。
這可能會(huì)導(dǎo)致安全性暴露。影響 如果實(shí)例變量為 public,那么就可以在類(lèi)實(shí)例上直接訪問(wèn)和操作該實(shí)例變量。
將實(shí)例變量聲明為 protected 并不一定能解決這一問(wèn)題:雖然不可能直接在類(lèi)實(shí)例基礎(chǔ)上訪問(wèn)這樣的變量,但仍然可以從派生類(lèi)訪問(wèn)這個(gè)變量。清單 1 演示了帶有 public 變量的代碼,因?yàn)樽兞繛?public 的,所以它暴露了。
清單 1. 帶有 public 變量的代碼 class Test { public int id; protected String name; Test(){ id = 1; name = "hello world"; } //code}public class MyClass extends Test{ public void methodIllegalSet(String name){ this.name = name; // this should not be allowed } public static void main(String[] args){ Test obj = new Test(); obj.id = 123; // this should not be allowed MyClass mc = new MyClass(); mc.methodIllegalSet("Illegal Set Value"); }}建議 一般來(lái)說(shuō),應(yīng)該使用取值方法而不是 public 變量。按照具體問(wèn)題具體對(duì)待的原則,在確定哪些變量特別重要因而應(yīng)該聲明為 private 時(shí),請(qǐng)將編碼的方便程度及成本同安全性需要加以比較。
清單 2 演示了以下列方式來(lái)使之安全的代碼:清單 2. 不帶有 public 變量的代碼 class Test { private int id; private String name; Test(){ id = 1; name = "hello world"; } public void setId(int id){ this.id = id; } public void setName(String name){ this.name = name; } public int getId(){ return id; } public String getName(){ return name; }}讓每個(gè)類(lèi)和方法都為 final不允許擴(kuò)展的類(lèi)和方法應(yīng)該聲明為 final。這樣做防止了系統(tǒng)外的代碼擴(kuò)展類(lèi)并修改類(lèi)的行為。
影響 僅僅將類(lèi)聲明為非 public 并不能防止攻擊者擴(kuò)展類(lèi),因?yàn)槿匀豢梢詮乃约旱陌鼉?nèi)訪問(wèn)該類(lèi)。建議 讓每個(gè)類(lèi)和方法都成為 final,除非有足夠的理由不這樣做。
按此建議,我們要求您放棄可擴(kuò)展性,雖然它是使用諸如 Java 語(yǔ)言之類(lèi)的面向?qū)ο笳Z(yǔ)言的主要優(yōu)點(diǎn)之一。在試圖提供安全性時(shí),可擴(kuò)展性卻成了您的敵人;可擴(kuò)展性只會(huì)為攻擊者提供更多給您帶來(lái)麻煩的方法。
不要依賴(lài)包作用域沒(méi)有顯式地標(biāo)注為 public、private 或 protected 的類(lèi)、方法和變量在它們自己的包內(nèi)是可訪問(wèn)的。影響 如果 Java 包不是封閉的,那么攻擊者就可以向包內(nèi)引入新類(lèi)并使用該新類(lèi)來(lái)訪問(wèn)您想保護(hù)的內(nèi)容。
諸如 java.lang 之類(lèi)的一些包缺省是封閉的,一些 JVM 也讓您封閉自己的包。然而,您最好假定包是不封閉的。
建議 從軟件工程觀點(diǎn)來(lái)看,包作用域具有重要意義,因?yàn)樗梢宰柚箤?duì)您想隱藏的內(nèi)容進(jìn)行偶然的、無(wú)意中的訪問(wèn)。但不要依靠它來(lái)獲取安全性。
應(yīng)該將類(lèi)、方法和變量顯式標(biāo)注為 public、private 或 protected 中適合您特定需求的那種。使類(lèi)不可克隆克隆允許繞過(guò)構(gòu)造器而輕易地復(fù)制類(lèi)實(shí)例。
影響 即使您沒(méi)有有意使類(lèi)可克隆,外部源仍然可以定義您的類(lèi)的子類(lèi),并使該子類(lèi)實(shí)現(xiàn) java.lang.Cloneable。這就讓攻擊者創(chuàng)建了您的類(lèi)的新實(shí)例。
拷貝現(xiàn)有對(duì)象的內(nèi)存映象生成了新的實(shí)例;雖然這樣做有時(shí)候是生成新對(duì)象的可接受方法,但是大多數(shù)時(shí)候是不可接受的。清單 3 說(shuō)明了因?yàn)榭煽寺《┞兜拇a:清單 3. 可克隆代碼 class MyClass{ private int id; private String name; public MyClass(){ id=1; name="HaryPorter"; } public MyClass(int id,String name){ this.id=id; this.name=name; } public void display(){ System.out.println("Id ="+id+""+"Name="+name); }}// hackers code to clone the user classpublic class Hacker extends MyClass implements Cloneable { public static void main(String[] args){ Hacker hack=new Hacker(); try{ MyClass o=(MyClass)hack.clone(); o.display(); } catch( e){ e.printStackTrace(); } }}建議 要防止類(lèi)被克隆,可以將清單 4 中所示的方法添加到您的類(lèi)中:清單 4. 使您的代碼不可克隆 public final Object clone() throws java.lang.{ throw new java.lang.(); }如果想讓您的類(lèi)可克隆并且您已經(jīng)考慮了這一選擇的后果,那么您仍然可以保護(hù)您的類(lèi)。
要做到這一點(diǎn),請(qǐng)?jiān)谀念?lèi)中定義一個(gè)為 final 的克隆方法,并讓它依賴(lài)于您的一個(gè)超類(lèi)中的一個(gè)非 final 克隆方法,如清單 5 中所示:清單 5. 以安全的方式使您的代碼可克隆 public final Object clone() throws java.lang. { super.clone(); }類(lèi)中出現(xiàn) clone() 方法防止攻擊者重新定義您的 clone 方法。使類(lèi)不可序列化序列化允許將類(lèi)實(shí)例中的數(shù)據(jù)保存在外部文件中。
闖入代碼可以克隆或復(fù)制實(shí)例,然后對(duì)它進(jìn)行序列化。影響 序列化是令人擔(dān)憂(yōu)的,因?yàn)樗试S外部源獲取對(duì)您的對(duì)象的內(nèi)部狀態(tài)的控制。
這一外部源可以將您的對(duì)象之一序列化成攻擊者隨后可以讀取的字節(jié)數(shù)組,這使得攻擊者可以完全審查您的對(duì)象的內(nèi)部狀態(tài)。
HttpServletRequest request.getRemoteAddr()//獲取遠(yuǎn)程IP地址 HttpServletResponse response.setContentType("text/html;charset=gbk")//設(shè)置發(fā)送方式和字符集 response.getWriter();//獲取輸出對(duì)象,構(gòu)造PrintWriter對(duì)象 返回響應(yīng) 利用: 1) PrintWriter out = response.getWriter // 用于返回文本數(shù)據(jù)給客戶(hù)端 2) ServletOutputStream out = response.getOutputStream // 用于返回二進(jìn)制數(shù)據(jù)給客戶(hù)端 Servlet中從request獲得參數(shù)的方法: String getParameter(String); 有此參數(shù)但無(wú)值返回""; 無(wú)此參數(shù)則返回:null String[] getParameterValues(String); Map getParameterMap(); Enumeration getParameterNames();獲得的是參數(shù)的名字,需要用名字再去獲得參數(shù)的值 1)請(qǐng)闡述什么是ServletContext? 一種servlet服務(wù)的上下文,每一個(gè)servlet實(shí)例都對(duì)應(yīng)在一個(gè)web application中,都屬于這個(gè)上下文, 即為這個(gè)servletContext. 在一個(gè)servlet服務(wù)中,通過(guò)getServletContext()方法,獲得上下文;2) 如何在一個(gè)Servlet中調(diào)用另外一個(gè)Servlet;如何在兩個(gè)Servlet之間傳遞數(shù)據(jù) getServletContext().getRequestDispatcher("/xxxx/xxxx").forward(request,response); request.setAttribute("xxxx",xxxx);------>requeset.getAttribute("xxxx"); Servlet中的方法: init(ServletConfig);//初始化Servlet用 init中有異常則servlet直接被回收,無(wú)異常則繼續(xù)調(diào)用service()方法 覆蓋父類(lèi)init(ServletConfig)可能會(huì)出錯(cuò)(因?yàn)楦割?lèi)函數(shù)會(huì)對(duì)config做保存處理,以便以后使用),可以調(diào)用super(config)解決 service(request,response); //具體會(huì)調(diào)用HttpServlet的doGet,doPost(程序員在具體的servlet程序中覆蓋了)方法實(shí)現(xiàn)功能, destory();//銷(xiāo)毀servlet實(shí)例的時(shí)候調(diào)用 Servlet生命周期: 裝載,init(),service(),destory()Servlet中進(jìn)行頁(yè)面轉(zhuǎn)發(fā): getServletContext().getRequestDispatcher("/user/user_list.jsp").forward(request, response); 或者: response.sendRedirect(request.getContextPath() + "/find.do"); Request中g(shù)etContextPath、getServletPath、getRequestURI、request.getRealPath的區(qū)別//轉(zhuǎn)載假定你的web application 名稱(chēng)為news,你在瀏覽器中輸入請(qǐng)求路徑: ; charset=GBK"%>
下面簡(jiǎn)單列舉一下學(xué)習(xí)java的一個(gè)系統(tǒng)知識(shí)點(diǎn)的一些介紹():一:java基礎(chǔ)部分:java基礎(chǔ)的時(shí)候,有些知識(shí)點(diǎn)是非常重要的,比如循環(huán)系列。
For,while,do-while.這方面只要用心點(diǎn)基本沒(méi)什么難點(diǎn)。二:面向?qū)ο螅簅op面向?qū)ο蟮臅r(shí)候,偏重理論,相信這方面的文章也很多,可以多看看,在這就不說(shuō)了。
重點(diǎn)掌握面向?qū)ο蟮娜筇卣骱突驹怼H簀ava核心一:這方面主要偏重API,所以在學(xué)習(xí)了這章的時(shí)候,一定要對(duì)照API去學(xué)習(xí),多看API,主要就是方法多,string和集合的方法最為重要。
四:java核心二:主要講解了異常,線(xiàn)程和IO流,其實(shí)個(gè)人認(rèn)為重點(diǎn)掌握線(xiàn)程就行,對(duì)于流和異常多寫(xiě)就行,線(xiàn)程偏重理論也最為重要。五:oracle數(shù)據(jù)庫(kù)方面:建議學(xué)習(xí)數(shù)據(jù)庫(kù)的時(shí)候一定要端正態(tài)度,數(shù)據(jù)庫(kù)極為重要,本人當(dāng)時(shí)在學(xué)習(xí)這個(gè)的時(shí)候,一直以為數(shù)據(jù)庫(kù)只是為了增刪改查,故沒(méi)有認(rèn)真學(xué)習(xí),后期面試的時(shí)候吃了不少虧,因?yàn)楝F(xiàn)在軟件公司對(duì)數(shù)據(jù)庫(kù)的要求跟java一樣重要,基本都會(huì)單獨(dú)一張筆試題筆試數(shù)據(jù)庫(kù)。
六:JDBC/XML系列:JDBC主要是3個(gè)核心接口(Connection) (Statement) (ResultSet)的使用,在學(xué)習(xí)的時(shí)候,熟練運(yùn)用3接口,jdbc的原理也相當(dāng)重要,雖然后期學(xué)習(xí)了HIbernate之后,JDBC不需要再用,但其底層原理還是JDBC,而且現(xiàn)在很多軟件公司不一定會(huì)用到Hibernate框架,所以建議還是把“本”學(xué)好,XML:重點(diǎn)掌握解析互換的2個(gè)核心接口方法。七:HTML/CSS/JS:對(duì)于這個(gè),本人相當(dāng)糾結(jié),因?yàn)檫@個(gè)有點(diǎn)偏向于美工的意思,所以后期想從事后臺(tái)開(kāi)發(fā)的同學(xué)一般不會(huì)太重視,但是現(xiàn)在都是web項(xiàng)目,而且很多軟件公司并不是把許多這方面的事情交給美工(除非是那種有很高要求的靜態(tài)頁(yè)面),而且現(xiàn)在html代碼都是在jsp里面寫(xiě),所以建議還是好好學(xué)學(xué),因?yàn)楣静粫?huì)讓一個(gè)美工去專(zhuān)門(mén)為你寫(xiě)一些簡(jiǎn)單的html代碼,包括js!這章其實(shí)不難,就是屬性方法知識(shí)點(diǎn)比較多,多記記,多寫(xiě)寫(xiě),重在多練!八:Servlet/Jsp:如果想從事web和b/s開(kāi)發(fā)(現(xiàn)在基本都是web和b/s開(kāi)發(fā)),這章極為重要,服務(wù)器的訪問(wèn)以及配置。
tomcat的使用都在這一章,雖然后期struts框架的學(xué)習(xí)簡(jiǎn)化了servlet代碼的繁瑣性,但是你可知道現(xiàn)在有些公司只用servlet不用struts!即使用了框架技術(shù)也不一定是struts!servlet跟JDBC一樣都是“本”,而struts和Hibernate一樣都是封裝了它們而后簡(jiǎn)化代碼而已。所以只有把“本”學(xué)會(huì)了,就不怕框架的變化!jsp就不多說(shuō)了,如果你學(xué)習(xí)java這個(gè)就不會(huì)缺少!后期b/s項(xiàng)目頁(yè)面的布局以及功能就全靠它了。
九:Ajax/Jquery:當(dāng)初學(xué)習(xí)這個(gè)的時(shí)候,本人沒(méi)有用心去學(xué),然后結(jié)果就是本人在進(jìn)公司之后花了一個(gè)星期的時(shí)間練習(xí)jQuery!這個(gè)對(duì)于強(qiáng)化web服務(wù)器頁(yè)面的功能技術(shù)實(shí)在是強(qiáng)大.這個(gè)封裝了js對(duì)象的技術(shù),可以對(duì)jsp頁(yè)面元素進(jìn)行樣式的更改以及操作,想要玩好web項(xiàng)目,這個(gè)技術(shù)必須玩好!十:SSH:傳說(shuō)中的三大框架;Struts:前面已經(jīng)提到,這個(gè)框架技術(shù)主要是為了彌補(bǔ)servlet和jsp頁(yè)面之間交互的復(fù)雜性,可以有效的提高客戶(hù)端與服務(wù)器之間的交互。而且采用了MVC思想進(jìn)行改善減弱代碼之間的復(fù)雜性。
Hibernate:主要封裝了jdbc的核心功能,可以采用映射方式訪問(wèn)并操作數(shù)據(jù)庫(kù),一定程度上講是簡(jiǎn)化了程序代碼,但前面已經(jīng)提到,由于是框架,而框架是隨著時(shí)代而改變的,并且很多公司不一定用到這個(gè)框架,所以,只有掌握好JDBC的根本原理,才會(huì)更加理解這個(gè)框架。Spring框架:其實(shí)后期學(xué)框架知識(shí)大家都會(huì)覺(jué)得很無(wú)趣和乏味,因?yàn)榭蚣艿闹R(shí)都是理論很深的知識(shí)點(diǎn),spring主要是要完善代碼之間的耦合度,包括類(lèi)似工廠模式的對(duì)象自動(dòng)控制,AOP的事物日志管理等,都其實(shí)是為了減少程序員的工作量,但不得不說(shuō)是有很大的作用的,而且這個(gè)框架可以整合JDBC以及Hibernate,struts技術(shù),可以把所有的框架技術(shù)都整合在一起。
相當(dāng)于一塊主板把內(nèi)存,風(fēng)扇,cpu,顯卡都集中在一起。 前面所有的都是個(gè)人學(xué)習(xí)之中的一點(diǎn)感受,希望你也能有所感觸,主要想說(shuō)明的是前面的基礎(chǔ)一定要打好,對(duì)于學(xué)習(xí)方法的問(wèn)題也可以和大家聊一聊,本人在學(xué)習(xí)之初,由于面向?qū)ο蠛图弦恍├碚撦^深的知識(shí)點(diǎn)出現(xiàn),導(dǎo)致后期比較注重理論,最終在寫(xiě)實(shí)際項(xiàng)目的時(shí)候吃了苦頭,因?yàn)榇a量沒(méi)有跟上,即使理論都懂,但很多功能還是無(wú)法自己寫(xiě)出,所以要強(qiáng)調(diào)的是在注重理論的情況下一定要多寫(xiě)代碼,我的建議是在理論比較深刻的知識(shí)點(diǎn)面前,比如面向?qū)ο螅希€(xiàn)程這些知識(shí),多看點(diǎn)理論,而對(duì)于html,css以及API方法比較多的知識(shí)點(diǎn)的情況下,多寫(xiě)代碼。
總之,各50%最好!當(dāng)然,這就需要大家付出更多的時(shí)間和精力辛苦勤勞下了!其實(shí)java的學(xué)習(xí)還是要多練代碼,多思考,舉一反三,任何的知識(shí)點(diǎn)只要你認(rèn)真的去做,沒(méi)有拿不下的頑石,勤能補(bǔ)拙,相信自己,然后用功,你就勝利了。下面為提供部分本人整理的筆記:String的核心方法:字符串轉(zhuǎn)換整數(shù):Integer.parseInt(字符串變量);整數(shù)轉(zhuǎn)換字符串:String.valueOf(整型變量)日期轉(zhuǎn)字符串:new SimpleDateFormat().format(date類(lèi)型)返回字符串元素的字符長(zhǎng)度:length()方法Int IndexOf。
第2章 一切都是對(duì)象2.1 用句柄操縱對(duì)象2.2 必須創(chuàng)建所有對(duì)象2.2.1 保存在什么地方2.2.2 特殊情況:主類(lèi)型2.2.3 Java中的數(shù)組2.3 絕對(duì)不要清除對(duì)象2.3.1 作用域2.3.2 對(duì)象的作用域2.4 新建數(shù)據(jù)類(lèi)型:類(lèi)2.4.1 字段和方法2.5 方法、自變量和返回值2.5.1 自變量列表2.6 構(gòu)建Java程序2.6.1 名字的可見(jiàn)性2.6.2 使用其他組件2.6.3 static關(guān)鍵字2.7 我們的第一個(gè)Java程序2.8 注釋和嵌入文檔2.8.1 注釋文檔2.8.2 具體語(yǔ)法2.8.3 嵌入HTML2.8.4 @see:引用其他類(lèi)2.8.5 類(lèi)文檔標(biāo)記2.8.6 變量文檔標(biāo)記2.8.7 方法文檔標(biāo)記2.8.8 文檔示例2.9 編碼樣式2.10 總結(jié)2.11 練習(xí) 第3章 控制程序流程3.1 使用Java運(yùn)算符3.1.1 優(yōu)先級(jí)3.1.2 賦值3.1.3 算術(shù)運(yùn)算符3.1.4 自動(dòng)遞增和遞減3.1.5 關(guān)系運(yùn)算符3.1.6 邏輯運(yùn)算符3.1.7 按位運(yùn)算符3.1.8 移位運(yùn)算符3.1.9 三元if-else運(yùn)算符3.1.10 逗號(hào)運(yùn)算符3.1.11 字串運(yùn)算符+3.1.12 運(yùn)算符常規(guī)操作規(guī)則3.1.13 造型運(yùn)算符3.1.14 Java沒(méi)有“sizeof”3.1.15 復(fù)習(xí)計(jì)算順序3.1.16 運(yùn)算符總結(jié)3.2 執(zhí)行控制3.2.1 真和假3.2.2 if-else3.2.3 反復(fù)3.2.4 do-while3.2.5 for3.2.6 中斷和繼續(xù)3.2.7 切換3.3 總結(jié)3.4 練習(xí) 第4章 初始化和清除4.1 由構(gòu)建器保證初始化4.2 方法過(guò)載4.2.1 區(qū)分過(guò)載方法4.2.2 主類(lèi)型的過(guò)載4.2.3 返回值過(guò)載4.2.4 默認(rèn)構(gòu)建器4.2.5 this關(guān)鍵字4.3 清除:收尾和垃圾收集4.3.1 finalize()用途何在4.3.2 必須執(zhí)行清除4.4 成員初始化4.4.1 規(guī)定初始化4.4.2 構(gòu)建器初始化4.5 數(shù)組初始化4.5.1 多維數(shù)組4.6 總結(jié)4.7 練習(xí) 第5章 隱藏實(shí)施過(guò)程5.1 包:庫(kù)單元5.1.1 創(chuàng)建獨(dú)一無(wú)二的包名5.1.2 自定義工具庫(kù)5.1.3 利用導(dǎo)入改變行為5.1.4 包的停用5.2 Java訪問(wèn)指示符5.2.1 “友好的”5.2.2 public:接口訪問(wèn)5.2.3 private:不能接觸5.2.4 protected:“友好的一種”5.3 接口與實(shí)現(xiàn)5.4 類(lèi)訪問(wèn)5.5 總結(jié)5.6 練習(xí) 第6章 類(lèi)再生6.1 合成的語(yǔ)法6.2 繼承的語(yǔ)法6.2.1 初始化基礎(chǔ)類(lèi)6.3 合成與繼承的結(jié)合6.3.1 確保正確的清除6.3.2 名字的隱藏6.4 到底選擇合成還是繼承6.5 protected6.6 遞增開(kāi)發(fā)6.7 上溯造型6.7.1 何謂“上溯造型”?6.8 final關(guān)鍵字6.8.1 final數(shù)據(jù)6.8.2 final方法6.8.3 final類(lèi)6.8.4 final的注意事項(xiàng)6.9 初始化和類(lèi)裝載6.9.1 繼承初始化6.10 總結(jié)6.11 練習(xí) 第7章 多形性7.1 上溯造型7.1.1 為什么要上溯造型7.2 深入理解7.2.1 方法調(diào)用的綁定7.2.2 產(chǎn)生正確的行為7.2.3 擴(kuò)展性7.3 覆蓋與過(guò)載7.4 抽象類(lèi)和方法7.5 接口7.5.1 Java的“多重繼承”7.5.2 通過(guò)繼承擴(kuò)展接口7.5.3 常數(shù)分組7.5.4 初始化接口中的字段7.6 內(nèi)部類(lèi)7.6.1 內(nèi)部類(lèi)和上溯造型7.6.2 方法和作用域中的內(nèi)部類(lèi)7.6.3 鏈接到外部類(lèi)7.6.4 static內(nèi)部類(lèi)7.6.5 引用外部類(lèi)對(duì)象7.6.6 從內(nèi)部類(lèi)繼承7.6.7 內(nèi)部類(lèi)可以覆蓋嗎?7.6.8 內(nèi)部類(lèi)標(biāo)識(shí)符7.6.9 為什么要用內(nèi)部類(lèi):控制框架7.7 構(gòu)建器和多形性7.7.1 構(gòu)建器的調(diào)用順序7.7.2 繼承和finalize()7.7.3 構(gòu)建器內(nèi)部的多形性方法的行為7.8 通過(guò)繼承進(jìn)行設(shè)計(jì)7.8.1 純繼承與擴(kuò)展7.8.2 下溯造型與運(yùn)行期類(lèi)型標(biāo)識(shí)7.9 總結(jié)7.10 練習(xí) 第8章 對(duì)象的容納8.1 數(shù)組8.1.1 數(shù)組和第一類(lèi)對(duì)象8.1.2 數(shù)組的返回8.2 集合8.2.1 缺點(diǎn):類(lèi)型未知8.3 枚舉器(反復(fù)器)8.4 集合的類(lèi)型8.4.1 Vector8.4.2 BitSet8.4.3 Stack8.4.4 Hashtable8.4.5 再論枚舉器8.5 排序8.6 通用集合庫(kù)8.7 新集合8.7.1 使用Collections8.7.2 使用Lists8.7.3 使用Sets8.7.4 使用Maps8.7.5 決定實(shí)施方案8.7.6 未支持的操作8.7.7 排序和搜索8.7.8 實(shí)用工具8.8 總結(jié)8.9 練習(xí) 第9章 違例差錯(cuò)控制9.1 基本違例9.1.1 違例自變量9.2 違例的捕獲9.2.1 try塊9.2.2 違例控制器9.2.3 違例規(guī)范9.2.4 捕獲所有違例9.2.5 重新“擲”出違例9.3 標(biāo)準(zhǔn)Java違例9.3.1 RuntimeException的特殊情況9.4 創(chuàng)建自己的違例9.5 違例的限制9.6 用finally清除9.6.1 用finally做什么9.6.2 缺點(diǎn):丟失的違例9.7 構(gòu)建器9.8 違例匹配9.8.1 違例準(zhǔn)則9.9 總結(jié)9.10 練習(xí) 第10章 Java IO系統(tǒng)10.1 輸入和輸出10.1.1 InputStream的類(lèi)型10.1.2 OutputStream的類(lèi)型10.2 增添屬性和有用的接口10.2.1 通過(guò)FilterInputStream從InputStream里讀入數(shù)據(jù)10.2.2 通過(guò)FilterOutputStream向OutputStream里寫(xiě)入數(shù)據(jù)10.3 本身的缺陷:RandomAccessFile10.4 File類(lèi)10.4.1 目錄列表器10.4.2 檢查與創(chuàng)建目錄10.5 IO流的典型應(yīng)用10.5.1 輸入流10.5.2 輸出流10.5.3 快捷文件處理10.5.4 從標(biāo)準(zhǔn)輸入中讀取數(shù)據(jù)10.5.5 管道數(shù)據(jù)流10.6 StreamTokenizer10.6.1 StringTokenizer10.7 Java 1.1的IO流10.7.1 數(shù)據(jù)的發(fā)起與接收10.7.2 修改數(shù)據(jù)流的行為10.7.3 未改變的類(lèi)10.7.4 一個(gè)例子10.7.5 重定向標(biāo)準(zhǔn)IO10.8 壓縮10.8.1 用GZIP進(jìn)行簡(jiǎn)單壓縮10.8.2 用Zip進(jìn)行多文件保存10.8.3 Java歸檔(jar)實(shí)用程序10.9 對(duì)象串聯(lián)10.9.1 尋找類(lèi)10.9.2 序列化的控制10.9.3 利用“持久性”10.10 總結(jié)10.11 練習(xí) 第11章 運(yùn)行期類(lèi)型鑒定11.1 對(duì)RTTI的需要11.1.1 Class對(duì)象11.1.2 造型前的檢查11.2 RTTI語(yǔ)法11.3 反射:運(yùn)行期類(lèi)信息11.3.1 一個(gè)類(lèi)方法提取器11.4 總結(jié)11.5 練習(xí) 第12章 傳遞和返回對(duì)象12.1 傳遞句柄12.1.1 別名問(wèn)題12.2 制作本地副本12.2.1 按值傳遞12.2.2 克隆對(duì)象12.2.3 使類(lèi)具有克隆能力12.2.4 成功的克隆12.2.5 Object.clone()的效果12.2.6 克隆合成對(duì)象12.2.7 用Vector進(jìn)行深層復(fù)制12.2.8 通過(guò)序。
考試大整理Java技術(shù)知識(shí) 一、Java簡(jiǎn)介 Java是由美國(guó)Sun Microsystem,Inc。
開(kāi)發(fā)出來(lái)的一種面向?qū)ο蟮恼Z(yǔ)言,它已經(jīng)廣泛用于Internet 上以完成一些HTML無(wú)法完成的功能。Java有簡(jiǎn)單、穩(wěn)定、安全、界面友善等幾大特點(diǎn),而且對(duì)于UNIX,Macintosh或者PC機(jī)都能使用,這就是為什么Java如此受歡迎的原因了,Java是由C++衍生過(guò)來(lái)的,它的風(fēng)格和C++很相似,不過(guò)就和C++相比就簡(jiǎn)單得多 。
Java由于其指令和結(jié)構(gòu)都是十分嚴(yán)謹(jǐn)?shù)模沂菍?zhuān)門(mén)為不同環(huán)境些執(zhí)行所設(shè)計(jì),所以Java編寫(xiě)的程序遠(yuǎn)比C++要穩(wěn)定,而且改錯(cuò)也比較容易。在網(wǎng)絡(luò)上執(zhí)行程序時(shí),Java對(duì)安全性的保障具有非常嚴(yán)格的控制,尤其是對(duì)用戶(hù)端安全的保護(hù)以及規(guī)定都有詳盡而嚴(yán)格的規(guī)定。
二、Java的特點(diǎn) Java在運(yùn)行機(jī)理上和C++很相似,但是兩者也有很多差異: 1、Java不支持結(jié)構(gòu)和指針;在C/C++中,最靈活也是最頭疼的東東就是指針(一說(shuō)到這個(gè)玩意我就全身發(fā)冷),但是在JAVA中,為了保持它的平臺(tái)無(wú)關(guān)性,Java取消了指針。 2、自動(dòng)內(nèi)存管理和線(xiàn)索控制。
在C和C++中,內(nèi)存必須用free、malloc和其它許多內(nèi)存管理標(biāo)準(zhǔn)庫(kù)管理。因此,系統(tǒng)要了解何時(shí)分配、釋放內(nèi)存并且跟蹤所有的內(nèi)存使用情況是非常困難的。
如果要在C和C++中實(shí)現(xiàn)線(xiàn)索功能,必須使用一個(gè)可對(duì)線(xiàn)索進(jìn)行各種控制的類(lèi)庫(kù)。 而在Java中,盡管線(xiàn)索仍然需要類(lèi)的支持,但系統(tǒng)卻在語(yǔ)言級(jí)包括了線(xiàn)索同步機(jī)制。
3、Java具有內(nèi)嵌的內(nèi)存管理程序。一旦創(chuàng)建了一個(gè)對(duì)象,Java的運(yùn)行系統(tǒng)就開(kāi)始跟蹤這個(gè)對(duì)象,直到不再需要跟蹤該對(duì)象的所有引用為止。
當(dāng)某個(gè)對(duì)象不存在相應(yīng)的引用時(shí),Java把這個(gè)對(duì)象放到一個(gè)用于垃圾搜集的棧內(nèi)。 為在性能損失最小的情況下提供自動(dòng)垃圾搜集機(jī)制,這個(gè)垃圾搜集程序?qū)⒃诤笈_(tái)或作為低優(yōu)先級(jí)線(xiàn)索運(yùn)行。
這樣,Java的垃圾搜集軟件將在前臺(tái)線(xiàn)索的執(zhí)行期間抽空?qǐng)?zhí)行,或者在系統(tǒng)顯式提出需要使用那些被已經(jīng)死亡的類(lèi)所占用的內(nèi)存空間時(shí)執(zhí)行。 從后臺(tái)內(nèi)存管理程序可以很明顯地看出,多線(xiàn)索的確可以增強(qiáng)Java環(huán)境的相對(duì)性能。
鑒于多線(xiàn)索的重要性,Java在語(yǔ)言級(jí)提供了線(xiàn)索同步機(jī)制,使多線(xiàn)索成為一種內(nèi)嵌特性。Java 語(yǔ)言支持針對(duì)方法的同步修飾符,并通過(guò)該修飾符來(lái)指明線(xiàn)索的運(yùn)行順序。
此外,Java還能控制方法與實(shí)例變量的相互作用機(jī)制,確保了各方法之間在修改數(shù)據(jù)時(shí)不會(huì)產(chǎn)生沖突。 Java的內(nèi)存管理和線(xiàn)索支持還具有使Java語(yǔ)言簡(jiǎn)單化的作用。
正是由于把內(nèi)存管理任務(wù)嵌入到了Java環(huán)境,Java語(yǔ)言才可以取消指針數(shù)據(jù)類(lèi)型、malloc和free函數(shù)。這樣,程序員就可以把更多的時(shí)間化在真正的編程工作上,而不是去跟蹤調(diào)試與內(nèi)存使用相關(guān)的程序錯(cuò)誤。
正是由于其多線(xiàn)索機(jī)制,Java才可以為一個(gè)可移植的解釋系統(tǒng)提供較高的性能。 4、Java的編譯和C/C++大有不同,C/C++的編譯器是將源代碼編譯成某種處理器所能處理的機(jī)器碼,而Java編譯器只是將它編譯成一種臨時(shí)代碼,稱(chēng)為字節(jié)碼或虛擬機(jī)代碼,通過(guò)文件。
class進(jìn)行存儲(chǔ),運(yùn)行時(shí)通過(guò)Java虛擬機(jī)運(yùn)行,而不基于任何特定處理器。 三、Java在瀏覽器上的運(yùn)用 首先時(shí)網(wǎng)頁(yè)制作人員,在HTML代碼中寫(xiě)入標(biāo)記,在客戶(hù)端的瀏覽器遇到該標(biāo)志的時(shí)候,如果它與Java兼容的話(huà),就會(huì)下載相應(yīng)的類(lèi)文件,類(lèi)文件中裝的就是我們剛剛說(shuō)的字節(jié)碼,瀏覽器中的虛擬機(jī)根據(jù)客戶(hù)端的處理器將字節(jié)碼轉(zhuǎn)換為特定的機(jī)器碼,于是它就在這臺(tái)機(jī)器上執(zhí)行了。
Java 基本知識(shí)點(diǎn)概要1. 了解Java語(yǔ)言的特征,掌握J(rèn)DK(Java開(kāi)發(fā)工具包)的安裝、目錄層次、環(huán)境變量配置,Java程序的實(shí)現(xiàn)過(guò)程 a).J2SE 1.6( JDK1.5)的安裝:(推薦路徑) Jdk路徑: C:\Soft\JDK1.6 Jre路徑: C:\program files\Java\jre1.6.0\。
b).環(huán)境變量配置: 我的電腦--〉右擊屬性--〉高級(jí)--〉環(huán)境變量--〉新建 變量名 變量值Java_Home C:\Soft\JDK1.6Path %Java_Home%\binClassPath %Java_Home%\jre\lib\rt.jar;.c).編寫(xiě)Java源文件(Xxx.java)==>編譯成字節(jié)碼 (javac Xxx.java) ==>執(zhí)行字節(jié)碼文件 java Xxx 2.Java語(yǔ)言基礎(chǔ) a). 數(shù)據(jù)類(lèi)型: 8種基本類(lèi)型:byte,char,short,int,long,float,double,boolean 引用類(lèi)型: 數(shù)組, 類(lèi),接口 b).結(jié)構(gòu)化語(yǔ)句: if,if--else ,if--else if ,switch--case,while,do--while,for c).數(shù)組 int num[]={1,2,3,4,5}; <> int []num={1,2,3,4,5}; int num[]=new int[size]; int num[]=new int[]{1,2,3,4,5}; 3.面向?qū)ο蟮幕A(chǔ) a).類(lèi):具有相同屬性和行為的一組對(duì)象的集合 b).對(duì)象:客觀存在的或可被描述的抽象對(duì)象,具有特定屬性和行為的實(shí)體。 c).類(lèi)是對(duì)象的模板(原型),對(duì)象是類(lèi)的具體實(shí)例 d).抽象、封裝、繼承,多態(tài)(重載,重寫(xiě),接口多實(shí)現(xiàn)) e).構(gòu)造方法(默認(rèn)構(gòu)造器/參數(shù)化構(gòu)造器) f).限制訪問(wèn)修飾符: private,缺省(默認(rèn)),protected,public g).附加修飾符:final,static,abstract h).接口 4.Java 基礎(chǔ)包 a). java.lang : 包裝類(lèi)(Byte,Character,Short,Integer,Long,Float,Double,Boolean) 其它類(lèi):String,StringBuffer,Math,Class,Object b). java.util 隨機(jī)類(lèi):Random 日期類(lèi):Date,Calender 集合框架體系:Collection,List,Set,ArrayList,LinkedList,Vector,HashMap c). java.io 文件類(lèi):File 字節(jié)流:FileInputStream,FileOutputStream 字符流:FileReader,FileWriter,BufferedReader,BufferedWriter 二進(jìn)制流:(了解) DataInputStream,DataOutputStream 構(gòu)造鍵盤(pán)流:BufferedReader input=new BufferedReader(new InputStreamReader(System.in)); d). java.swt /javax.swing 容器類(lèi)組件:JFrame,JPanel,JScrollPane 組件: JLabel,JTextField,JPasswordField,JTextArea,JComboBox, JRadioButton,JCheckBox,JMenuBar,JMenu,JMenuItem 5.JDBC 數(shù)據(jù)庫(kù)連接 數(shù)據(jù)庫(kù)的連接步驟: 1). 加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)類(lèi): Class.forName(driver) 2). 通過(guò)驅(qū)動(dòng)程序管理器獲取連接: DriverManager.getConnection(url,user,password) 3). 基于連接對(duì)象建立處理器對(duì)象/預(yù)處理器對(duì)象 Statement stmt=conn.createStatement(); PreparedStatement stmt=conn.prepareStatement("insert into student values(?,?,?,?,?)"); 4). 處理器執(zhí)行SQL命令(Select/Insert/Update/Delete)executeQuery(Select) ==>返回查詢(xún)的結(jié)果集(ResultSet, ResultSet.getXXX(列編號(hào),從1開(kāi)始)) executeUpdate(Insert/Update/Delete) ==>返回執(zhí)行命令影響的記錄行(int) 5). 關(guān)閉各個(gè)對(duì)象 導(dǎo)入java.sql包 一、加載要連接數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序 Class.forName(driver) 注:Class.forName()方法將給定的類(lèi)加載到JVM,如果系統(tǒng)中不存在給定的類(lèi), 則會(huì)引發(fā)異常 二、通過(guò)驅(qū)動(dòng)程序管理器得到連接實(shí)例 Connection conn=DriverManager.getConnection(url,user,pwd); 注1:DriverManager類(lèi)跟蹤已注冊(cè)的驅(qū)動(dòng)程序,通過(guò)getConnection(URL)方法, 找到一個(gè)能夠連接至URL中指定的數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序,它接收三個(gè)參數(shù), 分別表示: 數(shù)據(jù)源的名稱(chēng)(類(lèi)型) 、用戶(hù)名(可選)、密碼(可選) 注2: 1). localhost 表示本機(jī),也可以用127.0.0.1 如果你連的不是本機(jī),可能通過(guò) 機(jī)器名 或 IP(192.111.113.100) 來(lái)連接 2). 1433是端口號(hào),SQL server默認(rèn)是1433 , 自己可以手工的改動(dòng)它 3). databasename后面跟你的數(shù)據(jù)庫(kù)的名稱(chēng),表示你要連接的數(shù)據(jù)庫(kù)是哪個(gè) 4). 最后是用戶(hù)名及密碼, 當(dāng)前可以訪問(wèn)該數(shù)據(jù)庫(kù)的用戶(hù)及密碼 注3:基于不同連接方式和不同類(lèi)型的數(shù)據(jù)源連接字符串如下: 1. Jdbc-Odbc橋 (SQLServer/Microsoft Access )數(shù)據(jù)庫(kù) 1.1 加載驅(qū)動(dòng)程序: Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 1.2 建立數(shù)據(jù)源(控制面板中配置數(shù)據(jù)源,MyDataSource是數(shù)據(jù)源名稱(chēng)) conn=DriverManager.getConnection("jdbc:odbc:MyDataSource"); 2. 直連SQLServer 驅(qū)動(dòng)程序: -- SQLServer 2000: 2.1 Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); 2.2 conn=DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433;dataBaseName=DBName","sa",""); -- SQLServer 2005: 3.1 Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); 3.2 conn=DriverManager.getConnection("jdbc:sqlserver://localhost:1433; dataBaseName=DBName","sa",""); -- 直連Access 驅(qū)動(dòng)程序: 4.1 加載驅(qū)動(dòng)程序: Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 4.2、不建立數(shù)據(jù)源 ,直接寫(xiě)連接字符串 conn=DriverManager.getConnection("jdbc:odbc:;Driver=Microsoft Access Driver (*.mdb);DBQ=Test.mdb"); 注: 1). DBQ后面指定的是要連接的Access 數(shù)據(jù)庫(kù) 2). Microsoft Access driver (*.mdb) 中。
編寫(xiě)安全的Internet應(yīng)用并不是一件輕而易舉的事情:只要看看各個(gè)專(zhuān)業(yè)公告板就可以找到連續(xù)不斷的安全漏洞報(bào)告。
你如何保證自己的Internet應(yīng)用不象其他人的應(yīng)用那樣滿(mǎn)是漏洞?你如何保證自己的名字不會(huì)出現(xiàn)在令人難堪的重大安全事故報(bào)道中?如果你使用Java Servlet 、JavaServer Pages(JSP)或者EJB,許多難以解決的問(wèn)題都已經(jīng)事先解決。 當(dāng)然,漏洞仍有可能出現(xiàn)。
下面我們就來(lái)看看這些漏洞是什么,以及為什么Java程序員不必?fù)?dān)心部分C和Perl程序員必須面對(duì)的問(wèn)題。 C程序員對(duì)安全漏洞應(yīng)該已經(jīng)很熟悉,但象OpenBSD之類(lèi)的工程提供了處理此類(lèi)問(wèn)題的安全系統(tǒng)。
Java語(yǔ)言處理這類(lèi)問(wèn)題的經(jīng)驗(yàn)要比C少20年,但另一方面,Java作為一種客戶(hù)端編程語(yǔ)言誕生,客戶(hù)端對(duì)安全的要求比服務(wù)器端苛刻得多。 它意味著Java的發(fā)展有著一個(gè)穩(wěn)固的安全性基礎(chǔ)。
Java原先的定位目標(biāo)是瀏覽器。然而,瀏覽器本身所帶的Java虛擬機(jī)雖然很不錯(cuò),但卻并不完美。
Sun的《Chronology of security-related bugs and issues》總結(jié)了運(yùn)行時(shí)環(huán)境的漏洞發(fā)現(xiàn)歷史。 我們知道,當(dāng)Java用作服務(wù)器端編程語(yǔ)言時(shí),這些漏洞不可能被用作攻擊手段。
但即使Java作為客戶(hù)端編程語(yǔ)言,重大安全問(wèn)題的數(shù)量也從1996年的6個(gè)(其中3個(gè)是相當(dāng)嚴(yán)重的問(wèn)題)降低到2000年的1個(gè)。不過(guò),這種安全性的相對(duì)提高并不意味著Java作為服務(wù)器端編程語(yǔ)言已經(jīng)絕對(duì)安全,它只意味著攻擊者能夠使用的攻擊手段越來(lái)越受到限制。
聲明:本網(wǎng)站尊重并保護(hù)知識(shí)產(chǎn)權(quán),根據(jù)《信息網(wǎng)絡(luò)傳播權(quán)保護(hù)條例》,如果我們轉(zhuǎn)載的作品侵犯了您的權(quán)利,請(qǐng)?jiān)谝粋€(gè)月內(nèi)通知我們,我們會(huì)及時(shí)刪除。
蜀ICP備2020033479號(hào)-4 Copyright ? 2016 學(xué)習(xí)鳥(niǎo). 頁(yè)面生成時(shí)間:3.621秒