Java容易混淆的基礎知識

      網友投稿 772 2022-05-30

      面向對象

      Java中容易混淆的基礎知識

      三大特性:

      繼承,封裝,多態

      封裝

      3中修飾符:public,private,protected,給位于同一個或不同包中的對象賦予了不同的訪問權限

      封裝的一些好處

      通過隱藏對象的屬性來保護對象內部的狀態

      提高代碼的可用性,可維護性

      提高模塊化

      繼承

      給對象提供從基類獲取字段和方法的能力,基礎提高代碼的重用性,可以在不修改類的情況下添加新的特性

      多態

      多態就是同一函數在不同類中有不同的實現;

      面向對象的多態性,即“一個接口,多個方法”。

      多態性體現在基類中定義的屬性和方法被子類繼承后,可以具有不同的屬性或表現方式。

      多態性允許一個接口被多個同類使用,彌補了單繼承的不足。

      final,finally,finalize的區別

      final

      final可以修飾類、變量、方法,修飾類表示該類不能被繼承、修飾方法表示該方法不能被重寫、修飾變量表示該變量是一個 常量不能被重新賦值。

      finally

      finally一般作用在try-catch代碼塊中,在處理異常的時候,通常我們將一定要執行的代碼放入finally代碼塊中,表示不管是 否出現異常,該代碼塊都會執行,一般用來存放一些關閉資源的代碼。

      finalize

      finalize是一個方法,屬于Object類的一個方法,而Object類是所有類的父類,該方法一般由垃圾回收器來調用,當我們調 用System.gc() 方法的時候,由垃圾回收器調用finalize(),回收垃圾,一個對象是否可回收的最后判斷。

      int和integer的區別

      int

      int是基本數據類型

      integer

      integer是其包裝類,是一個類

      為了在各種類型中轉換,通過各種方法調用

      int a = 0; String result = Integer.toString(a); //將int轉換為String

      重載與重寫的區別

      override重寫

      overload重載

      抽象類和接口的區別

      接口時公開的,不能有私有的方法和變量,

      抽象類可以有私有的方法或私有的變量

      抽象類和接口的區別

      反射的用途以及實現

      反射機制所提供的功能

      在運行時創造一個類的對象;

      判斷一個類所具有的成員變量和方法

      調用一個對象的方法

      生成動態代理

      Java反射的主要功能:

      確定一個對象的類

      取出類的modifiers,數據成員,方法,構造類,超類

      在運行時刻調用動態對象的方法.

      創建數組,數組大小和類型

      反射機制的理解和應用

      自定義注解的場景及實現

      登陸、權限攔截、日志處理,以及各種Java 框架,如Spring,Hibernate,JUnit 提到注解就不能不說反射,Java自定義注解是通過運行時靠反射獲取注解。實際開發中,例如我們要獲取某個方法的調用日志,可以通過AOP(動態代理機制)給方法添加切面,通過反射來獲取方法包含的注解,如果包含日志 注解,就進行日志記錄。

      http請求的get和post方式的區別

      原理區別

      一般我們在瀏覽器輸入一個網址訪問網站都是GET請求;再FORM表單中,可以通過設置Method指定提交方式為GET或者POST提交方式,默認為GET提交方式。

      HTTP定義了與服務器交互的不同方法,其中最基本的四種:GET,POST,PUT,DELETE,HEAD,其中GET和HEAD被稱為安全方法,因為使用GET和HEAD的HTTP請求不會產生什么動作。不會產生動作意味著GET和HEAD的HTTP請求不會在服務器上產生任何結果。但是安全方法并不是什么動作都不產生,這里的安全方法僅僅指不會修改信息。

      根據HTTP規范,POST可能會修改服務器上的資源的請求。比如CSDN的博客,用戶提交一篇文章或者一個讀者提交評論是通過POST請求來實現的,因為再提交文章或者評論提交后資源(即某個頁面)不同了,或者說資源被修改了,這些便是“不安全方法”。

      請求的區別

      GET方法會把名值對追加在請求的URL后面。因為URL對字符數目有限制,進而限制了用在 客戶端請求的參數值的數目。并且請求中的參數值是可見的,因此,敏感信息不能用這種方式傳遞。

      POST方法通過把請求參數值放在請求體中來克服GET方法的限制,因此,可以發送的參數的數目是沒有限制的。最后,通過POST請求傳遞的敏感信息對外部客戶端是不可見的。

      參考:get和post請求方式的區別

      seesion與cookie的區別

      cookie數據存放在客戶的瀏覽器上,session數據放在服務器上.

      cookie不是很安全,別人可以分析存放在本地的COOKIE并進行COOKIE欺騙考慮到安全應當使用session。

      設置cookie時間可以使cookie過期。但是使用session-destory(),我們將會銷毀會話。

      session會在一定時間內保存在服務器上。當訪問增多,會比較占用你服務器的性能考慮到減輕服務器性能方面,應當使用cookie。

      單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。(Session對象沒有對存儲的數據量的限制,其中可以保存更為復雜的數據類型)

      JDBC流程

      加載JDBC驅動程序:

      在連接數據庫之前,首先要加載想要連接的數據庫的驅動到JVM(Java虛擬機), 這通過java.lang.Class類的靜態方法forName(String className)實現。

      例如:

      try{ //加載MySql的驅動類 Class.forName("com.mysql.jdbc.Driver") ; }catch(ClassNotFoundException e){ System.out.println("找不到驅動程序類 ,加載驅動失敗!"); e.printStackTrace() ;

      成功加載后,會將Driver類的實例注冊到DriverManager類中。

      提供JDBC連接的URL

      連接URL定義了連接數據庫時的協議、子協議、數據源標識。書寫形式:協議:子協議:數據源標識

      協議:在JDBC中總是以jdbc開始 子協議:是橋連接的驅動程序或是數據庫管理系統名稱。數據源標識:標記找到數據庫來源的地址與連接端口。

      例如:

      jdbc:mysql://localhost:3306/test? useUnicode=true&characterEncoding=gbk;useUnicode=true;(MySql的連接URL)

      表示使用Unicode字符集。如果characterEncoding設置為 gb2312或GBK,本參數必須設置

      為true 。characterEncoding=gbk:字符編碼方式。

      創建數據庫的連接

      java.sql.DriverManager Connection

      代表一個數據庫的連接。

      使用DriverManager的getConnectin(String url , String username , String password )方法傳入指定的欲連接的數據庫的路徑、數據庫的用戶名和 密碼來獲得。

      例如: //連接MySql數據庫,用戶名和密碼都是root

      String url = "jdbc:mysql://localhost:3306/test" ; String username = "root" ; String password = "root" ; try{ Connection con = DriverManager.getConnection(url , username , password ) ; }catch(SQLException se){ System.out.println("數據庫連接失敗!"); se.printStackTrace() ;

      ? 要執行SQL語句,必須獲得java.sql.Statement實例,Statement實例分為以下3 種類型:

      1、執行靜態SQL語句。通常通過Statement實例實現。

      2、執行動態SQL語句。通常通過PreparedStatement實例實現。

      3、執行數據庫存儲過程。通常通過CallableStatement實例實現。具體的實現方式:

      Statement stmt = con.createStatement() ? PreparedStatement pstmt = con.prepareStatement(sql) ? CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ?

      執行SQL語句

      Statement接口提供了三種執行SQL語句的方法:executeQuery 、executeUpdate 和execute

      1、ResultSet executeQuery(String sqlString):執行查詢數據庫的SQL語句 ,返回一個結果集(ResultSet)對象。

      2、int executeUpdate(String sqlString):用于執行INSERT、UPDATE或 DELETE語句以及SQL DDL語句,如:CREATE TABLE和DROP TABLE等

      3、execute(sqlString):用于執行返回多個結果集、多個更新計數或二者組合的 語句。 具體實現的代碼:

      ResultSet rs = stmt.executeQuery(“SELECT * FROM …”) ? int rows =

      stmt.executeUpdate(“INSERT INTO …”) ? boolean flag = stmt.execute(String sql) ?

      處理結果

      兩種情況:

      1、執行更新返回的是本次操作影響到的記錄數。

      2、執行查詢返回的結果是一個ResultSet對象。

      ? ResultSet包含符合SQL語句中條件的所有行,并且它通過一套get方法提供了對這些 行中數據的訪問。

      ? 使用結果集(ResultSet)對象的訪問方法獲取數據:

      while(rs.next()){

      String name = rs.getString(“name”) ?

      String pass = rs.getString(1) ? // 此方法比較高效

      }

      (列是從左到右編號的,并且從列1開始)

      關閉JDBC對象

      操作完成以后要把所有使用的JDBC對象全都關閉,以釋放JDBC資源,關閉順序和聲 明順序相反:

      1、關閉記錄集

      2、關閉聲明

      3、關閉連接對象

      if(rs!=null){ // 關閉記錄集 try{ rs.close(); }catch(SQLException e){e.printStackTrace(); } }try{ stmt.close(); } }catch(SQLException e){e.printStackTrace(); } if(conn!=null){ // 關閉連接對象 try{ conn.close(); }catch(SQLException e){ e.printStackTrace();20} }

      MVC思想

      M:Model 模型

      V:View 視圖

      C:Controller控制器

      模型就是封裝業務邏輯和數據的一個一個的模塊,控制器就是調用這些模塊的(java中通常是 用Servlet來實現,框架的話很多是用Struts2來實現這一層),視圖就主要是你看到的,比如JSP 等.

      當用戶發出請求的時候,控制器根據請求來選擇要處理的業務邏輯和要選擇的數據,再返回去 把結果輸出到視圖層,這里可能是進行重定向或轉發等.

      equals 與 == 的區別

      值類型(int,char,long,boolean等)都是用==判斷相等性。對象引用的話,判斷引用所指的對象 是否是同一個。equals是Object的成員函數,有些類會覆蓋(override)這個方法,用于判 斷對象的等價性。例如String類,兩個引用所指向的String都是"abc",但可能出現他們實際對應的對象并不是同一個(和jvm實現方式有關),因此用 ==判斷他們可能不相等,但用equals判斷一定是相等的。

      線程

      創建線程的方法及實現

      Java中創建線程主要有三種方式:

      一、繼承Thread類創建線程類

      (1) 定義Thread類的子類,并重寫該類的run方法,該run方法的方法體就代表了線程要完成的任務。因此把run()方法稱為執行體。

      (2) 創建Thread子類的實例,即創建了線程對象。

      (3) 調用線程對象的start()方法來啟動該線程。

      package com.thread; public class FirstThreadTest extends Thread{ int i = 0; //重寫run方法,run方法的方法體就是現場執行體public void run() { for(;i<100;i++){ System.out.println(getName()+" "+i); } } public static void main(String[] args) { for(int i = 0;i< 100;i++) { System.out.println(Thread.currentThread().getName()+" "+i): if(i==20) { new FirstThreadTest().start(); new FirstThreadTest().start(); } } }

      二、通過Runnable接口創建線程類

      (1) 定義runnable接口的實現類,并重寫該接口的run()方法,該run()方法的方法體同樣是該線程的線程執行體。

      (2) 創建 Runnable實現類的實例的target來創建Thread對象,該

      Thread對象才是真正的線程對象。

      (3)調用線程對象的start()方法來啟動該線程

      package com.thread; public class RunnableThreadTest implements Runnable { private int i; public void run() { for(i = 0;i <100;i++) { System.out.println(Thread.currentThread().getName()+" "+i); } } public static void main(String[] args) { for(int i = 0;i < 100;i++) { System.out.println(Thread.currentThread().getName()+" "+i); if(i==20) { RunnableThreadTest rtt = new RunnableThreadTest(); new Thread(rtt,"新線程1").start(); new Thread(rtt,"新線程2").start(); } } } }

      三、通過Callable和Future創建線程

      (1) 創建Callable接口的實現類,并實現call()方法,該call()方法將作為線程執行體,并且有返回值。

      (2) 創建Callable實現類的實例,使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的call()方法的返回值。

      (3) 使用FutureTask對象作為Thread對象的target創建并啟動新線程。

      (4) 調用FutureTask對象的get()方法來獲得子線程執行結束后的返回值

      package com.thread; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class CallableThreadTest implements Callable { public static void main(String[] args) { CallableThreadTest ctt = new CallableThreadTest(); FutureTask ft = new FutureTask<>(ctt); 13 for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + " 的循 環變量i的值" + i); if (i == 20) { new Thread(ft, "有返回值的線程").start(); } } try { System.out.println("子線程的返回值:" + ft.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } @Override public Integer call() throws Exception 34 { int i = 0; for (; i < 100; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } return i; } }

      采用實現Runnable、Callable接口的方式創見多線程時,優勢是:

      線程類只是實現了 接口或 接口,還可以繼承其他類。

      在這種方式下,多個線程可以共享同一個target對象,所以非常適合多個相同線程來處理同 一份資源的情況,從而可以將CPU、代碼和數據分開,形成清晰的模型,較好地體現了面 向對象的思想。

      劣勢是:

      編程稍微復雜,如果要訪問當前線程,則必須使用Thread.currentThread()方法。

      使用繼承Thread類的方式創建多線程時優勢是:

      編寫簡單,如果需要訪問當前線程,則無需使用Thread.currentThread()方法,直接使用this 即可獲得當前線程。

      劣勢是:

      線程類已經繼承了Thread類,所以不能再繼承其他父類。

      sleep() 、join()、yield()的區別

      一、sleep()

      在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行),此操作受到系統計時器和調度 程序精度和準確性的影響。 讓其他線程有機會繼續執行,但它并不釋放對象鎖。也就是如 果有Synchronized同步塊,其他線程仍然不能訪問共享數據。注意該方法要捕獲異常

      比如有兩個線程同時執行(沒有Synchronized),一個線程優先級為MAX_PRIORITY,另一 個為MIN_PRIORITY,如果沒有Sleep()方法,只有高優先級的線程執行完成后,低優先級 的線程才能執行;但當高優先級的線程sleep(5000)后,低優先級就有機會執行了。

      總之,sleep()可以使低優先級的線程得到執行的機會,當然也可以讓同優先級、高優先級的 線程有執行的機會。

      二、join()

      Thread的非靜態方法join()讓一個線程B“加入”到另外一個線程A的尾部。在A執行完畢之前, B不能工作。

      保證當前線程停止執行,直到該線程所加入的線程完成為止。然而,如果它加入的線程沒有 存活,則當前線程不需要停止。

      三、yield()

      yield()方法和sleep()方法類似,也不會釋放“鎖標志”,區別在于,它沒有參數,即yield()方 法只是使當前線程重新回到可執行狀態,所以執行yield()的線程有可能在進入到可執行狀態 后馬上又被執行,另外yield()方法只能使同優先級或者高優先級的線程得到執行機會,這也 和sleep()方法不同。

      再給大家推薦一本書:Java并發編程想要電子版也可以私信我

      線程池的幾種方式

      newFixedThreadPool(int nThreads)

      創建一個固定長度的線程池,每當提交一個任務就創建一個線程,直到達到線程池的最大數 量,這時線程規模將不再變化,當線程發生未預期的錯誤而結束時,線程池會補充一個新的線程

      newCachedThreadPool()

      創建一個可緩存的線程池,如果線程池的規模超過了處理需求,將自動回收空閑線程,而當 需求增加時,則可以自動添加新線程,線程池的規模不存在任何限制

      newSingleThreadExecutor()

      這是一個單線程的Executor,它創建單個工作線程來執行任務,如果這個線程異常結束,會 創建一個新的來替代它;它的特點是能確保依照任務在隊列

      中的順序來串行執行

      newScheduledThreadPool(int corePoolSize)

      創建了一個固定長度的線程池,而且以延遲或定時的方式來執行任務,類似于Timer。

      private static final Executor exec=Executors.newFixedThreadPool(50); Runnable runnable=new Runnable(){ public void run(){ ... } } exec.execute(runnable); Callable callable=new Callable() { public Object call() throws Exception { return null; } } Future future=executorService.submit(callable); future.get(); // 等待計算完成后,獲取結果 future.isDone(); // 如果任務已完成,則返回 true future.isCancelled(); // 如果在任務正常完成前將其取消,則返回 true future.cancel(true); // 試圖取消對此任務的執行,true中斷運行的任務,false 允許正在運行的任務運行完成

      線程的生命周期

      新建(New)、就緒(Runnable)、運行(Running)、阻塞(Blocked)和死亡(Dead)5種狀態

      (1)生命周期的五種狀態

      新建(new Thread)

      當創建Thread類的一個實例(對象)時,此線程進入新建狀態(未被啟動)。

      例如:Thread t1=new Thread()?

      就緒(runnable)

      線程已經被啟動,正在等待被分配給CPU時間片,也就是說此時線程正在就緒隊列中排隊 等候得到CPU資源。例如:t1.start()?

      運行(running)

      線程獲得CPU資源正在執行任務(run()方法),此時除非此線程自動放棄CPU資源或者有 優先級更高的線程進入,線程將一直運行到結束。

      死亡(dead)

      當線程執行完畢或被其它線程殺死,線程就進入死亡狀態,這時線程不可能再進入就緒狀態 等待執行。

      自然終止:正常運行run()方法后終止

      異常終止:調用**stop()**方法讓一個線程終止運行

      堵塞(blocked)

      由于某種原因導致正在運行的線程讓出CPU并暫停自己的執行,即進入堵塞狀態。

      正在睡眠:用sleep(long t) 方法可使線程進入睡眠方式。一個睡眠著的線程在指定的時間過去可進入就緒狀態。

      正在等待:調用wait()方法。(調用motify()方法回到就緒狀態)

      被另一個線程所阻塞:調用suspend()方法。(調用resume()方法恢復)

      鎖機制

      線程安全

      線程安全是指要控制多個線程對某個資源的有序訪問或修改,而在這些線程之間沒有產生沖 突。

      在Java里,線程安全一般體現在兩個方面:

      1、多個thread對同一個java實例的訪問(read和modify)不會相互干擾,它主要體現在關 鍵字synchronized。如ArrayList和Vector,HashMap和Hashtable(后者每個方法前都有synchronized關鍵字)。如果你在interator一個List對象時,其它線程remove一個element, 問題就出現了。

      2、每個線程都有自己的字段,而不會在多個線程之間共享。它主要體現在java.lang.ThreadLocal類,而沒有Java關鍵字支持,如像static、transient那樣。

      volatle實現原理

      深入分析 Volatile 的實現原理

      悲觀鎖,樂觀鎖

      是一種思想。可以用在很多方面。比如數據庫方面。

      悲觀鎖就是for update(鎖定查詢的行)

      樂觀鎖就是 version字段(比較跟上一次的版本號,如果一樣則更新,如果失敗則要重復讀-

      比較-寫的操作。)

      JDK方面:

      悲觀鎖就是sync

      樂觀鎖就是原子類(內部使用CAS實現)

      本質來說,就是悲觀鎖認為總會有人搶我的。樂觀鎖就認為,基本沒人搶。

      樂觀鎖是一種思想,即認為讀多寫少,遇到并發寫的可能性比較低,所以采取在寫時先讀出 當前版本號,然后加鎖操作(比較跟上一次的版本號,如果一樣則更新),如果失敗則要重 復讀-比較-寫的操作。

      CAS是一種更新的原子操作,比較當前值跟傳入值是否一樣,一樣則更新,否則失敗。CAS頂多算是樂觀鎖寫那一步操作的一種實現方式罷了,不用CAS自己加鎖也是可以的。

      樂觀鎖的業務場景及實現方式

      每次獲取數據的時候,都不會擔心數據被修改,所以每次獲取數據的時候都不會進行加鎖, 但是在更新數據的時候需要判斷該數據是否被別人修改過。如果數據被其他線程修改,則不 進行數據更新,如果數據沒有被其他線程修改,則進行數據更新。由于數據沒有進行加鎖, 期間該數據可以被其他線程進行讀寫操作。

      樂觀鎖:比較適合讀取操作比較頻繁的場景,如果出現大量的寫入操作,數據發生沖突的可 能性就會增大,為了保證數據的一致性,應用層需要不斷的重新獲取數據,這樣會增加大量 的查詢操作,降低了系統的吞吐量。

      最后

      都看到這了,給孩子一個三連支持一下吧,

      Java對初學者很友好;

      Java資源豐富,因為它可以解決不同的問題;

      Java有一個龐大而友好的社區;

      Java無處不在,因此更容易找到第一份工作;

      Java開發人員缺口大,薪水很高。

      只要你具備能力,薪資待遇你敢要公司就敢給。

      Java 任務調度

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:實戰分布式系統 - python實現Multi-Paxos - 1
      下一篇:基于CSE的微服務架構實踐-輕量級架構技術選型
      相關文章
      亚洲1区2区3区精华液| 国产亚洲精久久久久久无码| 亚洲欧洲日产国码一级毛片| 日本亚洲色大成网站www久久| 亚洲成人免费网站| 亚洲成在人天堂在线| 亚洲国产精品高清久久久| 亚洲色偷拍另类无码专区| 亚洲开心婷婷中文字幕| 亚洲人色婷婷成人网站在线观看| 国产国拍亚洲精品福利| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 国产亚洲一区二区在线观看| 国产亚洲精品国看不卡| 国产亚洲成人在线播放va| 永久亚洲成a人片777777| 亚洲码国产精品高潮在线| 亚洲国产精品无码久久一区二区 | 亚洲一级毛片免费看| 亚洲男人的天堂久久精品| 亚洲人成www在线播放| 亚洲依依成人亚洲社区| 亚洲精品久久无码| 在线观看亚洲免费视频| 亚洲片国产一区一级在线观看| 亚洲综合国产精品第一页| 亚洲日韩欧洲无码av夜夜摸| 久久亚洲国产精品| 亚洲图片校园春色| 亚洲熟妇无码八V在线播放| 亚洲AV成人片无码网站| 亚洲狠狠爱综合影院婷婷| 一本色道久久综合亚洲精品| 亚洲av无码成h人动漫无遮挡 | 亚洲视频在线一区二区三区| 亚洲伦理一二三四| 亚洲欧美日韩综合俺去了| 国产精品亚洲а∨无码播放不卡 | 国产亚洲精品美女2020久久| 国产亚洲一区二区三区在线不卡| 亚洲精品乱码久久久久久蜜桃不卡|