夯實基礎系列一:Java 基礎總結

来源:https://www.cnblogs.com/huayonglun/archive/2018/09/19/9678205.html
-Advertisement-
Play Games

前言 大學期間接觸 Java 的時間也不短了,不論學習還是實習,都讓我發覺基礎的重要性。互聯網發展太快了,各種框架各種技術更新迭代的速度非常快,可能你剛好掌握了一門技術的應用,它卻已經走在淘汰的邊緣了。 而學習新技術總要付出一定的時間成本,那麼怎麼降低時間成本呢?那就是打好基礎,技術再怎麼革新,底層 ...


前言

大學期間接觸 Java 的時間也不短了,不論學習還是實習,都讓我發覺基礎的重要性。互聯網發展太快了,各種框架各種技術更新迭代的速度非常快,可能你剛好掌握了一門技術的應用,它卻已經走在淘汰的邊緣了。

而學習新技術總要付出一定的時間成本,那麼怎麼降低時間成本呢?那就是打好基礎,技術再怎麼革新,底層的東西也很少會變動,牢固的基礎會幫助你在各種新技術的學習中游刃有餘,快速上手。

因為我選擇的方向是後臺開發,所以談談我認為的基礎有哪些。其他方向肯定也有自己的體系,從低層到高層,可以自己摸索。後臺的話,我覺得網路知識,各種協議,web 知識,資料庫知識,Linux 基本操作以及自己選擇的後臺語言知識,這些是最基礎最需要牢固掌握的。

所以從今天起,會出一系列與後臺基礎相關的博文,一是對自己過去學習的一個總結,二是分享出來,希望可以幫助到需要的人。

概要

Java 基礎我做了 10 個方面的總結,包括基本概念,面向對象,關鍵字,基本類型與運算,字元串與數組,異常處理,Java 平臺與記憶體管理,分散式 Java 應用,多線程,IO。以下對這些內容做一些簡單的總結,同時我也有完整的思維導圖,博客上不方便展示,若有需要,聯繫我

Java 基礎大綱

細節

1. 基本概念

1.1 語言特點
  • 純面向對象
  • 平臺無關性
  • 內置類庫
  • 支持web
  • 安全性
    • 防止代碼攻擊
  • 健壯性
    • 強類型機制
    • 垃圾回收器
    • 異常處理
    • 安全檢查機制
  • 去除C++中難以理解易混淆的特性
1.2 與C++比較
  • 解釋編譯混合型語言,執行速度慢,跨平臺
  • 純面向對象,只有類,不存在全局變數或全局函數
  • 無指針,無多繼承,可多實現
  • 垃圾回收器自動管理記憶體
1.3 main函數知識
  • Java程式入口方法
  • 可由final,synchronized修飾,不能用abstract
1.4 Java程式初始化順序
  • 靜態優於非靜態
  • 父類優於子類
  • 按照成員變數的定義順序
  • 總共10個
1.5 作用域與可見性
  • 靜態變數屬於類
  • 局部變數屬於花括弧
  • 成員變數看下一條
  • public、protected、default、private 可見性依次遞減
1.6 構造函數
  • 與類名相同,無返回值
  • 可重載,不能被繼承,即不能被覆蓋
  • 參數個數任意
  • 伴隨new 一起調用,為系統調用
  • 完成對象的初始化工作
  • 子類可通過super顯式調用父類。父類沒有提供無參,子類必須顯式調用
  • 未定義,預設無參,修飾符取決於類修飾符
1.7 標識介面
  • 無任何方法聲明
  • 表示實現它的類屬於一個特定的類型
1.8 clone 方法
  • 實現Cloneable介面
  • 重寫Object類中的clone()
  • clone()中調用super.clone()
  • 把淺複製引用指向新的克隆體
1.9 反射
  • 定義:允許程式在運行時進行自我檢查,也允許對其內部成員進行操作
  • 功能
    • 得到一個對象所屬的類
    • 獲取一個類的所有成員和方法
    • 運行時創建對象
    • 在運行時調用對象的方法
  • 獲取類的方式
    • class.forName("類路徑")
    • 類名.class
    • 實例.getClass()
1.10 創建對象的四種方式
  • new
  • 反射機制
  • clone()
  • 反序列化
