八股文|Java、MySQL斩个、計網(wǎng)后端面試

過于簡單的就不說了胯杭,比如“equals()==”有什么區(qū)別,相信大家都會受啥。

Java與JVM知識

JVM的內(nèi)存結(jié)構(gòu)

  1. 程序計數(shù)器(Program Counter Register):是線程私有的一塊內(nèi)存做个,記錄當前線程執(zhí)行的字節(jié)碼指令位置鸽心。
  2. Java虛擬機棧(Java Virtual Machine Stacks):也是線程私有的,用于存儲局部變量表居暖、操作數(shù)棧顽频、動態(tài)鏈接、方法出口等信息太闺。每個方法的調(diào)用都會在Java虛擬機棧中生成一個棧幀糯景,用于存儲方法的局部變量等信息。
  3. 本地方法棧(Native Method Stack):也是線程私有的省骂,為Java虛擬機調(diào)用Native方法服務(wù)蟀淮。
  4. Java堆(Java Heap):是所有線程共享的一塊內(nèi)存區(qū)域,用于存儲對象實例钞澳。Java堆還可以分為新生代和老年代怠惶,分別用于存儲不同生命周期的對象實例。
  5. 方法區(qū)(Method Area):也是所有線程共享的轧粟,用于存儲類信息策治、常量池、靜態(tài)變量兰吟、即時編譯器編譯后的代碼等數(shù)據(jù)通惫。
    對于線程私有的內(nèi)存結(jié)構(gòu)(程序計數(shù)器、Java虛擬機棧揽祥、本地方法棧)讽膏,不同線程之間互不干擾,是各自獨立的拄丰。而對于所有線程共享的內(nèi)存結(jié)構(gòu)(Java堆府树、方法區(qū)),需要進行線程同步料按,保證線程安全奄侠。

JVM的內(nèi)存一般分為五個區(qū)域。

區(qū)域 線程擁有 作用 大小
程序計數(shù)器 線程私有 記錄下一條指令的地址 很小
虛擬機棧 線程私有 存放方法的調(diào)用 一般
本地方法棧 線程私有 C/C++寫的native方法 一般
虛擬機堆 共享 創(chuàng)建的對象等數(shù)據(jù)
方法區(qū) 共享 常量载矿、靜態(tài)變量等 一般

注意:

  • 程序計數(shù)器很小垄潮,不會溢出內(nèi)存(Out Of Memory)。
  • 虛擬機是垃圾回收的重點照顧區(qū)域闷盔。
  • 諸如int等8種基本變量不在堆里弯洗,而是在棧里;而常量逢勾、靜態(tài)變量也不在堆里牡整,在方法區(qū)。

JVM虛擬機堆的內(nèi)存結(jié)構(gòu)

JVM虛擬機主要包括老生代溺拱、新生代逃贝、元空間三部分谣辞。其中新生代又包括了 Eden、S0沐扳、S1三個區(qū)域泥从。

(編者注:Eden 是英文里“伊甸園”的含義,大家可以理解為產(chǎn)房沪摄。Survivor 0躯嫉、Survivor 1 兩個區(qū)域意思是“幸存者0”“幸存者1”,簡稱為 S0卓起、S1)

堆的唯一目的就是存放對象實例和敬,幾乎所有的對象實例以及數(shù)組都在這里分配內(nèi)存。

大部分情況戏阅,對象都會首先在 Eden 區(qū)域分配昼弟,在一次新生代垃圾回收后,如果對象還存活奕筐,則會進入 S0 或者 S1舱痘,并且對象的年齡還會加 1(Eden 區(qū)->Survivor 區(qū)后對象的初始年齡變?yōu)?1),當它的年齡增加到一定程度(默認為 15 歲)离赫,就會被晉升到老年代中芭逝。對象晉升到老年代的年齡閾值,可以通過參數(shù) -XX:MaxTenuringThreshold 來設(shè)置渊胸。

一個對象誕生于 Eden 區(qū)旬盯。當 Eden 區(qū)人滿為患時,JVM 使用 minor gc翎猛,把 Eden 區(qū)已經(jīng)死掉的對象清理掉胖翰。然后把 S0 中的對象、Eden 區(qū)幸存的對象切厘,移動到 S1 區(qū)萨咳。(當然,也可以是從 S1 移動到 S0 區(qū))這個時候所有的對象“年齡”都 +1疫稿。當年齡達到一定程度時培他,就會被移動到老生區(qū)。

死亡對象判斷方法

引用計數(shù)法

如果別的地方有對這個對象的引用遗座,那么引用計數(shù) +1舀凛。如果沒有別的地方引用了,就判斷這個對象死亡途蒋。
這個算法不是很好猛遍,因為如果兩個對象相互引用,而不被其它的地方引用,那么他們并不會被判斷死亡螃壤。

可達性分析法

把對象之間的引用關(guān)系看做一張圖(或一棵樹),從垃圾回收根節(jié)點(GC Roots)出發(fā)筋帖,能夠達到的對象奸晴,就是還存活的。無法達到的對象日麸,就是已經(jīng)死亡的寄啼。

Java的垃圾回收是怎樣的機制

Java中的垃圾回收是自動化的,它會在程序運行時自行管理內(nèi)存的分配和回收代箭。Java的垃圾回收機制會定期掃描堆內(nèi)存中的對象墩划,標記出無法回收的對象并清除掉不再被引用的對象以釋放內(nèi)存。Java采用了可達性分析算法來判斷對象是否可以回收嗡综。如果一個對象再也無法通過任何引用達到乙帮,那么它就可以被回收。此外极景,Java還提供了finalize()方法讓開發(fā)人員在對象被回收之前做一些清理工作察净。

因為垃圾回收機制和內(nèi)存管理是由虛擬機完成的,所以Java程序員無需自己手動釋放內(nèi)存盼樟,這是Java的自動化垃圾回收機制帶來的好處氢卡。

Java垃圾回收常用的算法包括標記-清除、標記-整理晨缴、復(fù)制算法和分代算法译秦。

  • 標記-清除算法會標記不需要回收的對象,然后清除掉需要回收的對象击碗;

  • 標記-整理算法會對所有存活的對象進行整理以減少內(nèi)存碎片筑悴;

  • 標記-復(fù)制算法會將存活的對象復(fù)制到新的空間中,然后清除舊空間延都;

  • 而分代算法則是將對象按照生命周期的長短分為不同的代雷猪,在不同的代中采用不同的回收算法來提升垃圾回收效率。

