日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

码出高效

發(fā)布時(shí)間:2023/12/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 码出高效 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

碼出高效

    • 一.計(jì)算機(jī)基礎(chǔ)
      • 1.1 0和1的世界
        • 原碼,反碼,補(bǔ)碼
        • 為什么出現(xiàn)反碼,補(bǔ)碼
        • 位運(yùn)算
      • 1.2 浮點(diǎn)數(shù)
      • 1.3 字符集與亂碼
      • 1.4 CPU與內(nèi)存
      • 1.5 TCP/IP
      • 1.6 信息安全
    • 二.面向?qū)ο?/li>
      • 2.1 OOP理念
      • 2.2 初識Java
      • 2.3 類
      • 2.4 方法
    • 三.代碼風(fēng)格
      • 3.1 命名規(guī)約
        • 3.1.1 常量
        • 3.1.2 變量
      • 3.2 代碼展示風(fēng)格
        • 3.2.1 縮進(jìn),空格與空行
        • 3.2.2 換行與高度
        • 3.2.3 控制語句
    • 四 走進(jìn)JVM
      • 4.1 字節(jié)碼
      • 4.2 類加載過程
      • 4.3 內(nèi)存布局
      • 4.4 對象實(shí)例化
      • 4.5 垃圾回收
    • 異常與日志
      • 5.1 異常分類
      • 5.2 try 代碼塊
      • 5.3 異常的接與拋
      • 5.4 日志
        • 5.4.1 日志規(guī)范
        • 5.4.2 日志框架

一.計(jì)算機(jī)基礎(chǔ)

1.1 0和1的世界