1.11 package 作用
  • 提供多層命名空間,解決命名衝突
  • 對類按功能進行分類,使項目組織更加清晰

2. 面向對象

2.1 與面向過程區別
  • 層次邏輯關係不同。
    • 面向對象是通過類的層次結構來體現類之間的繼承與發展
    • 面向過程是通過模塊的層次結構概括模塊與模塊間的關係與功能
  • 數據處理方式不同與控製程序方式不同
    • 面向對象是數據與操作封裝成一個整體,通過事件驅動來激活和運行程式
    • 面向過程是數據單獨存儲,控製程序方式上按照設計調用或返回程式
2.2 特性
  • 抽象
  • 繼承
  • 多態
  • 封裝
2.3 這種開發方式優點
  • 開發效率高。代碼重用
  • 保證軟體的魯棒性。經過長期測試的已有代碼
  • 保證軟體的高可維護性。設計模式成熟
2.4 繼承
  • 單繼承
  • 只能繼承父類的非私有成員變數和方法
  • 同名成員變數,子類覆蓋,不會繼承
  • 相同函數簽名,子類覆蓋,不會繼承
2.5 組合和繼承區別
  • 組合:在新類中創建原有類的對象。has a
  • 繼承是 is a
2.6 多態
  • 方法重載
    • 編譯時多態
  • 方法覆蓋
    • 運行時多態
  • 成員變數無多態概念
2.7 覆蓋和重載區別
  • 子父類關係,垂直;同類方法間關係,水平
  • 一對方法發生關係;多個方法發生關係
  • 參數列表相同;參數列表不同
  • 調用的方法根據對象的類型決定;根據調用時的實參表決定方法體
2.8 抽象類與介面異同

  • 不能被實例化
  • 介面的實現類實現了介面,抽象類的子類實現了方法,才能被實例化

  • 介面只能定義方法,不能實現;抽象類可以有定義和實現
  • 介面需要被實現;抽象類需要被繼承
  • 介面強調特定功能的實現;抽象類強調所屬關係
  • 介面成員變數預設為 public static final,成員方法 public abstract
  • 抽象類變數預設default,方法不能用 private、static、synchronized、native 修飾
2.9 內部類
  • 靜態內部類
    • static 修飾
    • 只能訪問外部類中的static數據
  • 成員內部類
    • 與實例綁定
    • 不可定義靜態屬性和方法
    • 外部實例化後,該內部類才能被實例化
  • 局部內部類
    • 代碼塊內
    • 不能被public、protected、private以及static修飾
    • 只能訪問final 局部變數
  • 匿名內部類
    • 無類名
    • 無構造函數,必須繼承或實現其他類
    • 原則
      • 無構造函數
      • 無靜態成員,方法和類
      • 不能是public、protected、private、static
      • 只能創建匿名內部類的一個實例
      • new 後面有繼承或實現
      • 特殊的局部內部類
2.10 如何獲取父類類名
  • 利用反射:obj.getClass().getSuperClass().getName()
  • 不使用super.getClass()原因:該方法在 Object中為final與native,子類不能覆蓋,返回此Object運行時類
2.11 this
  • 指向當前實例對象
  • 區分成員變數與方法形參
2.12 super
  • 訪問父類成員變數或方法
  • 子類同名會覆蓋,訪問父類只能通過super
  • 子類構造函數需顯示調用父類構造函數時,super()必須為構造函數的第一條語句

3. 關鍵字

3.1 變數命名
  • 英文字母
  • 數字
  • _和$
  • 不能包含空白字元
  • 首字元不能為數字
  • 保留字不能做標識符
  • 區分大小寫
3.2 assert
  • 軟體調試
  • 運行時開啟 -ea
3.3 static
  • 特定類的統一存儲空間,類綁定
  • 成員變數:屬於類,記憶體中只有一個複製
  • 成員方法:調靜態數據。可實現單例模式
  • 代碼塊:初始化靜態變數,只被執行一次
  • 內部類:不能與外部類重名,只能訪問外部類靜態數據(包括私有)
3.4 switch
  • 多分支選擇
  • 整型或字元類型變數或整數表達式
  • Java 7 開始支持 String。原理是String的hashCode()返回的int類型值匹配