Java的異常/錯誤及其分類

Java中的異常主要分為三類:受檢異常晰房、運行時異常和錯誤求摇。

  1. 受檢異常(Checked Exception):這類異常在編譯期就需要被檢查到并進行處理,否則編譯器會報錯殊者。如IOException和SQLException等与境。這類異常在處理時需要使用try-catch語句或者throws聲明拋出。
  2. 運行時異常(Unchecked Exception):這類異常在程序運行時才會拋出猖吴,如空指針異常(NullPointerException)和數(shù)組下標越界異常(ArrayIndexOutOfBoundsException)等摔刁。這種異常通常是由于程序邏輯錯誤或者意外情況導(dǎo)致的。程序員通常不需要對此類異常進行特別處理海蔽。
  3. 錯誤(Error):這類異常通常是由于系統(tǒng)錯誤或者資源耗盡等嚴重問題導(dǎo)致的共屈,如OutOfMemoryError等绑谣。與運行時異常類似,錯誤也不需要特別處理拗引,通常會導(dǎo)致程序崩潰借宵,而需要排查和修復(fù)錯誤產(chǎn)生的根本原因。

所以矾削,處理異常需要根據(jù)異常類型和情況選擇合適的方式進行處理壤玫,通常我們會對受檢異常進行捕獲和處理,對于運行時異常和錯誤則不需要特別處理哼凯。

Java的反射

反射是Java程序運行時獲取程序結(jié)構(gòu)(如類欲间、接口、變量断部、方法猎贴、注解等)信息的一種能力。它允許程序在運行時獲取一個類的完整構(gòu)造家坎,并進行操作嘱能,比如實例化對象、獲取屬性虱疏、調(diào)用方法等惹骂。通過反射,程序可以動態(tài)地創(chuàng)建對象做瞪、讀取和修改對象的屬性值和調(diào)用對象的方法对粪,同時也可以操作類的元數(shù)據(jù),例如泛型信息装蓬、注解等著拭。
用途:

  1. 動態(tài)地創(chuàng)建對象:通過反射可以在運行時根據(jù)類名動態(tài)地創(chuàng)建對象。
  2. 訪問私有變量和方法:反射可以訪問和修改類中的私有變量和方法牍帚,這在某些情況下是十分必要的儡遮。
  3. 動態(tài)代理:通過反射可以動態(tài)地生成代理類,從而實現(xiàn)AOP編程暗赶。
  4. 編寫通用代碼:反射可以使代碼更加通用鄙币,從而減少代碼量。

使用JDBC時蹂随,為什么要反射

動態(tài)加載JDBC驅(qū)動程序的類十嘿,從而使得JDBC驅(qū)動程序能夠被使用。因為JDBC驅(qū)動程序不是由Java語言編寫的岳锁,它們是通過本地代碼實現(xiàn)的绩衷,因此需要使用本地庫。而在Java中,通過反射機制可以動態(tài)獲取并加載本地庫咳燕,使得JDBC驅(qū)動程序能夠被正確加載和使用勿决。

Java類加載的過程

Java類加載的過程可分為三個階段:

  1. 加載:通過類加載器將class文件加載到JVM中,并生成對應(yīng)的Class對象招盲。
  2. 鏈接:
    2.1. 驗證:確保加載的類符合Java語言規(guī)范和JVM規(guī)范剥险,避免安全問題。
    2.2. 準備:為類變量分配內(nèi)存空間宪肖,并設(shè)置默認值。
    2.3. 解析:將符號引用轉(zhuǎn)換為直接引用健爬,如將變量或方法的名字轉(zhuǎn)換為內(nèi)存地址控乾。
  3. 初始化:為類變量賦初始值,并執(zhí)行靜態(tài)代碼塊娜遵。
    如果有父類蜕衡,則先進行父類加載。如果這些階段中存在錯誤设拟,便會拋出ClassNotFoundException慨仿、NoClassDefFoundError等異常。

(編者注:其它書籍纳胧、文檔镰吆、博客可能會使用別的說法,例如把2.鏈接中的三個步驟拆開來跑慕。)

Java中和class有關(guān)的Exception

  1. ClassNotFoundException万皿,表示在運行時找不到指定的類,通常是因為類路徑或者類名稱不正確核行。檢查型牢硅。
  2. NoClassDefFoundError,表示無法找到類定義芝雪,通常是因為代碼試圖使用某個類减余,但找不到該類的定義。非檢查型惩系,而且是Error位岔。
  3. NoSuchMethodError,表示代碼試圖調(diào)用不存在的方法蛆挫,通常是因為當前版本的類庫與代碼編譯時使用的類庫不同赃承。
  4. IllegalAccessException,表示試圖訪問私有成員或受保護的成員悴侵,但沒有足夠的權(quán)限瞧剖。
  5. InstantiationException,表示試圖創(chuàng)建抽象類或接口的實例,或試圖創(chuàng)建沒有無參構(gòu)造函數(shù)的類的實例抓于。

Class.forName()做粤、ClassLoader.loadClass()有什么區(qū)別

  • Class.forName() 在加載類的過程中,會對類進行初始化捉撮。
  • ClassLoader.loadClass() 不會自動初始化類怕品,需要顯式調(diào)用Class.newInstance()Class.getDeclaredConstructor() 創(chuàng)建實例對象來啟動初始化。

Java并發(fā)編程知識

進程與線程的概念是什么巾遭?有什么區(qū)別肉康?

進程是程序在執(zhí)行過程中分配和管理資源的基本單位。包含了代碼灼舍、數(shù)據(jù)以及執(zhí)行的上下文等相關(guān)信息吼和。操作系統(tǒng)會為每一個進程分配一定的資源,例如內(nèi)存骑素、CPU時間片等炫乓。

線程是進程中的一個執(zhí)行單元,一個進程可以包含多個線程献丑。線程共享進程的資源末捣,包括代碼、數(shù)據(jù)和上下文等创橄,因此在同一個進程中的多個線程之間可以直接共享數(shù)據(jù)尖啡。同時闹击,線程也有自己的椥ǎ空間和寄存器數(shù)據(jù)岔乔。