原碼,反碼,補(bǔ)碼

  • 原碼
    原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其余位表示值.
  • 反碼
    反碼的表示方法是:
    正數(shù)的反碼是其本身
    負(fù)數(shù)的反碼是在其原碼的基礎(chǔ)上, 符號位不變,其余各個位取反.
  • 補(bǔ)碼
    補(bǔ)碼的表示方法是:
    正數(shù)的補(bǔ)碼就是其本身
    負(fù)數(shù)的補(bǔ)碼是在其原碼的基礎(chǔ)上, 符號位不變, 其余各位取反, 最后+1. (即在反碼的基礎(chǔ)上+1)
  • 為什么出現(xiàn)反碼,補(bǔ)碼

    將符號位參與運(yùn)算, 并且只保留加法的方法. 首先來看原碼:
    計(jì)算十進(jìn)制的表達(dá)式: 1-1=0
    1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2

    為了解決原碼做減法的問題, 出現(xiàn)了反碼:
    計(jì)算十進(jìn)制的表達(dá)式: 1-1=0
    1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0
    發(fā)現(xiàn)用反碼計(jì)算減法, 結(jié)果的真值部分是正確的. 而唯一的問題其實(shí)就出現(xiàn)在"0"這個特殊的數(shù)值上. 雖然人們理解上+0和-0是一樣的, 但是0帶符號是沒有任何意義的. 而且會有[0000 0000]原和[1000 0000]原兩個編碼表示0.

    補(bǔ)碼的出現(xiàn), 解決了0的符號以及兩個編碼的問題:
    1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]補(bǔ) + [1111 1111]補(bǔ) = [0000 0000]補(bǔ)=[0000 0000]原

    位運(yùn)算

    <<左移 >>右移 >>>無符號右移
    在左移<<與右移>>兩種運(yùn)算中,符號位均參與移動,除負(fù)數(shù)往右移動,高位補(bǔ)l 之外,其他情況均在空位處補(bǔ)0

    左移運(yùn)算由于符號位參與向左移動,在移動后的結(jié)果中,最左位可能是1 或者0,
    即正數(shù)向左移動的結(jié)果可能是正,也可能是負(fù),負(fù)數(shù)向左移動的結(jié)果同樣可能是正,
    也可能是負(fù)

    對于三個大于號的>>〉無符號向右移動(注意不存在<<<無符號向左移動的運(yùn)
    算方式),當(dāng)向右移動時(shí),正負(fù)數(shù)高位均補(bǔ)0 ,正數(shù)不斷向右移動的最小值是0 ,而
    負(fù)數(shù)不斷向右移動的最小值是l

    為何負(fù)數(shù)不斷地?zé)o符號向右移動的最小值是l 呢?在實(shí)際編程中,位移運(yùn)算僅作
    用于整型(32 位)和長整型(64 位)數(shù)上,假如在整型數(shù)上移動的位數(shù)是32 位,無
    論是否帶符號位以及移動方向,均為本身。因?yàn)橐苿拥奈粩?shù)是個mod 32 的結(jié)果,
    即35 >> 1 與3 5 ?33 是一樣的結(jié)果

    1.2 浮點(diǎn)數(shù)

    從數(shù)字時(shí)間的科學(xué)計(jì)數(shù)法映射到計(jì)算機(jī)世界的浮點(diǎn)數(shù)是,數(shù)值從十進(jìn)制改為二進(jìn)制,還要考慮內(nèi)存硬件設(shè)備的實(shí)現(xiàn)方式.在規(guī)格化表示上存在差異,稱謂有所改變,指數(shù)稱為"階碼",有效數(shù)字稱為"尾數(shù)",所以用戶存儲符號,階碼,尾數(shù)的二進(jìn)制位分別稱為符號位,階碼位,尾數(shù)位.

  • 符號位
    在最高二進(jìn)制位上分配l 位表示浮點(diǎn)數(shù)的符號,0 表示正數(shù),1 表示負(fù)數(shù)。
  • 階碼位
    在符號位右側(cè)分配8 位用來存儲指數(shù),
  • 尾數(shù)位
    最右側(cè)分配連續(xù)的23 位用來存儲有效數(shù)字,
  • 加減運(yùn)算
    在數(shù)學(xué)中,進(jìn)行兩個小數(shù)的加減運(yùn)算時(shí),首先要將小數(shù)點(diǎn)對齊,然后同位數(shù)進(jìn)行
    加減運(yùn)算。對兩個采用科學(xué)計(jì)數(shù)法表示的數(shù)做加減法運(yùn)算時(shí),為了讓小數(shù)點(diǎn)對齊就需
    要確保指數(shù)一樣。當(dāng)小數(shù)點(diǎn)對齊后,再將有效數(shù)字按照正常的數(shù)進(jìn)行加減運(yùn)算。

    在要求絕對精確表示的業(yè)務(wù)場景下,比如金融行業(yè)的貨幣表示,推薦使用整型存
    儲其最小單位的值,展示時(shí)可以轉(zhuǎn)換成該貨幣的常用單位,比如人民幣使用分存儲,
    美元使用美分存儲。在要求精確表示小數(shù)點(diǎn)n 位的業(yè)務(wù)場景下,比如圓周率要求存儲
    小數(shù)點(diǎn)后1000 位數(shù)字,使用單精度和雙精度浮點(diǎn)數(shù)類型保存是難以做到的,這時(shí)推
    薦采用數(shù)組保存小數(shù)部分的數(shù)據(jù)。在比較浮點(diǎn)數(shù)時(shí),由于存在誤差,往往會出現(xiàn)意料
    之外的結(jié)果,所以禁止通過判斷兩個浮點(diǎn)數(shù)是否相等來控制某些業(yè)務(wù)流程。在數(shù)據(jù)庫
    中保存小數(shù)時(shí),推薦使用decimal 類型,禁止使用float 類型和double 類型。因?yàn)檫@
    兩種類型在存儲的時(shí)候,存在精度損失的問題。

    1.3 字符集與亂碼

    在ASCII 碼中,有兩個特殊的控制字符10 和13 ,前者是LF 即“\n ”,后者是
    CR 即V”,在編碼過程中,代碼的換行雖然是默認(rèn)不可見的,但在不同的操{乍系統(tǒng)中’
    表示方式是不樣的。在UNIX 系統(tǒng)中,換行使用換行符“\n,在window系統(tǒng)中,
    換行使用"\r\n;在舊版macOS中,換行符使用回車符"/r",在新版macOS中使用
    與UNIX 系統(tǒng)豐目同的換行方式。前編碼環(huán)境使用換行方式是LF ,
    這也是推薦的換行方式,避免出現(xiàn)源碼在不同操作系統(tǒng)中換行顯示不同的情況。

    1.4 CPU與內(nèi)存

    CPU ( Central Processing Unit )是一塊超大規(guī)模的集成電路板,是計(jì)算機(jī)的核心
    部件,承載著計(jì)算機(jī)的主要運(yùn)算和控制功能,是計(jì)算機(jī)指令的最終解釋模塊和執(zhí)行模
    塊。硬件包括基板、核心、針腳,基板用來固定核心和針腳,針腳通過基板上的基座
    連接電路信號,CPU 核心的工藝極度精密,達(dá)到10 納米級別。CPU 的內(nèi)部結(jié)
    構(gòu)如圖 所示。

    內(nèi)存物理結(jié)構(gòu)由內(nèi)存芯片、電路板、控制芯片、相關(guān)支持模塊等組成,內(nèi)
    存芯片結(jié)構(gòu)比較簡單,核心是存儲單元,支持模塊是地址譯碼器和讀寫控制器,如圖所示。

    1.5 TCP/IP

    TCP/IP ( Transmission Control Protocol I Internet Protocol )中文譯為傳輸控制協(xié)
    議/因特網(wǎng)互聯(lián)協(xié)議,這個大家族里的其他知名協(xié)議還有HTTP, HTT陀、FTP、
    SMTP、UDP, ARP、PPP、IEEE 802.x 等。TCP/IP 是當(dāng)前流行的網(wǎng)絡(luò)傳輸協(xié)議框架,
    從嚴(yán)格意義上講它是一個協(xié)議族,因?yàn)門CP, IP 是其中最為核心的協(xié)議,所以就把
    該協(xié)議族稱為TCP/IP

    IP協(xié)議
    IP是面向無連接、無狀態(tài)的,沒有額外的機(jī)制保證發(fā)送的包是否有序到達(dá)。IP
    首先規(guī)定出IP 地址格式,該地址相當(dāng)于在邏輯意義上進(jìn)行了網(wǎng)段的劃分,給每臺計(jì)
    算機(jī)額外設(shè)置了一個唯一的詳細(xì)地址。既然鏈路層可以通過唯一的MAC 地址找到機(jī)
    器,為什么還需要通過唯的IP 地址再來標(biāo)識呢?簡單地說,在世界范圍內(nèi),不可
    能通過廣播的方式,從數(shù)以千萬計(jì)的計(jì)算機(jī)里找到目標(biāo)MAC 地址的計(jì)算機(jī)而不超時(shí)。

    連接池
    在客戶端與服務(wù)端之間可以事先創(chuàng)建若干連接并提
    前放置在連接池中,需要時(shí)可以從連接池直接獲取,數(shù)據(jù)傳輸完成后,將連接歸還至
    連接池中,從而減少頻繁創(chuàng)建和釋放連接所造成的開銷。例如,RPC 服務(wù)集群的注冊
    中心與服務(wù)提供方、消費(fèi)方之間,消息服務(wù)集群的緩存服務(wù)器和消費(fèi)者服務(wù)器之間,
    應(yīng)用后臺服務(wù)器和數(shù)據(jù)庫之間,都會使用連接池來提升性能。

    1.6 信息安全

    黑客與與安全
    現(xiàn)代黑客攻擊的特點(diǎn)是分布式、高流量、深度匿名
    互聯(lián)網(wǎng)企業(yè)都要建立一
    套完整的信息安全體系,遵循CIA 原則,即保密性(Confidentiality ) ,完整性(Integrity ),可用性(Availability )

    • 保密性。對需要保護(hù)的數(shù)據(jù)(比如用戶的私人信息等)進(jìn)行保密操作,無論
      是存儲還是傳輸,都要保證用戶數(shù)據(jù)及相關(guān)資源的安全。比如,在存儲文件
      時(shí)會進(jìn)行加密,在數(shù)據(jù)傳輸中也會通過各種編碼方式對數(shù)據(jù)進(jìn)行加密等。
    • 完整性。訪問的數(shù)據(jù)需要是完整的,而不是缺失的或者被篡改的,不然用戶
      訪問的數(shù)據(jù)就是不正確的。比如,在商場看中一個型號為NB 的手機(jī),但售
      貨員在包裝的時(shí)候被其他人換成了更便宜的型號為LB 的于機(jī),這就是我們
      所說的資源被替換了,也就是不滿足完整性的地方。在實(shí)際編寫代碼中,一
      定要保證數(shù)據(jù)的完整性,通常的做法是對數(shù)據(jù)進(jìn)行簽名和校驗(yàn)(比如MDS
      和數(shù)字簽名等)。
    • 可用性。服務(wù)需要是可用的。如果連服務(wù)都不可用,也就沒有安全這-說了。
      比如還是去商場買東西,如果有人惡意破壞商場,故意雇用大量水軍在商場
      的收銀臺排隊(duì),既不結(jié)賬也不走,導(dǎo)致其他人無法付款,這就是服務(wù)已經(jīng)不
      可用的表現(xiàn)。這個例子和常見的服務(wù)拒絕(Dos )攻擊十分相似。對于這種情況,
      通常使用訪問控制、限流等手段解決。

    SQL注入
    ( I )過濾異戶輸入?yún)?#xff06;中的阿彌字符,從而降低被SQL ,t入的風(fēng)險(xiǎn)。
    ( 2 )禁止通過字符南拼撞的SQL i吾旬,嚴(yán)恪使用參數(shù)綁定傳人的SQL 參數(shù)c
    ( 3 )合理使月數(shù)據(jù)庫擊可框豆、提供的防左入機(jī)制。

    XSS
    XSS 跨站腳本攻擊,即
    Cross-Site Scripting ,為了不幸日前端開發(fā)中層疊樣式表(css )的名字沖突,簡稱為
    XSSa XSS 是指黑客通過技術(shù)手段,向正常用戶請求的HTML 頁面中插入惡意腳本,
    從而可以執(zhí)行任意腳本。
    在防范xss 上,主要通過對用戶輸入數(shù)據(jù)做過濾或者轉(zhuǎn)義。比如Java 開發(fā)人
    員可以使用Jsoup 框架對用戶輸入字符串做xss 過濾,或者使用框架提供的工具
    類對用戶輸入的字符串做HTML 轉(zhuǎn)義,例如Spring 框架提供的HtmlUtils 。前端在
    瀏覽器展示數(shù)據(jù)時(shí),也需要使用安全的API 展示數(shù)據(jù),比如使用innerText 而不是
    innerHTML 。所以需要前、后端開發(fā)人員一同配合才能有效防范xss 漏洞。

    CSRF
    跨站請求偽造(Cross-Site Request Forgery ),簡稱CSRF ,也被稱為One-click
    Attack , !l.D 在用戶并不知惰的情況下,冒充用戶發(fā)起請求,在當(dāng)前已經(jīng)登錄的Web 應(yīng)
    用程序上執(zhí)行惡意操作,如惡意發(fā)帖、修改密碼、發(fā)郵件等。
    xss 是在正常用戶請求的HTML 頁面中執(zhí)行了黑客提供的惡意代碼,
    cs 盯是黑客直接盜用用戶瀏覽器中的登錄信息,冒充用戶去執(zhí)行黑客指定的操作。
    xss 問題出在用戶數(shù)據(jù)沒有過濾、轉(zhuǎn)義l cs 盯問題出在HTTP 接口沒有防范不受信
    任的調(diào)用。
    防范CSRF 漏洞主要通過以下方式,
    ( I ) CSRF Token 驗(yàn)證,利用瀏覽器的同源限制,在HTTP 接口執(zhí)行前驗(yàn)證頁面
    或者Cookie 中設(shè)置的Token ,只有驗(yàn)證通過才繼續(xù)執(zhí)行請求。
    ( 2 )人機(jī)交互,比如在調(diào)用上述網(wǎng)上銀行轉(zhuǎn)賬接口時(shí)校驗(yàn)短信驗(yàn)證碼。

    HTTPS
    ( I )瀏覽器向服務(wù)器發(fā)送請求,請求中包括瀏覽器支持的協(xié)議,并附帶一個隨
    機(jī)數(shù)。
    ( 2 )服務(wù)器收到請求后,選擇某種非對稱加密算法,把數(shù)字證書簽有公鑰、身
    份信息發(fā)送給瀏覽器,同時(shí)也附帶一個隨機(jī)數(shù)。
    ( 3 )瀏覽器收到后、驗(yàn)證證書的真實(shí)性,用服務(wù)器的公鋁發(fā)送握手信息給服務(wù)器。
    ( 4 )服務(wù)器解密后,使用主前的隨機(jī)數(shù)計(jì)算出,個對稱加密的密鑰,以此作為
    加密信息并發(fā)送。
    ( 5 )后續(xù)所有的信息發(fā)送都是以對稱加密方式進(jìn)行的。

    二.面向?qū)ο?/h2>

    2.1 OOP理念

    面向過程讓計(jì)算機(jī)有步驟地順次做件事情,是種過程化的敘事思維。但是在
    大型軟件開發(fā)過程中,發(fā)現(xiàn)用面向過程語言開發(fā),軟件維護(hù)、軟件復(fù)用存在著巨大的
    困難,代碼開發(fā)變成了記流水賬,久而久之就成為“面條”代碼,模塊之間互相輯合,
    流程互相穿插,往往牽發(fā)而動全身。面向?qū)ο筇岢鲆环N計(jì)算機(jī)世界里解決復(fù)雜軟件
    工程的方法論,拆解問題復(fù)雜度,從人類思維角度提出解決問題的步驟和方案。

    2.2 初識Java

    Java 語言擁有跨平臺、分布式、多線程、健壯性等主要特點(diǎn),是當(dāng)下比較主流的
    高級編程語言。它的類庫相當(dāng)豐富、功能強(qiáng)大、簡單易用,對開發(fā)者相當(dāng)友好,不僅
    吸收了C++的優(yōu)點(diǎn),還摒棄了其難以掌控的多繼承、指針等概念。Java 比較好地實(shí)
    現(xiàn)了面向?qū)ο罄碚?#xff0c;允許開發(fā)工程師以優(yōu)雅的思維方式處理復(fù)雜的編程場景。

    2.3 類

    類的定義
    類的定義由訪問級別、類型、類名、是否抽象、是否靜態(tài)、泛型標(biāo)識、繼承或?qū)?br /> 現(xiàn)關(guān)鍵字、父類或接口名稱等組成。類的訪問級別有public 和無訪問控制符,類型分
    為class 、interface 、en um 。

    接口與抽象類
    正如面向?qū)ο笏拇筇匦?#xff08;抽象、封裝、繼承、多態(tài))所述,定義類的過程就是抽
    象和封裝的過程,而接口與抽象類則是對實(shí)體類進(jìn)行更高層次的抽象,僅定義公共行
    為和特征。接口與抽象類的共同點(diǎn)是都不能被實(shí)例化,但可以定義引用變量指向?qū)嵗龑ο?br />

    內(nèi)部類
    在個.java 源文件中,只能定義一個類名與文件名完全致的公開類,使用
    public class 關(guān)鍵字來修飾。但在面向?qū)ο笳Z言中1 任何一個類都可以在內(nèi)部定義另外
    一個類,前者為外部類,后者為內(nèi)部類。內(nèi)部類本身就是類的一個屬性,與其他屬性
    定義方式一致。

    • 靜態(tài)內(nèi)部類,如static class StaticinnerC!ass {} ;
    • 成員內(nèi)部類,如:private class InstancelnnerC!ass {} ;
    • 局部內(nèi)部類,定義在方法或者表達(dá)式內(nèi)部,
    • 匿名內(nèi)部類,如:(new Thread(){} ).start()。

    訪問權(quán)限控制
    面向?qū)ο蟮暮诵乃枷胫痪褪欠庋b,只把有限的方法和成員公開給別人,這也是
    迪米特法則的內(nèi)在要求,使外部調(diào)用方對方法體內(nèi)的實(shí)現(xiàn)細(xì)節(jié)知道得盡可能少

    在定義類時(shí),推薦訪問控制級別從嚴(yán)處理.
    ( I )如果不允許外部直接通過new 創(chuàng)建對象,構(gòu)造方法必須是pnvale 。
    ( 2 )工具類不允許有p u b l ic 或default 構(gòu)造方法。
    ( 3 )類非s t a t ic 成員變雪并且與子類共享,必須是protected 。
    ( 4 )類非stat i c 成員變量并且僅在本類使用,必須是private 。
    ( 5 )類stat i c 成員變量如果僅在東類使用,必須是private o
    ( 6 )若是stat i c 成員變量,必須考慮是否為final o
    ( 7 )類成員方法只供類內(nèi)部調(diào)用,必須是private 。
    ( 8 )類成員方法只對繼承類公開,那么限制為protected

    this與super
    對象實(shí)例化時(shí),至少有條從本類出發(fā)抵達(dá)0 均ect 的通路,而打通這條路的兩
    個主要工兵就是thi s 和s uper

    類關(guān)系
    有關(guān)系的
    情況下,包括如下5 種類型,

    • [繼承]extends (is-a )。
    • [實(shí)現(xiàn)]implements (can-do)。
    • [組合]類是成員變量(contai ns - a )。
    • {聚合}類是成員變量(has-a)。
    • [依賴]import 類(use-a )

    序列化
    ( I ) Java 原生序列化
    Java 類通過實(shí)現(xiàn)Serializable 接口來實(shí)現(xiàn)該類對象的序列化,
    這個接口非常特殊,沒有任何方法,只起標(biāo)識作用。Java 序列化保留了對象類的元數(shù)
    據(jù)(如類、成員變量、繼承類信息等),以及對象數(shù)據(jù)等,兼容性最好,但不支持跨
    語言,而且性能一般

    實(shí)現(xiàn)Seri alizable 接口的類建議設(shè)置seria!VersionUID 字段值,如果不設(shè)置,那么
    每次運(yùn)行時(shí),編譯器會根據(jù)類的內(nèi)部實(shí)現(xiàn),包括類名、接口名、方法和屬性等來自
    動生成seria!Version UID 。如果類的源代碼有修改,那么重新編譯后seria!VersionUID
    的取值可能會發(fā)生變化。因此實(shí)現(xiàn)Serializable 接口的類一定要顯式地定義
    seria!Version UID 屬性值。修改類時(shí)需要根據(jù)兼容性決定是否修改serialVersionUID 值

    • 如果是兼容升級,請不要修改seria!VersionUID 字段,避免反序列化失敗。
    • 如果是不兼容升級,需要修改serialVersionUID 值,避免反序列化混亂。

    使用Java 原生序列化需注意,Java 反序歹lj化時(shí)不會調(diào)用類的無參構(gòu)造方法,而
    是調(diào)用native 方法將成員變量賦值為對應(yīng)類型的初始值。基于性能及兼容性考慮,不
    推薦使用Java 原生序列化

    ( 2 ) Hessian 序列化。
    Hessian 序列化是一種支持動態(tài)類型、跨語言、基于對象
    傳輸?shù)木W(wǎng)絡(luò)協(xié)議。Java 對象序列化的二進(jìn)制流可以被其他語言(如C++、Python )反
    序列化。Hessian 協(xié)議具有如下特性.

    • 自描述序列化類型。不依賴外部描述文件或接口定義,用一個字節(jié)表示常用基礎(chǔ)類型,極大縮短二進(jìn)制流。
    • 語言無關(guān),支持腳本語言。
    • 協(xié)議簡單,比Java 原生序列化高效。

    相比Hessian 1.0, Hessian 2.0 中增加了壓縮編碼,其序列化二進(jìn)制流大小是Java
    序列化的50% ,序列化耗時(shí)是Java 序列化的30 % ,反序列化耗時(shí)是Java 反序列化的
    20%

    Hessian 會把復(fù)雜對象所有屬性存儲在一個Map 申進(jìn)行序列化。所以在父類、子
    類存在同名成員變量的情況下,Hessian 序列化時(shí),先序列化子類,然后序列化父類,
    因此反序列化結(jié)果會導(dǎo)致子類同名成員變量被父類的值覆蓋。

    3 ) JSON 序列化
    JSON ( JavaScript Object Notation )是一種輕量級的數(shù)據(jù)交
    換格式。JSON 序列化就是將數(shù)據(jù)對象轉(zhuǎn)換為JSON 字符串。在序列化過程中拋棄了
    類型信息,所以反序列化時(shí)只有提供類型信息才能準(zhǔn)確地反序列化。相比前兩種方式,
    JSON 可讀性比較好,方便調(diào)試

    2.4 方法

    方法簽名
    方法簽名包括方法名稱和參數(shù)列表,是NM 標(biāo)識方法的唯一索引,不包括返回值,
    更加不包括訪問權(quán)限控制符、異常類型等。

    參數(shù)
    方法簽名包括方法名稱和參數(shù)列表,是NM 標(biāo)識方法的唯一索引,不包括返回值,
    更加不包括訪問權(quán)限控制符、異常類型等。
    無論是對于基本數(shù)據(jù)類型,還是引用變量,Java 中的參數(shù)傳遞都是值
    復(fù)制的傳遞過程。對于引用變量,復(fù)制指向?qū)ο蟮氖椎刂?#xff0c;雙方都可以通過自己的引
    用變量修改指向?qū)ο蟮南嚓P(guān)屬性。

    構(gòu)造方法
    構(gòu)造方法(Constructor )是方法名與類名相同的特殊方法,在新建對象時(shí)調(diào)用,
    可以通過不同的構(gòu)造方法實(shí)現(xiàn)不同方式的對象初始化,它有如下特征,
    ( I )構(gòu)造1J 沽名稱必示與吳兵相同。
    ( 2 )均圭方江主二沒有返國類在二吶,即使是void tli,-懷能有z 它返回對象的地址,
    并賦值給引用變量。
    ( 3 )枯l z 丁、-t: 吉~ t … ,’ .(…’ T 市被ff 弓. -.T ‘i「妒土I’" 調(diào)用途徑有三種
    一是通過new 關(guān)鍵字,二是在子類的構(gòu)造方法中通過super 調(diào)用父類的構(gòu)造方法,三
    是通過反射方式獲取并使用。
    ( 4 )吳王飛jj fo~ +「J 認(rèn)-~ ._送去均王元、去但是如果顯式定義了有參構(gòu)造方法,
    則此無參構(gòu)造方法就會被覆蓋,如果依然想擁有,就需要進(jìn)行顯式定義。
    ( 5 )均生于1 、主以和平外部無法使用私有構(gòu)造方法創(chuàng)建對象。

    類內(nèi)方法
    除構(gòu)造方法外,類中還可以有三類方法實(shí)例方法、
    靜態(tài)方法、靜態(tài)代碼塊。

    getter與setter
    在實(shí)例方法中有類特殊的方法,即ge憂er 與se憂er 方法,它們一般不包含任何
    業(yè)務(wù)邏輯,僅僅是為類成員屬性提供讀取和修改的方法,這樣設(shè)計(jì)有兩點(diǎn)好處I
    (!)滿足面向?qū)ο笳Z言封裝的特’生。盡可能將類中的屬性定義為private ,針對
    屬性值的訪問與修改需要使用相應(yīng)的getter 與se位er 方法,而不是直接對public 的屬
    性進(jìn)行讀取和修改。
    ( 2 )有利于統(tǒng)一控制。雖然直接對屬性進(jìn)行讀取、修改的方式和使用相應(yīng)的
    getter 與se憂er 方法在效果上是一樣的,但是前者難以應(yīng)對業(yè)務(wù)的變化。

    同步與異步
    同步調(diào)用是因剛性調(diào)用,是阻塞式操作,必須等待調(diào)用方法體執(zhí)行結(jié)束。而異步調(diào)
    用是柔性調(diào)用,是非阻塞式操作,在執(zhí)行過程中,如調(diào)用其他方法,自己可以繼續(xù)執(zhí)
    行而不被阻塞等待方法調(diào)用完畢。

    覆寫
    多態(tài)中的overri de ,本書翻譯成覆寫。如果翻譯成重寫,那么與重構(gòu)意思過于
    接近;如果翻譯成覆蓋,那么少了“寫”這個核心動詞。
    方法的覆寫可以總結(jié)成容易記憶的口訣“一大兩小兩同”。

    • 一大子類的方法訪問權(quán)限控制符只能相同或變大。
    • 兩小,拋出異常和返回值只能變小,能夠轉(zhuǎn)型成父類對象。子類的返回值、
      拋出異常類型必須與父類的返回值、拋出異常類型存在繼承關(guān)系。
    • 兩同i 方法名和參數(shù)必須完全相同。

    重載
    在同一個類中,如果多個方法有相同的名字、不同的參數(shù),即稱為重載,比如一
    個類中有多個構(gòu)造方法。JVM在重載方法中,選擇合適的目標(biāo)方法的順
    序如下

    泛型
    泛型的本質(zhì)是類型參數(shù)化,解決不確定具體對象類型的問題。在面向?qū)ο缶幊陶Z
    言中,允許程序員在強(qiáng)類型校驗(yàn)下定義某些可變部分,以達(dá)到代碼復(fù)用的目的。

    • 尖捂號里的每個元素都指代一種未知類型。
    • 尖括號的位置非常講究,必須在類目之后或方法返回值之前
    • 泛型在定義處只具備執(zhí)行Object方法的能力
    • 對于編譯之后的字節(jié)碼指令,其實(shí)沒有這些花頭花腦的方法簽名,充分說明泛型只是一種編寫代碼時(shí)的語法檢查

    數(shù)據(jù)類型

    I )對象頭(Object !leader )
    對象頭占用12 個字節(jié),存儲內(nèi)容包括對象標(biāo)記(markOop )和類元信息(klassOop )。
    對象標(biāo)記存儲對象本身運(yùn)行時(shí)的數(shù)據(jù),如哈希碼、GC 標(biāo)記、鎖信息、線程關(guān)聯(lián)信息等,
    這部分?jǐn)?shù)據(jù)在64 位NM 上占用8 個字節(jié),稱為"Mark word",為了存儲更多的狀
    態(tài)言息,對象標(biāo)記的存儲恪式是非固定的(具休與JVM 的實(shí)現(xiàn)有關(guān))。類元信患、存
    儲的是對象指向它的類元數(shù)據(jù)(即Kl ass )的首地址’占用4 個字節(jié),與refvar 開銷一致。
    ( 2 )實(shí)例數(shù)據(jù)(Instance Data )
    存儲本類對象的實(shí)例成員變量和所有可見的父類成員變量。如Integer 的實(shí)例
    成員只有一個private int value ,占用4 個字節(jié),所以加上對象頭為16 個字節(jié)1 再
    如,上述示例代碼的R巳fObjDemo 對象大小為48 個字節(jié),一個子類RefObjSon 繼承
    RefObjDemo ,即使子類內(nèi)部是空的,n ew RefObjSon 的對象也是占用48 個字節(jié)。
    ( 3 )對齊填充(Padding )
    對象的存儲空間分配單位是8 個字節(jié),如果一個占用大小為16 個字節(jié)的對象,
    增加一個成員變量byte 類型,此時(shí)需要占用17 個字節(jié),但是也會分配24 個字節(jié)進(jìn)
    行對齊填充操作。

    包裝類型
    ( I ) 所有的POJO 類屬性必須使用包裝數(shù)據(jù)類型
    ( 2 ) RPC 方法的返回值和參數(shù)必須使用包裝數(shù)據(jù)類型。
    ( 3 )所有的局部變量推薦使用基本數(shù)據(jù)類型。

    字符串
    字符串相關(guān)類型主要有三種String 、Strin gBuild 町、Strin gBuffer 。String 是只讀
    字符串,典型的immutabl e 對象,對它的任何改動,其實(shí)都是創(chuàng)建一個新對象,再把
    引用指向該對象。Strin g 對象賦值操作后,會在常量池中進(jìn)行緩存,如果下次申請創(chuàng)
    建對象時(shí),緩存中已經(jīng)存在,貝lj直接返回相應(yīng)引用給創(chuàng)建者。而StringBuffer 貝lj 可以
    在原對象上進(jìn)行修改,是線程安全的。JDK5 號|入的Str i ngBuilder 與StringBuffer 均繼
    承自AbstractStringBui Ider ,兩個子類的很多方法都是通過飛uper . 方法。”的方式調(diào)
    用抽象父類中的方法,此抽象類在內(nèi)部與String 一樣,也是以字符數(shù)組的形式存儲字
    符串的。StringBuilder 是非線程安全的,把是否需要進(jìn)行多線程加鎖交給工程師決定,
    操作效率比StringBuffer 高。線程安全的對象先產(chǎn)生是因?yàn)橛?jì)算機(jī)的發(fā)展總是從單線
    程到多線程,從單機(jī)到分布式。

    三.代碼風(fēng)格

    3.1 命名規(guī)約

    • 包名統(tǒng)使用小寫,點(diǎn)分隔符之間有且僅有個自然語義的英語單詞。包名
      統(tǒng)一使用單數(shù)形式,但是類名如果有復(fù)數(shù)含義,則可以使用復(fù)數(shù)形式。
    • 抽象類命名使用Abstract 或Base 開頭;異常類命名使用Exception 結(jié)尾,測
      試類命名以它要測試的類名開始,以Test 結(jié)尾。
    • 類型與中括號緊挨相連來定義數(shù)組。
    • 枚舉類名帶上Enum 后綴,枚舉成員名稱需要全大寫,單詞間用下畫線隔開

    3.1.1 常量

    • 采用字母全部大寫、單詞之間加下畫線的方式。而局部常量采用小駝峰形式即可。
    • 避免魔法值,幾乎是固定不變的全局常量采用枚舉,普通常量采用不能實(shí)例化的抽象類

    3.1.2 變量

    變量的命名需要滿足小駝峰格式,命名體現(xiàn)業(yè)務(wù)含義即可。存在一種特殊情況,在定義類成員變量時(shí),特別是在POJO 類中,針對布爾類型的變量,命名不要加is 前綴,否則部分框架解析會引起序列化錯誤。

    3.2 代碼展示風(fēng)格

    3.2.1 縮進(jìn),空格與空行

  • 縮進(jìn)
    采用4 個空恪的縮進(jìn)方式
  • 空格
    ( I )任何二目,三目運(yùn)算符的左右兩邊都必須加一個空格.
    ( 2 )注釋的雙斜線與注釋內(nèi)容之間有且僅有一個空恪。
    ( 3 )方法參數(shù)在定義和傳入時(shí),多個參數(shù)逗號后面必須加空格。
    ( 4 )沒有必要增加若干空格使變量的賦值等號與上一行對應(yīng)的位置的等號對齊
    ( 5 )如果大括號內(nèi)為空,則可以簡寫成{}即可, 大括號中間無需換行和空格
    ( 6 )左右小括號與括號內(nèi)部的相鄰字符之間不要出現(xiàn)空格.
    ( 7 ) 左大括號前需要加空格
  • 空行
    空行用來分隔功能相似、邏輯內(nèi)聚、意思相近的代碼片段,使得程序布局更加清
  • 3.2.2 換行與高度

  • 換行
    約定單行字符數(shù)不超過120 個,超出則需要換行,換行時(shí)遵循如下原則:
    ( I )第二行相對第一行縮進(jìn)4個空格,從第三行開始,不再繼續(xù)縮進(jìn),參考示例。
    ( 2 )運(yùn)算符與下文一起換行。
    ( 3 )方法調(diào)用的點(diǎn)符號與下文一起換行。
    ( 4 )方法調(diào)用中的多個參數(shù)需要換行時(shí),在逗號后換行。
    ( 5 )在括號前不要換行。
  • 方法行數(shù)限制
    約定單個方法的總行數(shù)不超過80 行
  • 3.2.3 控制語句

  • 在if,else,for,while,do-while等語句中必須使用大括號.
  • 在條件表達(dá)式中不允許有賦值操作,也不允許在判斷表達(dá)式中出現(xiàn)復(fù)雜的邏輯組合.
  • 多級嵌套不能超過三層,對于超過3層的可采用衛(wèi)語句, 策略模式, 狀態(tài)模式
  • 避免采用取反邏輯運(yùn)算符
  • 四 走進(jìn)JVM

    4.1 字節(jié)碼

    Java 所有的指令有200 個左右,一個字節(jié)(8 位)可以存
    儲256 種不同的指令信息,一個這樣的字節(jié)稱為字節(jié)碼(Bytecode )。在代碼的執(zhí)行
    過程中,NM 將字節(jié)碼解釋執(zhí)行,屏蔽對底層操作系統(tǒng)的依賴l NM 也可以將字節(jié)
    碼編譯執(zhí)行,如果是熱點(diǎn)代碼,會通過刀T 動態(tài)地編譯為機(jī)器碼,提高執(zhí)行效率

    4.2 類加載過程

    第一步,Load 階段讀取類文件產(chǎn)生二進(jìn)制流,并轉(zhuǎn)化為特定的數(shù)據(jù)結(jié)構(gòu),初步
    校驗(yàn)cafe babe 魔法數(shù)、常量池、文件長度、是否有父類等,然后創(chuàng)建對應(yīng)類的java.
    Jang.Class 實(shí)例。
    第二步,Link 階段包括驗(yàn)證、準(zhǔn)備、解析三個步驟。驗(yàn)證是更詳細(xì)的校驗(yàn),比
    如final 是否合規(guī)、類型是否正確、靜態(tài)變量是否合理等i 準(zhǔn)備階段是為靜態(tài)變量分
    配內(nèi)存,并設(shè)定默認(rèn)值,解析類和方法確保類與類之間的相互引用正確性,完成內(nèi)存
    結(jié)構(gòu)布局。
    第三步,Init 階段執(zhí)行類構(gòu)造器<clinit> 方法,如果賦值運(yùn)算是通過其他類的靜
    態(tài)方法來完成的,那么會馬上解析另外個類,在虛擬機(jī)槍中執(zhí)行完畢后通過返回值
    進(jìn)行賦值。

    4.3 內(nèi)存布局

  • Heap(堆區(qū))
    Heap 是OOM 故障最主要的發(fā)源地,它存儲著幾乎所有的實(shí)例對象,堆由垃圾
    收集器自動回收,堆區(qū)由各子線程共享使用。通常情況下,它占用的空間是所有內(nèi)存
    區(qū)域中最大的,但如果無節(jié)制地創(chuàng)建大量對象,也窯易消耗完所有的空間。堆的內(nèi)存
    空間既可以固定大小,也可以在運(yùn)行時(shí)動態(tài)地調(diào)整,通過如下參數(shù)設(shè)定初始值和最大
    值,比如-Xms256M -Xmxl024M ,其中-X 表示它是JVM 運(yùn)行參數(shù),ms 是memory
    start 的簡稱,mx 是memory max 的簡稱,分別代表最小堆窯量和最大堆窯量。
  • Metaspace (元空間
    早在JDK8版本中,無空間的前身Perm 區(qū)已經(jīng)被淘汰。在JDK7 及之前的版本中,只有Hotspot
    才有Perm 區(qū),譯為永久代,它在啟動時(shí)固定大小,很難進(jìn)行調(diào)優(yōu),并且FGC 時(shí)會移
    動類無信息。在某些場景下,如果動態(tài)加載類過多,容易產(chǎn)生Perm 區(qū)的OOM 。
    區(qū)別于永久代,元空間在本地內(nèi)存中分配。在JDK8 里,Perm 區(qū)中的所有內(nèi)容
    中字符串常量移至堆內(nèi)存,其他內(nèi)容包括類元信息、字段、靜態(tài)屬性、方法、常量等
    都移動至無空間內(nèi),比如圖4-10 中的0均ect 類元信息、靜態(tài)屬性System.out 、整型
    常量10000000 等。圖4-10 中顯示在常量池中的Strir 氈,其實(shí)際對象是被保存在堆內(nèi)
    存中的。
  • JVM Stack ( 虛擬機(jī)棧)
    棧(Stack )是-個先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu),就像子彈的彈夾,最后壓入的子彈先發(fā)射,
    壓在底部的子彈最后發(fā)射,撞針只能訪問位于頂部的那一顆子彈。
  • Native Method Stacks (本地方法棧)
    本地方法棧(Native Method Stack )在JVM 內(nèi)存布局中,也是結(jié)程對象私有的,
    但是虛擬機(jī)棧“主內(nèi)”,而本地方法棧“主外”。
  • Program Counter Register (程序計(jì)數(shù)寄存器)
    每個線程在創(chuàng)建后,都會產(chǎn)生自己的程序計(jì)數(shù)器和枝幀,程序計(jì)數(shù)器用來存放執(zhí)行指令的偏移量和行號指示器等,線程執(zhí)行或恢復(fù)都要依賴程序計(jì)數(shù)器。程序計(jì)數(shù)器在各個線程之間互不影響,此區(qū)域也不會發(fā)生內(nèi)存溢出異常。
  • 最后,從線程共享的角度來看,堆和元空間是所有線程共享的,而虛擬機(jī)枝、本
    地方法枝、程序計(jì)數(shù)器是線程內(nèi)部私有的,從這個角度看下Java 內(nèi)存結(jié)構(gòu),如圖4-12
    所示。

    4.4 對象實(shí)例化

    4.5 垃圾回收

    Java 會對內(nèi)存進(jìn)行自動分配與回收管理,使上層業(yè)務(wù)更加安全,方便地使用內(nèi)存
    實(shí)現(xiàn)程序邏輯。在不同的口爪4 實(shí)現(xiàn)及不同的回收機(jī)制中,堆內(nèi)存的劃分方式是不一
    樣的,垃圾回收的主要目的是清除不再使用的對象,自動釋放內(nèi)存。

    異常與日志

    5.1 異常分類

    JDK 中定義了套完整的異常機(jī)制,所有異常都是Throwable 的子類,分
    為Error (致命異常)和Exception (非致命異常)。Error 是一種非常特殊的異
    常類型,它的出現(xiàn)標(biāo)識著系統(tǒng)發(fā)生了不可控的錯誤,例如StackOverflowError 、
    OutO島1 emoryEηor 。針對此類錯誤,程序無法處理,只能人工介入。Exception 又分
    為ch ecked 異常(受檢異常)和unchecked 異常(非受檢異常)。

    5.2 try 代碼塊

    try-catch-finally 是處理程序異常的三部曲。當(dāng)存在try 時(shí),可以只有catch 代碼塊,
    也可以只有finally 代碼塊,就是不能單獨(dú)只有try 這個光桿司令。

    5.3 異常的接與拋

    契約式編程理念就完全處于防御式編程理念的下風(fēng),
    所以我們推薦方法的返回值可以為null ,不強(qiáng)制返回空集合或者空對象等,但是必須
    添加注釋充分說明什么情況下會返回null 值。防止NP E 定是調(diào)用方的責(zé)任,需要
    調(diào)用方進(jìn)行事先判斷。

    5.4 日志

    記錄應(yīng)用系統(tǒng)曰志主要有三個原因記錄操作軌跡、監(jiān)控系統(tǒng)運(yùn)行狀況、
    回溯系統(tǒng)故障。

    5.4.1 日志規(guī)范

    應(yīng)用中的擴(kuò)展日志命名方式應(yīng)該有統(tǒng)-
    的約定,通過命名能直觀明了地表明當(dāng)前日志文件是什么功能,如監(jiān)控、訪問日志
    等。推薦的日志文件命名方式為appName_logType logName.log 。其中,log Type 為
    日志類型,推薦分類有stats 、monitor 、visit 等,logNam e 為日志描述。這種命名的
    好處是通過文件名就可以知道曰志文件屬于什么應(yīng)用,什么類型,什么目的,也有利
    于歸類查找。例如,mppserv er 應(yīng)用中單獨(dú)監(jiān)控時(shí)區(qū)轉(zhuǎn)換異常的日志文件名定義為
    mppserver monitor timeZoneConvert.log 。

    代碼規(guī)約推薦曰志文件至少保存1 5 天,可以根據(jù)日志文件的重要程度、
    文件大小及磁盤空間再自行延長保存時(shí)間。

  • 預(yù)先判斷曰志級別
  • 避免無效日志打印
  • 區(qū)別對待錯誤日志
  • 保證記錄內(nèi)容完整
  • 5.4.2 日志框架

    日志框架分為三大部分,包括日志門面、曰志適配器、日志庫。

  • 日志門面
    門面設(shè)計(jì)模式是面向?qū)ο笤O(shè)計(jì)模式中的一種,日志框架采用的就是這種模式,類
    似JDB C 的設(shè)計(jì)理念。它只提供一套接口規(guī)范,自身不負(fù)責(zé)日志功能的實(shí)現(xiàn),目的是
    讓使用者不需要關(guān)注底層具體是哪個日志庫來負(fù)責(zé)日志打印及具體的使用細(xì)節(jié)等。目
    前用得最為廣泛的曰志門面有兩種slf4j 和commons -logging 。
  • 日志庫
    它具體實(shí)現(xiàn)了日志的相關(guān)功能,主流的日志庫有三個,分別是log4j 、log -jdk 、
    logback 。最早Java 要想記錄曰志只能通過System.out 或System.err 來完成,非常不方便。
    log4j 就是為了解決這一問題而提出的,它是最早誕生的曰志庫。接著JD K 也在1 .4 版
    本引入了一個日志庫java. util.logging. Logger.,簡稱log-dk。這樣市面上就出現(xiàn)兩種日志
    功能的實(shí)現(xiàn),開發(fā)者在使用時(shí)需要關(guān)注所使用的日志庫的具體細(xì)節(jié)。logback 是最晚出
    現(xiàn)的,它與log4j 出自同一個作者,是log4j的升級版且本身就實(shí)現(xiàn)了slf4j的接口。
  • 日志適配器
    曰志適配器分兩種場景
    ( I )日志門面適配器,因?yàn)閟lf4j規(guī)范是后來提出的此之前的日志庫是沒有
    實(shí)現(xiàn)slf4j的接口的,例如log4j ;所以在工程里要想使用slf4j +log4j 的模式,就額
    外需要個適配器(slf4j-log4j12 來解決接口不兼容的問題。
    ( 2 )日志庫適配器,在一些老的工程里,一開始為了開發(fā)簡單而直接使用了日志庫API來完成曰志打印,隨著時(shí)間的推移想將原來直接調(diào)用日志庫的模式改為業(yè)界標(biāo)準(zhǔn)的門面模式(例如slf4j +logback 組合),但老工程代碼里打印曰志的地方太多,難以改動,所以需要個運(yùn)隊(duì)器來完成從舊日志庫的API 到slf4j 的路由,這樣在不改動原有代碼的情況l、也能使用slf4j叫來統(tǒng)一管理曰志,而日后續(xù)自由替換具體日志庫也不成可題。
  • 總結(jié)

    以上是生活随笔為你收集整理的码出高效的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。