3.5 volatile
  • 保證線程間的可見性
  • 從記憶體中取數據,而不是緩存
  • 不保證原子性
3.6 instanceof
  • 二元運算符
  • 判斷一個引用類型的變數所指向的對象是否是一個類的實例
  • 即左邊對象是否是右邊類的實例
3.7 strictfp
  • 精確浮點
  • 確保浮點運算的準確性
  • 若不指定,結果依賴於虛擬機平臺
  • 指定後依賴於統一標準,保證各平臺的一致性
3.8 null
  • 不是合法的Object實例
  • 無記憶體
  • 表明該引用目前沒有指向任何對象

4. 基本類型與運算

4.1 基本數據類型
  • int長度
    • byte(8 bit)
    • short(16 bit)
    • int(32 bit)
    • long(64 bit)
  • float長度
    • 單精度(32 bit float)
    • 雙精度(64 bit double)
  • boolean 類型變數的取值
    • true
    • false
  • char數據類型:Unicode字元(16 bit)
  • void:java.lang.Void 無法直接對其進行操作
4.2 不可變類
  • 實例創建後,值不可變
  • 所有的基本類型的包裝類+String
  • 優點
    • 使用簡單
    • 線程安全
    • 節省記憶體
  • 缺點:會因為值的不同而產生新的對象,導致無法預料的問題
4.3 類型轉換
  • 隱式類型轉換
    • 低精度到高精度
    • byte->short->char->int->long->float->double
  • 顯式類型轉換
    • 反之
    • 可能會損失精度
  • 類型自動轉換
    • 低到高
    • char類型會轉換為其對應的ASCII碼
    • byte、char、short參與運算自動轉為int,但"+=",不轉
    • 基本數據類型與boolean不能相互轉換
    • 多種類型混合運算,自動轉成容量最大類型
  • 運算符優先順序

      點   ()  []
      +(正)    -(負)        ++  --  ~   !
      *   /   %
      +(加)    -(減)
      <<  >>  >>>
      <   <=  >   >=  instanceof
      ==  !=
      &
      |
      ^
      &&
      ||
      ?:
      =   +=  -=  *=  /=  %=  &=       |= ^=  ~=  <<= >>= >>>=

5. 字元串與數組

5.1 字元串創建與存儲機制
  • 常量池
  • new String("abc")創建1個或2個對象
5.2 ==、equals和hashCode區別
  • == 比較引用,記憶體
  • 未覆蓋,同==;比較內容
  • hashCode鑒定對象是否相等,返回整數
5.3 String,StringBuffer,StringBuilder
  • String:不可變,執行效率最低
  • StringBuffer:可修改,線程安全,效率較高
  • StringBuilder:可修改,線程不安全,效率最高
5.4 其他
  • 數組初始化方式
  • length屬性和length()方法

6. 異常處理

6.1 finally塊執行時機
  • 若try中有return,在return前
  • 若try-finally或catch-finally中都有return,finally會覆蓋
6.2 finally代碼塊不是一定會被執行
  • 程式進入try之前出現異常
  • try中調用System.exit(0)
6.3 Error

嚴重錯誤,不可恢復

6.4 Exception
  • 可恢復,編譯器可捕捉
  • 檢查性異常
    • IO
    • SQL
  • 運行時異常
    • JVM處理
    • NullPointException
    • ClassCastException
    • ArrayIndexOutOfBoundsException
  • 出現異常後,一直往上層拋,直到遇到處理代碼或最上層
  • 多態。若先捕獲基類,再捕獲子類。子類處理代碼將永遠不會得到執行

7. Java平臺與記憶體管理

7.1 Java平臺與其他語言平臺的區別
  • 純軟體,包括JVM與JAVA API
  • JVM虛擬,不跨平臺
7.2 JAVA代碼的執行
  • 代碼編譯為class:sun jdk 中javac
  • 裝載class:ClassLoader
  • 執行class
    • 解釋執行
    • 編譯執行
      • client compiler
      • server compiler