進程和線程的主要區(qū)別在于:

  1. 進程之間相互隔離,不能直接訪問和修改對方的內(nèi)存空間咖熟;而線程之間可以共享同一個進程的資源圃酵;
  2. 每個進程有獨立的內(nèi)存空間,但是進程內(nèi)的多個線程共享同一個內(nèi)存空間馍管;
  3. 創(chuàng)建和銷毀線程的開銷比創(chuàng)建和銷毀進程的開銷小郭赐,因此多用于并發(fā)環(huán)境下的處理。

(編者注:可能在其它的博客确沸、文檔捌锭、書籍里,有說得更清楚的罗捎。)

為什么要多線程編程观谦?什么場景下使用多線程編程?

多線程編程可以提高程序的執(zhí)行效率和響應(yīng)速度桨菜。當程序需要處理多個任務(wù)時豁状,使用多線程可以讓不同的任務(wù)并行執(zhí)行捉偏,避免單線程阻塞導(dǎo)致程序響應(yīng)緩慢。

多線程編程適用于以下場景:

  • 當程序需要執(zhí)行一些耗時的操作時泻红,使用多線程可以將這些操作放到另一個線程中執(zhí)行夭禽,讓主線程可以繼續(xù)響應(yīng)用戶的操作,提高程序的響應(yīng)速度谊路。
  • 當程序需要執(zhí)行多個任務(wù)時讹躯,使用多線程可以同時執(zhí)行這些任務(wù),提高了程序的并發(fā)能力缠劝。
  • 當需要使用某些第三方庫或API時潮梯,這些庫可能是阻塞式的,也就是說在執(zhí)行過程中會阻塞當前線程惨恭,影響程序的響應(yīng)速度酷麦。使用多線程可以將這些操作放到另一個線程中執(zhí)行,保持主線程的響應(yīng)速度喉恋。

有哪些并發(fā)問題?

  1. 競態(tài)條件:多個線程(或進程)同時訪問共享數(shù)據(jù)母廷,導(dǎo)致數(shù)據(jù)的狀態(tài)不確定性和不一致性轻黑。

  2. 死鎖和活鎖:多個線程持有互斥鎖,但是它們彼此需要對方釋放鎖才能繼續(xù)執(zhí)行琴昆,導(dǎo)致線程無法前進氓鄙。

  3. 資源不足:多個線程競爭資源,但是資源數(shù)限制业舍,導(dǎo)致某些進程無法獲取所需資源抖拦。

  4. 數(shù)據(jù)同步問題:多線程訪問同一數(shù)據(jù)源可能會導(dǎo)致數(shù)據(jù)不一致,需要使用同步技術(shù)來保證數(shù)據(jù)的一致性舷暮。

  5. 上下文切換開銷:多個線程在并發(fā)執(zhí)行時态罪,會頻繁地發(fā)生上下文切換,導(dǎo)致系統(tǒng)開銷增加下面。

進程間通信复颈、線程間通信的方法有哪些?

進程間通信的方式包括管道沥割、命名管道耗啦、共享內(nèi)存、消息隊列机杜、信號量和套接字等帜讲。其中,管道和命名管道用于單向通信椒拗,共享內(nèi)存和消息隊列用于數(shù)據(jù)共享似将,信號量用于進程間進行同步和互斥获黔,套接字則可以實現(xiàn)不同機器間的通信。(筆者注:這套說辭僅適用于Java玩郊,應(yīng)該不是隨便兩個進程都可以這樣的肢执。)

線程間通信的方式包括鎖、條件變量译红、信號量预茄、讀寫鎖和原子變量等。其中侦厚,鎖用于實現(xiàn)線程之間的互斥耻陕,條件變量用于線程之間的通信,信號量也可以用于線程間同步和互斥刨沦。讀寫鎖則用于讀取和修改共享數(shù)據(jù)的場景诗宣,原子變量則可以保證某些操作的原子性。

線程安全是什么含義想诅?

"線程安全"是指在多線程應(yīng)用程序中召庞,當多個線程同時訪問共享資源時,不會發(fā)生不確定的来破、意外的結(jié)果篮灼。

線程安全要求:原子性、可見性徘禁、有序性诅诱。

  • 原子性(atomicity)指的是一個操作是不可被中斷的整體,在對多個數(shù)據(jù)進行操作的時候送朱,要么所有數(shù)據(jù)同時發(fā)生變化娘荡,要么所有數(shù)據(jù)都不發(fā)生變化。

  • 可見性(visibility)指的是一個線程修改的變量能否被其他線程及時感知到驶沼。在多線程編程中炮沐,如果不保證可見性,可能會出現(xiàn)一個線程修改了共享變量的值回怜,但是其他線程仍然讀取的是舊值的情況央拖。

  • 有序性(ordering)指的是一個線程中的操作與其他線程中的操作發(fā)生的先后順序可能會存在差異,需要通過特定的機制來保證一定的順序鹉戚,以及保證在一個線程中的操作順序鲜戒。

引申:用synchronized上鎖保證三個特性。用volatile保證可見性抹凳、有序性遏餐,不保證原子性

守護線程是什么赢底?

守護線程(daemon thread)失都,是服務(wù)其他的線程柏蘑。當所有的非守護線程結(jié)束運行時,守護線程會隨著虛擬機的關(guān)閉而結(jié)束運行粹庞。

守護線程主要用于在后臺執(zhí)行支持性任務(wù)咳焚,比如Java垃圾回收線程就是一個典型的守護線程。

start()方法和 run()方法有什么區(qū)別庞溜?

調(diào)用 start() 方法會創(chuàng)建一個新的線程并在新的線程中執(zhí)行 run() 方法革半。
而調(diào)用 run() 方法則只是在當前線程中直接執(zhí)行 run() 方法。如果直接調(diào)用 run() 方法流码,那么就不會創(chuàng)建新的線程又官,而是在當前線程中直接執(zhí)行,這可能會阻塞主線程漫试。

Java有哪些常見的線程安全的容器六敬?

Java中的線程安全容器主要有以下幾種:

  1. ConcurrentHashMap:適用于高并發(fā)環(huán)境的哈希表,支持高效的并發(fā)讀寫操作驾荣。
  2. CopyOnWriteArrayList:一個線程安全的ArrayList外构,它采用了一種寫時復(fù)制的思想,在寫操作時播掷,會進行數(shù)據(jù)的復(fù)制审编,因此讀操作不會阻塞寫操作。
  3. ConcurrentLinkedQueue:基于鏈表實現(xiàn)的線程安全隊列叮趴,適用于高并發(fā)的生產(chǎn)者消費者模型。
  4. BlockingQueue:Java中提供的阻塞隊列接口权烧,提供了put眯亦、take等阻塞方法,能夠很好地支持生產(chǎn)者消費者模式般码。
    還有一些其他的線程安全容器妻率,如ThreadLocal等,不過它們的作用和上述容器不太相同板祝。