7.3 java源碼編譯機制
  • 詞法分析器組件:Token流
  • 語法分析器組件:語法樹
  • 語義分析器組件:註解語法樹
    • 將語法樹中的名字、表達式等元素與變數、方法、類型等聯繫到一起
    • 檢查變數使用前是否已聲明
    • 推導泛型方法的類型參數
    • 檢查類型匹配性
    • 進行常量摺疊
    • 檢查所有語句都可到達
    • 檢查變數的確定性賦值
    • 解除語法糖
    • 將泛型JAVA轉成普通Java
    • 檢查所有checked exception都被捕獲或拋出
    • 將含語法糖的語法樹轉成簡單語法樹eg:foreach,自動摺疊
  • 代碼生成器組件:位元組碼
7.4 類載入機制
  • 裝載:全限定名+類載入器載入類
  • 鏈接
    • 校驗
      • 格式不符,拋VerifyError
      • 載入引用的類失敗:拋NoClassDefFoundError
    • 準備:靜態變數預設初始化
    • 解析:屬性、方法驗證(可選)
  • 初始化(不是類載入必須觸發的)
    • 靜態初始化代碼
    • 構造器代碼
    • 靜態屬性初始化
    • 觸發時機
      • 調用了new
      • 反射調用了類中的方法
      • 子類調用了初始化
      • JVM啟動過程中指定的初始化類
        • Bootstrap Class Loader:$JAVA_HOME/jre/lib/rt.jar
        • Extension Class Loader:$JAVA_HOME/jre/lib/ext/*.jar
        • System Class Loader:$CLASSPATH
        • User Defined Class Loader
7.5 類執行機制
  • 解釋執行
    • JVM位元組碼為中間代碼,由JVM在運行期對其解釋並執行
      • invokestatic
      • invokevirtual
      • invokeinterface
      • invokespecial
    • 基於棧
      • 代碼緊湊,體積小
      • 線程創建後,產生PC和Stack
      • 指令解釋執行
      • 棧頂緩存:棧頂值緩存在寄存器上
      • 部分棧幀共用
  • 編譯執行
    • client compiler
      • 輕量級,占記憶體少
      • 方法內聯
      • 去虛擬化
      • 冗餘消除
    • server compiler
      • 重量級,占記憶體多
      • 逃逸分析是C2進行很多優化的基礎
      • 標量替換:用標量替換聚合量
      • 棧上分配
        • 若對象未逃逸,C2會選擇在棧上直接創建Point對象實例,而不是在堆上
        • 棧上分配更快速,對象易回收
      • 同步消除:如果發現同步的對象未逃逸,那也沒有同步的必要。C2會去掉同步代碼塊
7.6 記憶體空間
  • 方法區:類信息,線程共用
    • 對象實例+數組
    • 分代管理
      • 新生代
      • 舊生代
  • 本地方法棧:支持native方法,Sun JDK的實現中本地方法棧和JVM方法棧是同一個
  • PC寄存器:線程私有
  • JVM方法棧:線程私有
7.7 記憶體分配
  • Java對象,堆上分配,分配需加鎖,開銷大
  • 當堆上空間不足-->GC-->仍不足-->拋OutOfMemory
  • Sun JDK 為新創建的線程在Eden上分配TLAB
  • 多個小對象比大對象分配更高效
  • 基於逃逸分析直接從棧上分配
7.8 記憶體回收
  • 收集器
    • 引用計數收集器
      • 計數器增減有消耗
      • 不適合迴圈引用
    • 跟蹤收集器
      • 集中式管理
      • 全局記錄數據的引用狀態
      • 從根集合掃描對象,可能會造成應用程式暫停
      • 三種實現演算法
        • 複製
          • 適用於回收空間中存活對象較少
          • 缺點:需要增加一塊空的記憶體空間及進行對象的移動
        • 標記-清除:會產生記憶體碎片
        • 標記-壓縮:不產生記憶體碎片
  • Sun JDK中可用GC
    • 新生代
      • 串列GC(Serial GC):複製演算法
        • Minor GC
        • 強軟弱虛
      • 並行回收GC(Parrallel Scavenge):掃描複製多線程
      • 並行 GC(ParNew):配合舊生代 CMS
    • 舊生代和持久代可用GC
      • 串列:標記壓縮+清除
      • 並行:標記壓縮
      • 併發:CMS
          1. 標記:暫停
          1. 併發標記:恢復,輪詢著色對象,以標記它們
          1. 重新標記:暫停
          1. 併發收集:恢復
        • CMS記憶體回收易產生碎片,但是它提供了整理碎片的功能
        • 浮動垃圾:CMS回收時產生應該回收但要等到下次CMS才能被回收掉的對象
  • Full GC
    • 對新生代舊生代及持久代都進行的GC
    • 觸發的四種情況
      • 舊生代空間不足
      • 持久代空間滿
      • CMS GC出現promotion failed和concurrent mode failure
      • 統計得到的Minor GC晉升到舊生代的平均大小大於舊生代的剩餘空間
7.9 記憶體泄露
  • 一個不再被程式使用的對象或變數還在記憶體中占有存儲空間
  • 符合垃圾回收標準
    • 對象賦空值null
    • 給對象賦予新值,重新分配了記憶體空間
  • 泄露的兩種情況
    • 堆中申請的空間沒有被釋放
    • 對象不再被使用,但仍然存活在記憶體中
  • 泄露原因
    • 靜態集合類
    • 各種連接
    • 監聽器
    • 變數不合理的作用域
    • 單例模式

8. 分散式Java應用

8.1 基於消息方式實現系統間的通信
  • TCP/IP+BIO
    • socket.setSoTimeOut()設置等待響應的超時時間
    • 一連接一線程
    • 缺點:無論連接是否真實,都要創建線程
    • BIO下伺服器端所能支撐的連接數目有限
  • TCP/IP+NIO
    • Channel
      • SocketChannel:建立連接,監聽事件,操作讀寫
      • ServerSocketChannel:監聽埠,監聽連接事件
    • Selector:獲取是否要處理的事件
    • Buffer:存放處理的數據
    • NIO Reactor模式,通過註冊感興趣的事件及掃描是否有感興趣的事件發生,從而做出相應的動作
    • 多個請求,連接復用
    • 只有在有真實的請求時,才會創建線程
    • 一請求一線程
  • UDP/IP+BIO
    • DatagramSocket:負責監聽埠,讀寫數據
    • DatagramPacket:作為數據流對象進行傳輸
  • UDP/IP+NIO
    • DatagramChannel:監聽埠,進行讀寫
    • ByteBuffer:數據流傳輸
  • NIO好處:只在有流要讀取或可寫入流時才做出相應的IO操作,而不像BIO方式阻塞當前線程
8.2 基於遠程調用方式實現系統間的通信
  • 遠程調用方式
    • 系統間通信和系統內一樣
    • 讓使用者感覺調用遠程同調用本地一樣
  • 基於Java自身技術
    • RMI:客戶端代理,stub,封裝對象,序列化為流,TCP/IP BIO,Skeleton,反序列化,獲取對象實例,調用
    • WebService
        1. 服務端的服務生成WSDL文件
        1. 將應用+WSDL文件放入HTTP伺服器
        1. 借用Java輔助工具根據WSDL文件生成客戶端stub代碼
        1. stub將產生的對象請求信息封裝為標準化的SOAP格式數據,併發請求到伺服器端
        1. 服端在接收到SOAP格式數據時進行轉化,反射調用相應的Java類
      • SOAP優點支持跨語言,缺點對複雜對象結構難支持
8.3 基於開源框架
  • Spring RMI

9. 多線程

9.1 線程資源同步機制
  • JVM保證以下操作順序
    • 同一線程操作
    • 對於main Memory 上的同一個變數的操作
    • 對於加了鎖的main Memory上的對象操作
  • 為避免資源操作的臟數據問題,JVM提供了
    • synchronized
    • volatile
    • lock/unlock
    • 目的是控制資源競爭
9.2 線程交互機制
  • 基於Object的wait/notify/notifyAll
    • 為避免假喚醒,需要double check
    • 調用對象的wait-->wait sets--->釋放鎖--->其他線程notify---->wait sets---->執行此對象線程--->刪除sets中此線程
  • 基於JDK 5 併發包,支持線程交互
    • Semphore的acquire,release
    • Condition的await,signal
    • CountDownLatch的await和countDown
9.3 線程狀態
  • New
  • Runnable
  • Running
  • Wait
  • TimedWait
  • Blocked
  • Terminated
9.4 sleep()與wait()方法的區別
  • sleep
    • 暫停一段時間執行
    • Thread的靜態方法
    • 不釋放鎖
    • 需要捕獲異常
  • wait
    • 使線程暫停執行
    • Object方法,用於線程間通信
    • 釋放鎖
9.5 守護線程
  • 後臺提供服務
  • 用戶線程全部終止,只剩下守護線程時,JVM就會退出
  • 調用start()之前,調用線程對象的setDaemon(true)
9.6 join
  • 調用該方法的線程在執行完run()後,再執行join方法後面的代碼
  • 線程合併,實現同步功能

10. IO

10.1 流本質
  • 數據傳輸
10.2 流分類
  • 位元組流:不使用緩存
  • 字元流
    • 碼表映射
    • 使用緩存
10.3 裝飾者模式
  • 運行時動態給對象增加額外的職責
  • 是你還有你,一切拜托你
  • FilterInputStream
10.4 Java Socket
  • ServerSocket server = new ServerSocket(2000);
  • Socker socket = server.accept();
  • 客戶端:Socket socket = new Socket("localhost",2000);
10.5 NIO
  • Channel--Selector--Buffer
  • 反應器模式
10.6 序列化
  • 對象持久化方式
  • 解決在對對象流進行讀寫操作時引發的問題
  • 對象寫進流里進行網路傳輸,保存到文件,資料庫
10.7 如何實現序列化
  • 實現Serializable介面
  • 使用FileOutputStream來構造ObjectOutputStream對象
  • 使用該對象的writeObject(obj)方法將對象寫出
  • 要恢復時,使用對應的輸入流
10.8 序列化特點
  • 一個類能被序列化,它的子類也能被序列化
  • static代表類成員,transient代表臨時數據。均不能被序列化
  • 序列化影響性能,需要才使用
  • 需要通過網路來發送對象,或對象的狀態需要被持久化到資料庫或文件中
  • 序列化能實現深複製,即可以複製引用的對象
10.9 反序列化
  • 將流轉化為對象
  • UID最好自己定義。優點
    • 提高程式運行效率。省去計算過程
    • 提高程式不同平臺相容性。不同計算方式,反序列化失敗
    • 增強程式各個版本的可相容性。加入新屬性,預設UID變化
10.10 外部序列化
  • 實現Externalizable介面控制

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Python基礎:print & input & 變數 & 運算符 & Python數據類型 & 運算符與表達式 Python 基礎 1 註釋 單行註釋 多行註釋 三個單引號'''括起來 三個雙引號"""括起來 print 輸出 作用:列印到屏幕上一些信息 可以接受多個字元串,用逗號分隔,遇到逗號會 ...
  • 本文主要記錄springboot中配置RestTemplate。 ...
  • 本文主要介紹如何在一個springboot項目配置兩個數據源(mysql和oracle)。 ...
  • 在數組中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007 1.數組歸併排序 2.歸併排序比較左右兩個堆數組中的元素大小時,進行計數,倒著比較,因為左堆倒第... ...
  • input()函數1.等待輸入;2.將輸入的內容賦值給了等於號前面的變數;3.input返回的數據類型是str。 ...
  • 之前裝好tomcat後正常運行 後來重裝系統後,又一次配置環境時卻報錯。 在網上查找了兩篇文章。 https://blog.csdn.net/haleyliu123/article/details/68953796 https://blog.csdn.net/qq_28688909/article/ ...
  • 電腦處理不同的數據需要定義不同的數據類型。改變數字數據類型的值,意味著要重新分配記憶體空間用來存儲新的數值。 int,整數包含正整數和負整數,32位和64位系統的取值範圍不同。32位系統的取值範圍:-2**31 ~ 2**31-164位系統的取值範圍:-2**63 ~ 2**63-1 long,長整 ...
  • 上篇我們知道了關於python的一個hello world的簡單程式代碼,現在我們來瞭解關於python裡面的變數,我們來瞭解下,變數是什麼? 變數:變數是為了存儲程式運算過程中的一些中間結果,為了方便之後的調用,同一變數可以重新賦值。 變數的特點:具有描述性的標記,存儲在記憶體里。 我們來看個列子, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...