ConcurrentHashMap是怎么實現(xiàn)線程安全的宫静?

ConcurrentHashMap實現(xiàn)了分段鎖,將整個Map的存儲空間分成了若干個小段券时,每一小段都是一個獨立的鎖孤里。不同的線程可以同時訪問這些小段上的不同數(shù)據(jù),從而提高了并發(fā)性能橘洞。
分段鎖的另一個好處是捌袜,當一個線程訪問其中一個小段時,其他線程可以并行地訪問其他小段炸枣,不會被阻塞虏等。這種機制在高并發(fā)的場景下非常有效弄唧,可以極大提升ConcurrentHashMap的性能。

CopyOnWriteArrayList是怎么實現(xiàn)線程安全的霍衫?

CopyOnWriteArrayList是通過在修改元素的時候不直接修改原始數(shù)組候引,而是先將原始數(shù)組復(fù)制一份,并在副本上進行修改的方式實現(xiàn)線程安全的敦跌。當有線程要修改CopyOnWriteArrayList時澄干,先復(fù)制一份當前的元素數(shù)組,在副本上進行修改操作峰髓,并最終將修改后的副本替換掉原始的元素數(shù)組傻寂,這樣就避免了多線程并發(fā)修改同一個數(shù)組時可能會出現(xiàn)的問題。
在讀取元素時携兵,CopyOnWriteArrayList會直接從原始的數(shù)組中讀取數(shù)據(jù)疾掰,因為在多線程并發(fā)訪問的情況下,讀取數(shù)據(jù)是線程安全的徐紧。
因此静檬,CopyOnWriteArrayList適用于讀多寫少的場景,因為每次寫入數(shù)據(jù)都需要復(fù)制一份原始數(shù)組并级,這會占用一定的內(nèi)存空間拂檩,加重GC負擔,并且會造成數(shù)據(jù)不一致的問題嘲碧。

Java線程池的核心參數(shù)

  1. corePoolSize:線程池中保持的最小線程數(shù)量稻励。
  2. maximumPoolSize:線程池中允許的最大線程數(shù)量。
  3. keepAliveTime:當線程池中線程數(shù)量超過corePoolSize時愈涩,多余的空閑線程的存活時間望抽。
  4. unit:keepAliveTime的時間單位。
  5. workQueue:用來保存等待執(zhí)行的任務(wù)的阻塞隊列履婉。
  6. threadFactory:創(chuàng)建新線程的工廠煤篙。
  7. handler:當線程池中的工作隊列已滿且無法再添加新線程時,線程池將用handler來拒絕新提交的任務(wù)毁腿。

corePoolSize和maximumPoolSize的區(qū)別

corePoolSize表示核心線程池大小辑奈,也就是線程池中保持活動狀態(tài)的線程數(shù),即使這些線程處于空閑狀態(tài)已烤,也不會被回收鸠窗。
maximumPoolSize則是線程池最大的線程數(shù),如果隊列滿了胯究,且當前線程數(shù)小于最大線程數(shù)塌鸯,那就會創(chuàng)建新的線程來處理任務(wù)。

關(guān)于線程池的demo程序

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolDemo {

    public static void main(String[] args) {
        // 定義一個線程池唐片,其中最多有5個線程并行執(zhí)行
        ExecutorService executorService = Executors.newFixedThreadPool(5);

        // 向線程池提交10個任務(wù)
        for (int i = 0; i < 10; i++) {
            executorService.execute(new Task(i + 1));
        }

        // 關(guān)閉線程池
        executorService.shutdown();
    }

    /**
     * 自定義的任務(wù)類丙猬,實現(xiàn)Runnable接口
     */
    static class Task implements Runnable {
        private int taskNum;

        public Task(int taskNum) {
            this.taskNum = taskNum;
        }

        @Override
        public void run() {
            // 執(zhí)行任務(wù)涨颜,打印任務(wù)編號和當前線程名稱
            System.out.println("Task " + taskNum + " is running. Thread name: " + Thread.currentThread().getName());

            // 睡眠一段時間,模擬任務(wù)的執(zhí)行時間
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 任務(wù)執(zhí)行完畢茧球,打印結(jié)束信息
            System.out.println("Task " + taskNum + " is finished. Thread name: " + Thread.currentThread().getName());
        }
    }
}

死鎖的4個條件

  1. 互斥條件:一個資源每次只能被一個進程使用庭瑰。
  2. 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放抢埋。
  3. 不剝奪條件:進程已獲得的資源弹灭,在未完成使用之前,不能被強行剝奪揪垄,只能由進程自己釋放穷吮。
  4. 循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。

悲觀鎖和樂觀鎖的含義

(概念)悲觀鎖默認其他線程可能會修改它饥努,因此在訪問前會先對資源進行加鎖捡鱼,以防止其他線程的干擾。(應(yīng)用場景)悲觀鎖一般采用互斥鎖酷愧、讀寫鎖等機制來實現(xiàn)驾诈。悲觀鎖適用于寫操作比較頻繁的場景,如數(shù)據(jù)庫的更新操作溶浴。

(概念)樂觀鎖默認認為對共享資源的修改是少數(shù)乍迄,因此不用加鎖。而是在更新數(shù)據(jù)時比較數(shù)據(jù)版本號等信息士败,如果版本號匹配闯两,就執(zhí)行更新操作,否則認為數(shù)據(jù)沖突谅将,需要回滾或者重試漾狼。樂觀鎖一般采用版本號、時間戳等機制來實現(xiàn)戏自。(應(yīng)用場景)樂觀鎖適用于讀操作比較頻繁而寫操作比較少的場景邦投,如多用戶訪問同一筆數(shù)據(jù)的場景伤锚。

樂觀鎖的CAS算法

CAS(Compare And Swap)算法通過比較內(nèi)存中的值是否與期望值相同擅笔,如果相同,則將新值寫入該內(nèi)存地址屯援;如果不同猛们,則表明有其他線程已經(jīng)修改過內(nèi)存中的值,此時需要重新讀取內(nèi)存中的值并再次比較和嘗試修改狞洋,直到修改成功弯淘。這種算法避免了多線程同時寫入數(shù)據(jù)時出現(xiàn)數(shù)據(jù)混亂的問題,提高了程序的并發(fā)性能吉懊。

算法

編者按:算法這里就不多說了庐橙,就聊聊排序算法吧假勿,被問到的概率比較大。

快速排序算法

快速排序的思路是選取一個基準元素态鳖,將數(shù)組中小于該元素的放在左邊转培,大于該元素的放在右邊,然后遞歸地對左邊和右邊重復(fù)這個過程浆竭,直到排序完成浸须。

以下是Java實現(xiàn)的快速排序函數(shù):

public static void quickSort(int[] arr, int left, int right) {
    if (left >= right) { // 如果左右指針相遇或交錯,則返回
        return;
    }
    int pivot = partition(arr, left, right);  // 選取基準元素
    quickSort(arr, left, pivot - 1);  // 對左半部分進行快速排序
    quickSort(arr, pivot + 1, right); // 對右半部分進行快速排序
}

public static int partition(int[] arr, int left, int right) {
    int pivot = arr[right];  // 基準元素選擇最右邊的一個
    int i = left - 1; // 定義i為小于基準元素的區(qū)間的末尾
    for (int j = left; j < right; j++) {
        if (arr[j] < pivot) {  // 如果當前元素比基準元素小
            i++;  // i擴大區(qū)間
            swap(arr, i, j);  // 交換i和j所指的元素
        }
    }
    swap(arr, i+1, right);  // 交換i+1和基準元素
    return i + 1;
}

public static void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

快速排序最好邦泄、平均和最壞情況下的時間復(fù)雜度分別為O(n \log n)删窒、O(n \log n)O(n^2)

Java自帶的排序算法

Java自帶的排序顺囊,例如Arrays.sort()肌索,并不是快速排序算法。而是Tim算法包蓝。

Arrays.sort()使用了一種名為TimSort的排序算法驶社。它是一種基于歸并排序和插入排序的混合排序算法,在處理小數(shù)組時使用插入排序测萎,在處理大數(shù)組時使用歸并排序亡电,并嘗試通過充分利用已排序的子序列來提高性能。

常見的排序算法

排序算法 最好時間復(fù)雜度 最壞時間復(fù)雜度 平均時間復(fù)雜度 是否穩(wěn)定
冒泡排序 O(n) O(n^2) O(n^2) 穩(wěn)定
選擇排序 O(n^2) O(n^2) O(n^2) 不穩(wěn)定
插入排序 O(n) O(n^2) O(n^2) 穩(wěn)定
快速排序 O(n \log(n)) O(n^2) O(n \log(n)) 不穩(wěn)定
歸并排序 O(n \log(n)) O(n \log(n)) O(n \log(n)) 穩(wěn)定
堆排序 O(n \log(n)) O(n \log(n)) O(n \log(n)) 不穩(wěn)定

MySQL數(shù)據(jù)庫

MySQL的引擎

  1. InnoDB是MySQL默認的引擎硅瞧,支持事務(wù)處理和行級鎖份乒,適合數(shù)據(jù)更新較頻繁的應(yīng)用。只支持BTREE索引腕唧,不支持HASH索引或辖。
  2. MyISAM不支持事務(wù)處理,但對讀操作性能好枣接,適合于數(shù)據(jù)量大但更新不頻繁的應(yīng)用颂暇。
  3. Memory引擎將表存儲在內(nèi)存中,讀寫速度非车蹋快耳鸯,但數(shù)據(jù)不是持久的,重啟后數(shù)據(jù)將會丟失膀曾。

BTREE索引和HASH索引對比

BTREE索引使用B-tree數(shù)據(jù)結(jié)構(gòu)進行存儲县爬,它可以對索引列進行排序,支持范圍查找和順序遍歷添谊,適合處理范圍查詢财喳,比如大于、小于、比較等耳高。但是在進行等值查詢時扎瓶,BTREE索引的查詢性能可能會有些許劣化。
HASH索引使用哈希表進行存儲泌枪,它可以快速進行等值查詢栗弟,查找時間近乎恒定,適合處理等值查詢工闺,比如"="和"IN"等乍赫。但是HASH索引對于范圍查詢和ORDER BY排序操作較為困難,而且因為哈希表的特性陆蟆,散列值沖突的情況較多雷厂,可能會降低其查詢效率。
總之叠殷,BTREE索引適合處理復(fù)雜的查詢改鲫,而HASH索引適合處理簡單的等值查詢。

MySQL數(shù)據(jù)庫中 索引的作用

MySQL數(shù)據(jù)庫的索引是用來加速數(shù)據(jù)庫表中的數(shù)據(jù)檢索和查詢的林束。通過在表中創(chuàng)建索引像棘,可以大大提高查詢的速度。
(編者注:具體到MySQL數(shù)據(jù)庫壶冒,索引index同時就是鍵key缕题,可以創(chuàng)建唯一鍵來讓某個字段的內(nèi)容互不相同,從而幫助實現(xiàn)數(shù)據(jù)約束胖腾。)

MySQL索引失效的情況

  1. 使用了NOT IN烟零。使用了OR
  2. 對索引列進行了函數(shù)操作咸作,如使用了函數(shù)锨阿、類型轉(zhuǎn)換或者運算符。
  3. 對索引列使用了LIKE操作符记罚,并且通配符在開頭(如 LIKE '%abc')墅诡。
  4. 對于多列索引,只使用了索引中部分列進行查詢桐智。
  5. 數(shù)據(jù)量過大末早,導(dǎo)致MySQL優(yōu)化器選擇全表掃描而非使用索引。
  6. 對于InnoDB存儲引擎酵使,在高并發(fā)環(huán)境下荐吉,若使用的是非主鍵索引焙糟,則可能會發(fā)生死鎖而導(dǎo)致索引失效口渔。

(編者注:不止這些。但是面試時也不必全部答出來穿撮。其它的博客缺脉、文檔痪欲、書籍可能會有更豐富的答案。)

MySQL的索引最左匹配原則

MySQL的索引最左匹配原則是指攻礼,在使用復(fù)合索引進行查詢時业踢,MySQL會優(yōu)先匹配索引最左邊的列,只有當查詢條件包含索引最左邊的列時礁扮,才能充分利用索引知举。如果查詢條件不包含最左邊的列,即使后面有匹配的列也不能利用索引太伊,查詢效率會降低雇锡。

例如,有一個復(fù)合索引 (a,b,c)僚焦,如果查詢條件為 a=1锰提,那么MySQL會利用該索引查找到所有a=1的行,再在結(jié)果中進行b芳悲、c列的篩選立肘。如果查詢條件為 b=2,那么最左列a并沒有被用到名扛,MySQL無法利用該索引進行優(yōu)化谅年,會掃描整個表進行查找,查詢會變得非常慢肮韧。

數(shù)據(jù)庫的ACID屬性

ACID屬性是指數(shù)據(jù)庫在事務(wù)處理中需要滿足的一些基本性質(zhì)踢故,其中:

  • 原子性(Atomicity):事務(wù)是一個不可分割的操作序列,要么全部執(zhí)行成功惹苗,要么全部失敗回滾殿较,不允許部分執(zhí)行。
  • 一致性(Consistency):事務(wù)執(zhí)行前后桩蓉,數(shù)據(jù)庫的狀態(tài)必須保持一致淋纲,不會因為操作錯誤或者其他異常情況導(dǎo)致數(shù)據(jù)的邏輯錯誤或者不一致。
  • 隔離性(Isolation):事務(wù)執(zhí)行時院究,對其他事務(wù)是隔離的洽瞬,每個事務(wù)都認為自己是唯一的操作,不受其他事務(wù)的干擾业汰。
  • 持久性(Durability):事務(wù)執(zhí)行成功后伙窃,對數(shù)據(jù)庫的影響必須是永久性的,即使在系統(tǒng)崩潰或者重啟的情況下样漆,數(shù)據(jù)也能夠得到恢復(fù)为障。

臟讀、不可重復(fù)讀、幻讀

  • 臟讀是指當一個事務(wù)讀取了另一個事務(wù)未提交的數(shù)據(jù)鳍怨,然后這些數(shù)據(jù)被回滾或修改呻右,導(dǎo)致第一個事務(wù)讀取了不正確的數(shù)據(jù)。

  • 不可重復(fù)讀是指在一個事務(wù)的執(zhí)行過程中鞋喇,由于其他事務(wù)修改或刪除了已經(jīng)查詢的數(shù)據(jù)声滥,導(dǎo)致第一個事務(wù)后續(xù)的查詢結(jié)果和前面的查詢結(jié)果不同。

  • 幻讀是指在一個事務(wù)的執(zhí)行過程中侦香,由于其他事務(wù)插入了新的數(shù)據(jù)落塑,導(dǎo)致第一個事務(wù)后續(xù)查詢時出現(xiàn)了一些新的行,使得之前的結(jié)果變得不合法罐韩。

數(shù)據(jù)庫的隔離級別

MySQL處理并發(fā)問題的隔離級別如下:

  1. 讀未提交(READ UNCOMMITTED):在該級別下芜赌,一個事務(wù)可以讀取另一個事務(wù)未提交的數(shù)據(jù)(臟讀),容易出現(xiàn)幻讀和不可重復(fù)讀的問題伴逸。
  2. 讀已提交(READ COMMITTED):在該級別下缠沈,一個事務(wù)只能讀取已經(jīng)提交的數(shù)據(jù),相對于讀未提交級別错蝴,此級別可以避免臟讀問題洲愤,但是幻讀和不可重復(fù)讀的問題仍可能出現(xiàn)。
  3. 可重復(fù)讀(REPEATABLE READ):在該級別下顷锰,一個事務(wù)執(zhí)行期間多次讀取相同的數(shù)據(jù)柬赐,總是得到同樣的結(jié)果,即只能讀取到自己的操作官紫,不能讀取未提交的數(shù)據(jù)肛宋,可以解決臟讀和不可重復(fù)讀問題。
  4. 串行化(SERIALIZABLE):在該級別下束世,MySQL使用悲觀鎖酝陈,對所有數(shù)據(jù)進行鎖定,可以避免臟讀毁涉、不可重復(fù)讀和幻讀的出現(xiàn)沉帮,但是會造成大量的鎖等待,降低數(shù)據(jù)庫的并發(fā)性能贫堰。

CHAR穆壕,VARCHAR 和 Text 的比較

CHAR是固定長度的,而VARCHAR是可變長度的其屏。相比之下喇勋,CHAR處理固定長度的字符串時速度更快,但是浪費存儲空間偎行,而VARCHAR適用于處理可變長度的字符串川背,節(jié)省存儲空間贰拿,但是在索引和比較時速度稍慢一些。

Text則是一種特殊的VARCHAR類型渗常,可以存儲大量的文本數(shù)據(jù)。相對而言汗盘,Text類型能夠存儲更長的文本皱碘,但在處理較小的數(shù)據(jù)時相對會浪費存儲空間和一定的查詢效率。因此隐孽,當需要存儲大量文本數(shù)據(jù)時癌椿,應(yīng)使用Text類型。

設(shè)計數(shù)據(jù)表的第一菱阵、二踢俄、三范式

  1. 第一范式(1NF):表中的所有列都是不可分割的原子值,即每一列都只包含單一的數(shù)據(jù)項晴及,不可再分都办。

  2. 第二范式(2NF):表中的非主鍵列必須完全依賴于主鍵,而非部分依賴虑稼。也就是說琳钉,一個表必須有一個唯一的主鍵,并且所有的非主鍵列必須和主鍵列有完全依賴關(guān)系蛛倦。

  3. 第三范式(3NF):表中的所有列必須和主鍵列直接相關(guān)歌懒,而不能與依賴于其他列。換句話說溯壶,表中的每一列都應(yīng)該只和主鍵列直接相關(guān)及皂,而不是間接相關(guān)。

實現(xiàn)了第一范式且改,保證了數(shù)據(jù)不會出現(xiàn)多余的重復(fù)字段验烧。實現(xiàn)了第二范式,則保證數(shù)據(jù)的唯一性和正確性又跛。實現(xiàn)了第三范式噪窘,則保證了數(shù)據(jù)只存儲在一個地方,避免了數(shù)據(jù)的冗余效扫。

計算機網(wǎng)絡(luò)知識

域名解析的過程

  1. 用戶在瀏覽器中輸入網(wǎng)址倔监,瀏覽器會向本地域名解析器(通常為路由器)發(fā)起查詢。

  2. 如果本地解析器中已經(jīng)有了這個域名的緩存記錄菌仁,那么它會直接返回IP地址給瀏覽器浩习;否則,它會向上級DNS服務(wù)器發(fā)出查詢請求济丘。

  3. 上級DNS服務(wù)器也可能會有緩存記錄谱秽,如果有洽蛀,就返回給本地解析器;否則疟赊,它會向更高層級的DNS服務(wù)器發(fā)出請求吝羞。 這個過程會一直重復(fù)战坤,直到查詢到根域名服務(wù)器(Root Name Server)。根域名服務(wù)器會返回下一級DNS服務(wù)器的地址(通常是頂級域名服務(wù)器,比如“.com”)判族,本地解析器然后向下一級DNS服務(wù)器發(fā)出查詢請求就谜。

  4. DNS服務(wù)器返回目標域名對應(yīng)的IP地址給本地解析器挺益,本地解析器再將結(jié)果緩存起來牲尺,同時將IP地址返回給瀏覽器。

  5. 瀏覽器通過IP地址向目標服務(wù)器發(fā)出請求戳玫,服務(wù)器響應(yīng)后將網(wǎng)頁內(nèi)容返回給瀏覽器熙掺,完成整個過程。

(編者注:不必分為什么第一步咕宿、第二步……等币绩。像講故事一樣講出來,言之有理即可府阀。)

TCP和UDP

聯(lián)系

  1. 都是用來將數(shù)據(jù)從一個應(yīng)用程序傳輸?shù)搅硪粋€應(yīng)用程序类浪。

  2. 都需要運用一些特定的協(xié)議來完成數(shù)據(jù)傳輸。

  3. 都支持面向連接和無連接的通信方式肌似。

區(qū)別

  1. TCP是面向連接的協(xié)議费就,UDP是無連接的協(xié)議。

  2. TCP提供可靠的數(shù)據(jù)傳輸川队,而UDP則不保證數(shù)據(jù)傳輸?shù)目煽啃浴?/p>

  3. TCP使用流量控制力细、擁塞控制和錯誤校驗來確保可靠性固额,而UDP則只提供基本的錯誤檢測眠蚂。

  4. TCP通信速度較慢,UDP通信速度較快斗躏。

  5. TCP可以適應(yīng)不同的網(wǎng)絡(luò)狀況逝慧,而UDP則更適用于高速數(shù)據(jù)傳輸。

建立于TCP啄糙、UDP的應(yīng)用層協(xié)議

TCP協(xié)議對應(yīng)的應(yīng)用層協(xié)議有HTTP笛臣、FTP、SMTP隧饼、TELNET沈堡、SSH等;
UDP協(xié)議對應(yīng)的應(yīng)用層協(xié)議有DNS燕雁、DHCP诞丽、TFTP等鲸拥。

TCP的三次握手、四次揮手

(編者按僧免,老掉牙了刑赶,去看別的書籍、博客懂衩,這里就不寫了撞叨。別人寫得很詳細了。)

TCP的滑動窗口

TCP協(xié)議的滑動窗口(Sliding Window)是一種流量控制機制勃痴,用于在發(fā)送端和接收端之間進行數(shù)據(jù)傳輸時的數(shù)據(jù)包確認和窗口大小調(diào)整谒所。

滑動窗口的基本原理是热康,在發(fā)送數(shù)據(jù)包之后沛申,發(fā)送方維護一個大小為N的窗口。N是指可以一次性發(fā)送多少個數(shù)據(jù)包未收到接收方的確認信息姐军。接收方收到數(shù)據(jù)包后铁材,會發(fā)送確認信息給發(fā)送方,告訴發(fā)送方已經(jīng)收到了數(shù)據(jù)奕锌,以及下一個期望接收的數(shù)據(jù)包的序號(ACK)著觉。在發(fā)送方收到ACK之后,就可以將窗口向前滑動一位惊暴,發(fā)送下一個數(shù)據(jù)包饼丘。接收方也可以根據(jù)當前情況調(diào)整窗口大小,從而控制傳輸速率辽话。

滑動窗口的作用是通過動態(tài)調(diào)整窗口大小來適應(yīng)不同網(wǎng)絡(luò)條件下的數(shù)據(jù)傳輸肄鸽。通過控制發(fā)送方發(fā)送數(shù)據(jù)包的速率,可以防止數(shù)據(jù)擁塞油啤、傳輸錯誤等問題的發(fā)生典徘。同時,滑動窗口也提供了一種簡便的流量控制機制益咬,可以確保高效逮诲、可靠地進行數(shù)據(jù)傳輸。

TCP的擁塞控制

TCP通過擁塞窗口來實現(xiàn)擁塞控制幽告。擁塞窗口是TCP用來控制發(fā)送數(shù)據(jù)量的一個參數(shù)梅鹦。當擁塞窗口較小時,TCP發(fā)送數(shù)據(jù)包的速度也會相應(yīng)較慢冗锁,以此來避免網(wǎng)絡(luò)擁塞帘瞭。TCP還會根據(jù)網(wǎng)絡(luò)的擁塞情況不斷調(diào)整擁塞窗口的大小,以達到更為合理的擁塞控制蒿讥。此外蝶念,TCP還通過重傳機制來保證數(shù)據(jù)的可靠性抛腕,同時避免持續(xù)發(fā)送數(shù)據(jù)導(dǎo)致網(wǎng)絡(luò)擁塞的情況∶窖常總之担敌,TCP的擁塞控制機制使其能夠在網(wǎng)絡(luò)擁塞的情況下自適應(yīng)地調(diào)整發(fā)送數(shù)據(jù)的速度,從而保證網(wǎng)絡(luò)傳輸?shù)馁|(zhì)量和穩(wěn)定性廷蓉。

HTTP和HTTPS的區(qū)別

HTTPS 在傳輸數(shù)據(jù)時全封,使用了TLS/SSL協(xié)議進行加密處理,使得數(shù)據(jù)傳輸過程中被竊聽或篡改的可能性大大降低桃犬。因此刹悴,當用戶訪問一個使用 HTTPS 協(xié)議的網(wǎng)站時,他們的數(shù)據(jù)會更加安全攒暇。而 HTTP 則未加密土匀,數(shù)據(jù)傳輸過程中可能會被篡改、竊聽形用,對于涉及敏感信息(如密碼就轧、銀行卡信息等)的傳輸,使用 HTTP 是不安全的田度。

HTTP的GET和POST方法

GET方法一般用來請求服務(wù)器返回某個資源妒御,它會將請求的參數(shù)編碼放在URL的后面,可以在瀏覽器地址欄中看到镇饺,因此在請求時傳遞的參數(shù)有長度限制(一般是2048個字符)乎莉,傳遞的數(shù)據(jù)量較小。GET方法是一個冪等方法奸笤,多次調(diào)用不會對資源產(chǎn)生副作用惋啃。因為GET方法的特性,它適用于請求數(shù)據(jù)揭保,但不適用于提交數(shù)據(jù)肥橙。

POST方法一般用來提交數(shù)據(jù),它會將參數(shù)放在HTTP請求體中秸侣,參數(shù)不會出現(xiàn)在URL中存筏,因此可以傳遞大量數(shù)據(jù)。POST方法不是一個冪等方法味榛,多次調(diào)用會對資源產(chǎn)生副作用椭坚,比如在數(shù)據(jù)庫中創(chuàng)建或修改數(shù)據(jù)。因為POST方法的特性搏色,它適用于提交表單數(shù)據(jù)善茎、上傳文件等需要提交數(shù)據(jù)的情景。

HTTP的狀態(tài)碼

1XX:信息響應(yīng)類频轿,表示服務(wù)器已經(jīng)接收到請求垂涯,正在處理中烁焙。

2XX:成功響應(yīng)類,表示請求已經(jīng)被服務(wù)器成功地接收耕赘、理解骄蝇、并接受處理。

3XX:重定向響應(yīng)類操骡,表示需要進一步操作以完成請求九火。

4XX:客戶端錯誤響應(yīng)類,表示請求存在問題册招,服務(wù)器無法處理岔激。

5XX:服務(wù)器錯誤響應(yīng)類,表示服務(wù)器在處理請求時發(fā)生了錯誤是掰。

常見的狀態(tài)碼有:200 OK(請求成功), 404 Not Found(請求的資源不存在), 500 Internal Server Error(服務(wù)器內(nèi)部錯誤)等虑鼎。

(編者注:有些書籍和文檔中有非常詳細的狀態(tài)碼解釋。但是狀態(tài)碼很多冀惭,不必要每個都十分了解震叙。)

HTTP請求頭的參數(shù)

(僅說明常見的)

  1. Accept:指定客戶端能夠接收的內(nèi)容類型掀鹅。

  2. Accept-Encoding:指定客戶端能夠接受的編碼方式散休,比如 gzip 或 deflate。

  3. Authorization:在需要認證的請求中乐尊,包含認證信息戚丸。

  4. Content-Length:請求體的長度。

  5. Content-Type:請求體的類型扔嵌,比如 application/json限府。

  6. Cookie:包含客戶端發(fā)送給服務(wù)器的 cookie 信息。

  7. User-Agent:客戶端的瀏覽器信息痢缎,用來識別客戶端的瀏覽器類型胁勺。

  8. Host:請求的主機名。

HTTP相應(yīng)頭的參數(shù)

(僅說明常見的)

  1. Content-Type:響應(yīng)體的傳輸類型独旷,比如text/html署穗、application/json等喵;
  2. Content-Length:響應(yīng)體的長度喵嵌洼;
  3. Cache-Control:控制緩存的行為案疲,比如max-ageno-cache麻养、private等喵褐啡;
  4. Server:服務(wù)器的軟件和版本號喵;
  5. Date:響應(yīng)的時間戳喵鳖昌;
  6. Set-Cookie:設(shè)置Cookie信息喵备畦;
  7. Location:重定向的URL地址喵低飒。

cookie和session

Cookie是存儲在用戶計算機上的小文本文件,由瀏覽器維護懂盐。其中可以包含任何數(shù)據(jù)逸嘀,例如用戶信息、偏好設(shè)置等等允粤。網(wǎng)站可以在用戶訪問它們的時候設(shè)置cookie崭倘,并在后續(xù)的請求中讀取。比如用戶的語言偏好类垫、購物車內(nèi)容司光、頁面皮膚等,可以使用 Cookie 存儲悉患。

Session是將數(shù)據(jù)存儲在服務(wù)器上而不是客戶端計算機上残家。 在用戶與web服務(wù)器進行會話時,服務(wù)器會為每個會話創(chuàng)建一個session對象售躁,并為該會話提供一個唯一的session ID坞淮。 session ID隨后可以在每個迭代中通過cookie或URL參數(shù)發(fā)送回客戶端。在后續(xù)請求中陪捷,服務(wù)器可以根據(jù)session ID檢索session對象回窘,并使用其中存儲的數(shù)據(jù)進行請求處理。session經(jīng)常被用于存儲敏感數(shù)據(jù)市袖,例如用戶憑證等啡直,以防止不受信任的訪問。如登錄憑證苍碟、用戶權(quán)限酒觅、用戶信息等,采用 Session 機制比較保險微峰。


本文 90% 以上的內(nèi)容由 ChatGPT 撰寫舷丹。我(編者)只進行了簡單的勘誤、注釋蜓肆、整理颜凯。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市症杏,隨后出現(xiàn)的幾起案子装获,更是在濱河造成了極大的恐慌,老刑警劉巖厉颤,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件穴豫,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機精肃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門秤涩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人司抱,你說我怎么就攤上這事筐眷。” “怎么了习柠?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵匀谣,是天一觀的道長。 經(jīng)常有香客問我资溃,道長武翎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任溶锭,我火速辦了婚禮宝恶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘趴捅。我一直安慰自己垫毙,他們只是感情好,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布拱绑。 她就那樣靜靜地躺著综芥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪欺栗。 梳的紋絲不亂的頭發(fā)上毫痕,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天征峦,我揣著相機與錄音迟几,去河邊找鬼。 笑死栏笆,一個胖子當著我的面吹牛类腮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛉加,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼蚜枢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了针饥?” 一聲冷哼從身側(cè)響起厂抽,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎丁眼,沒想到半個月后筷凤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年藐守,在試婚紗的時候發(fā)現(xiàn)自己被綠了挪丢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡卢厂,死狀恐怖乾蓬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情慎恒,我是刑警寧澤任内,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站融柬,受9級特大地震影響族奢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜丹鸿,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一越走、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧靠欢,春花似錦廊敌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掷空,卻和暖如春肋殴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背坦弟。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工护锤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人酿傍。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓烙懦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赤炒。 傳聞我的和親對象是個殘疾皇子氯析,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容