java高級(jí)知識(shí)點(diǎn)

1.java基本數(shù)據(jù)類型

java一共8個(gè)基本數(shù)據(jù)類型

byte 1字節(jié)(1byte = 8 bit)
short 2字節(jié)
int 4字節(jié)
long 8字節(jié)
double 8字節(jié)
char 2字節(jié)(C語(yǔ)言中是1字節(jié))可以存儲(chǔ)一個(gè)漢字
float 4字節(jié)
boolean false/true(理論上占用1bit,1/8字節(jié),實(shí)際處理按1byte處理)
(string 4字節(jié) 不是基本數(shù)據(jù)類型)

2.Set、List侈咕、Map的區(qū)別和聯(lián)系

Set和List都是繼承自Collection接口,Map不是

Set
(1)不允許重復(fù)對(duì)象
(2)無序容器(你無法保證每個(gè)元素的存儲(chǔ)順序梳杏,TreeSet通過 Comparator 或者 Comparable 維護(hù)了一個(gè)排序順序。)
(3)只允許有一個(gè)null元素
(4)Set 接口最流行的幾個(gè)實(shí)現(xiàn)類是 HashSet淹接、LinkedHashSet 以及 TreeSet十性。最流行的是基于 HashMap 實(shí)現(xiàn)的 HashSet;TreeSet 還實(shí)現(xiàn)了 SortedSet 接口塑悼,因此 TreeSet 是一個(gè)根據(jù)其 compare() 和 compareTo() 的定義進(jìn)行排序的有序容器烁试。

List(接口)
(1)允許重復(fù)對(duì)象
(2)有序容器
(3)可以插入多個(gè)null元素
(4)常用的實(shí)現(xiàn)類有 ArrayList、LinkedList 和 Vector拢肆。ArrayList 最為流行,它提供了使用索引的隨意訪問靖诗,而 LinkedList 則對(duì)于經(jīng)常需要從 List 中添加或刪除元素的場(chǎng)合更為合適郭怪。

Map
(1)適用于存儲(chǔ)鍵值對(duì)
(2)可隨意創(chuàng)建null值,但只能有一個(gè)null鍵
(3)Map 接口最流行的幾個(gè)實(shí)現(xiàn)類是 HashMap刊橘、LinkedHashMap鄙才、Hashtable 和 TreeMap。(HashMap促绵、TreeMap最常用)

<1>線程安全集合類與非線程安全集合類
LinkedList攒庵、ArrayList嘴纺、HashSet是非線程安全的,Vector是線程安全的;
HashMap是非線程安全的浓冒,HashTable是線程安全的;
StringBuilder是非線程安全的栽渴,StringBuffer是線程安全的。

<2>為什么Set稳懒、List闲擦、map不實(shí)現(xiàn)Cloneable和Serializable接口
克隆(cloning)或者序列化(serialization)的語(yǔ)義和含義是跟具體的實(shí)現(xiàn)相關(guān)的场梆。因此應(yīng)該由集合類的具體實(shí)現(xiàn)類來決定如何被克隆或者序列化

(a)克隆是把一個(gè)對(duì)象里面的屬性值墅冷,復(fù)制給另一個(gè)對(duì)象。而不是對(duì)象引用的復(fù)制
(b)將對(duì)象的狀態(tài)保存在存儲(chǔ)媒體中一邊可以在以后重寫創(chuàng)建出完全相同的副本
按值將對(duì)象從一個(gè)應(yīng)用程序域法相另一個(gè)應(yīng)用程序域?qū)崿F(xiàn)Serializable接口的作用就是可以把對(duì)象存到字節(jié)流或油,然后可以恢復(fù)寞忿。所以你想你的對(duì)象沒有序列化,怎么才能在網(wǎng)絡(luò)傳輸呢顶岸?要網(wǎng)絡(luò)傳輸就得轉(zhuǎn)為字節(jié)流腔彰,所以在分布式應(yīng)用中,你就得實(shí)現(xiàn)序列化蜕琴。如果你不需要分布式應(yīng)用萍桌,那就沒必要實(shí)現(xiàn)序列化

3.Arrays.sort的實(shí)現(xiàn)

參考:
(1) http://blog.csdn.net/u011410529/article/details/56668545?locationnum=6&fps=1
(2) http://blog.csdn.net/wisgood/article/details/16541013

4.什么時(shí)候使用CopyOnArrayList

CopyOnWriteArrayList適合使用在讀操作遠(yuǎn)遠(yuǎn)大于寫操作的場(chǎng)景里(多線程),比如緩存凌简。發(fā)生修改時(shí)候做copy上炎,新老版本分離,保證讀的高性能雏搂,適用于以讀為主的情況

5.volatile的使用

volatitle變量提供了線程的可見性藕施,并不保證線程的安全性和原子性
線程的兩個(gè)主要特性分別是互斥和可見性,

互斥性 即一次只允許一個(gè)線程持有某個(gè)特定的鎖凸郑,從而保證一次就只有一個(gè)線程能夠使用該共享數(shù)據(jù)裳食。

可見性 必須確保釋放鎖之前對(duì)共享數(shù)據(jù)做出的更改對(duì)于隨后獲得該鎖的另一個(gè)線程是可見的 (如果沒有同步機(jī)制提供的這種可見性保證,線程看到的共享變量可能是修改前的值或不一致的值芙沥,這將引發(fā)許多嚴(yán)重問題诲祸。)

參考:http://blog.csdn.net/jinfeiteng2008/article/details/53423858

6.synchronied的使用

synchronized是Java中的關(guān)鍵字,是一種同步鎖而昨。它修飾的對(duì)象有以下幾種:

(1) 無論synchronized關(guān)鍵字加在方法上還是對(duì)象上救氯,如果它作用的對(duì)象是非靜態(tài)的,則它取得的鎖是對(duì)象歌憨;如果synchronized作用的對(duì)象是一個(gè)靜態(tài)方法或一個(gè)類着憨,則它取得的鎖是對(duì)類,該類所有的對(duì)象同一把鎖务嫡。

(2) 每個(gè)對(duì)象只有一個(gè)鎖(lock)與之相關(guān)聯(lián)甲抖,誰拿到這個(gè)鎖誰就可以運(yùn)行它所控制的那段代碼漆改。

(3) 實(shí)現(xiàn)同步是要很大的系統(tǒng)開銷作為代價(jià)的,甚至可能造成死鎖准谚,所以盡量避免無謂的同步控制挫剑。

參考:http://blog.csdn.net/luoweifu/article/details/46613015

7.CAS的實(shí)現(xiàn)原理以及問題

一個(gè)線程的失敗或者掛起不應(yīng)該影響其他線程的失敗或掛起的算法。

現(xiàn)代的CPU提供了特殊的指令氛魁,可以自動(dòng)更新共享數(shù)據(jù)暮顺,而且能夠檢測(cè)到其他線程的干擾,而 compareAndSet() 就用這些代替了鎖定秀存。

拿出AtomicInteger來研究在沒有鎖的情況下是如何做到數(shù)據(jù)正確性的捶码。

private volatile int value;

首先毫無以為,在沒有鎖的機(jī)制下可能需要借助volatile原語(yǔ)或链,保證線程間的數(shù)據(jù)是可見的(共享的)惫恼。

這樣才獲取變量的值的時(shí)候才能直接讀取。

public final int get() {
        return value;
    }

然后來看看++i是怎么做到的澳盐。

public final int incrementAndGet() {
   for (;;) {
       int current = get();
       int next = current + 1;
       if (compareAndSet(current, next))
           return next;
   }
}

在這里采用了CAS操作祈纯,每次從內(nèi)存中讀取數(shù)據(jù)然后將此數(shù)據(jù)和+1后的結(jié)果進(jìn)行CAS操作,如果成功就返回結(jié)果叼耙,否則重試直到成功為止腕窥。

而compareAndSet利用JNI來完成CPU指令的操作。

public final boolean compareAndSet(int expect, int update) {   
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

鎖機(jī)制存在以下問題:
(1) 在多線程競(jìng)爭(zhēng)下筛婉,加鎖簇爆、釋放鎖會(huì)導(dǎo)致比較多的上下文切換和調(diào)度延時(shí),引起性能問題爽撒。
(2) 一個(gè)線程持有鎖會(huì)導(dǎo)致其它所有需要此鎖的線程掛起入蛆。
(3) 如果一個(gè)優(yōu)先級(jí)高的線程等待一個(gè)優(yōu)先級(jí)低的線程釋放鎖會(huì)導(dǎo)致優(yōu)先級(jí)倒置,引起性能風(fēng)險(xiǎn)硕勿。

volatile是不錯(cuò)的機(jī)制哨毁,但是volatile不能保證原子性。因此對(duì)于同步最終還是要回到鎖機(jī)制上來源武。
獨(dú)占鎖是一種悲觀鎖扼褪,synchronized就是一種獨(dú)占鎖,會(huì)導(dǎo)致其它所有需要鎖的線程掛起粱栖,等待持有鎖的線程釋放鎖迎捺。而另一個(gè)更加有效的鎖就是樂觀鎖。所謂樂觀鎖就是查排,每次不加鎖而是假設(shè)沒有沖突而去完成某項(xiàng)操作,如果因?yàn)闆_突失敗就重試抄沮,直到成功為止跋核。

CAS應(yīng)用
CAS有3個(gè)操作數(shù)岖瑰,內(nèi)存值V,舊的預(yù)期值A(chǔ)砂代,要修改的新值B蹋订。當(dāng)且僅當(dāng)預(yù)期值A(chǔ)和內(nèi)存值V相同時(shí),將內(nèi)存值V修改為B刻伊,否則什么都不做露戒。

參考:http://blog.csdn.net/u014082714/article/details/50825597

8.接口和抽象類的區(qū)別,什么時(shí)候使用

(1) abstract class 在 Java 語(yǔ)言中表示的是一種繼承關(guān)系捶箱,一個(gè)類只能使用一次繼承關(guān)系智什。但是,一個(gè)類卻可以實(shí)現(xiàn)多個(gè)interface丁屎。

(2)在abstract class 中可以有自己的數(shù)據(jù)成員荠锭,也可以有非abstarct的成員方法,而在interface中晨川,只能夠有靜態(tài)的不能被修改的數(shù)據(jù)成員(也就是必須是static final的证九,不過在 interface中一般不定義數(shù)據(jù)成員),所有的成員方法都是abstract的共虑。

(3) abstract class和interface所反映出的設(shè)計(jì)理念不同愧怜。其實(shí)abstract class表示的是"is-a"關(guān)系,interface表示的是"like-a"關(guān)系妈拌。

(4) 實(shí)現(xiàn)抽象類和接口的類必須實(shí)現(xiàn)其中的所有方法拥坛。抽象類中可以有非抽象方法。接口中則不能有實(shí)現(xiàn)方法供炎。

(5) 接口中定義的變量默認(rèn)是public static final 型渴逻,且必須給其初值,所以實(shí)現(xiàn)類中不能重新定義音诫,也不能改變其值惨奕。

(6) 抽象類中的變量默認(rèn)是 friendly 型,其值可以在子類中重新定義竭钝,也可以重新賦值梨撞。

(7) 接口中的方法默認(rèn)都是 public,abstract 類型的。

9.JVM類加載機(jī)制

(1) 裝載:查找和導(dǎo)入Class文件香罐;
四個(gè)類加載器:
(a) Bootstrap ClassLoader是在JVM開始運(yùn)行的時(shí)候加載java的核心類
(b) Extension ClassLoader是用來加載擴(kuò)展類卧波,即/lib/ext中的類
(c) AppClassLoader用來加載Classpath的類,是和我們關(guān)系最密切的類
(d) URLClassLoader用來加載網(wǎng)絡(luò)上遠(yuǎn)程的類

(2) 鏈接:把類的二進(jìn)制數(shù)據(jù)合并到JRE中庇茫;
(a)校驗(yàn):檢查載入Class文件數(shù)據(jù)的正確性港粱;
(b)準(zhǔn)備:給類的靜態(tài)變量分配存儲(chǔ)空間;
(c)解析:將符號(hào)引用轉(zhuǎn)成直接引用;

(3) 初始化:對(duì)類的靜態(tài)變量查坪,靜態(tài)代碼塊執(zhí)行初始化操作


jvm.png

參考:http://blog.csdn.net/fgets/article/details/52934178

10.Spring注解

(1) @Controller
控制器Controller 負(fù)責(zé)處理由DispatcherServlet 分發(fā)的請(qǐng)求寸宏,它把用戶請(qǐng)求的數(shù)據(jù)經(jīng)過業(yè)務(wù)處理層處理之后封裝成一個(gè)Model ,然后再把該Model 返回給對(duì)應(yīng)的View 進(jìn)行展示偿曙。

(2) @RequestMapping
RequestMapping是一個(gè)用來處理請(qǐng)求地址映射的注解氮凝,可用于類或方法上。用于類上望忆,表示類中的所有響應(yīng)請(qǐng)求的方法都是以該地址作為父路徑罩阵。
@Controller 只是定義了一個(gè)控制器類,而使用@RequestMapping 注解的方法才是真正處理請(qǐng)求的處理器启摄。
如:

@RequestMapping(value = "/web/staff/order/list",
    method = RequestMethod.POST,
    produces = "application/json")

(3) @Resource和@Autowired
@Resource(byType)和@Autowired(byName)都是做bean的注入時(shí)使用稿壁,其實(shí)@Resource并不是Spring的注解,它的包是javax.annotation.Resource鞋仍,需要導(dǎo)入常摧,但是Spring支持該注解的注入。

(4) @ModelAttribute和 @SessionAttributes

(5) @PathVariable
用于將請(qǐng)求URL中的模板變量映射到功能處理方法的參數(shù)上威创,即取出uri模板中的變量作為參數(shù)落午。
如:

 @RequestMapping("/list/{userId}/{userType}")
    public String searchOrder(Model model, OrderSearchParam orderSearchParam, @PathVariable("userId") String userId, @PathVariable("userType") String userType) {...}

(6) @requestParam
@requestParam主要用于在SpringMVC后臺(tái)控制層獲取參數(shù),類似一種是request.getParameter("name")肚豺,它有三個(gè)常用參數(shù):defaultValue = "0", required = false, value = "isApp"溃斋;defaultValue 表示設(shè)置默認(rèn)值,required 銅過boolean設(shè)置是否是必須要傳入的參數(shù)吸申,value 值表示接受的傳入的參數(shù)類型梗劫。

(7) @ResponseBody
作用: 該注解用于將Controller的方法返回的對(duì)象,通過適當(dāng)?shù)腍ttpMessageConverter轉(zhuǎn)換為指定格式后截碴,寫入到Response對(duì)象的body數(shù)據(jù)區(qū)梳侨。
使用時(shí)機(jī):返回的數(shù)據(jù)不是html標(biāo)簽的頁(yè)面,而是其他某種格式的數(shù)據(jù)時(shí)(如json日丹、xml等)使用走哺;

(8) @Component
這是一個(gè)元注解,意思是它可以用于標(biāo)注其他注解哲虾,被它標(biāo)注的注解和它起到相同或者類似的作用

(9) @Repository
用于注解dao層丙躏,在daoImpl類上面注解。

參考:https://www.cnblogs.com/leskang/p/5445698.html

11.反射機(jī)制

反射機(jī)制是java的動(dòng)態(tài)性之一

動(dòng)態(tài)語(yǔ)言是指 程序在運(yùn)行時(shí)可以改變其結(jié)構(gòu)束凑,新的函數(shù)可以引進(jìn)晒旅,已有的函數(shù)可以被刪除等結(jié)構(gòu)上的變化,如javascript汪诉,python

Java通過反射機(jī)制废恋,可以在程序運(yùn)行時(shí)加載,探知和使用編譯期間完全未知的類,并且可以生成相關(guān)類對(duì)象實(shí)例拴签,從而可以調(diào)用其方法或則改變某個(gè)屬性值孝常。所以JAVA也可以算得上是一個(gè)半動(dòng)態(tài)的語(yǔ)言。

參考:http://blog.csdn.net/xu__cg/article/details/52882023

12.JVM內(nèi)存管理機(jī)制

(1) 方法區(qū)
方法區(qū)存放了要加載的類的信息(如類名蚓哩,修飾符)、類中的靜態(tài)變量上渴、final定義的常量岸梨、類中的field、方法信息

(2)堆區(qū)
在JVM所管理的內(nèi)存中稠氮,堆區(qū)是最大的一塊曹阔,堆區(qū)也是JavaGC機(jī)制所管理的主要內(nèi)存區(qū)域,堆區(qū)由所有線程共享隔披,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建赃份。堆區(qū)用來存儲(chǔ)對(duì)象實(shí)例及數(shù)組值,可以認(rèn)為java中所有通過new創(chuàng)建的對(duì)象都在此分配奢米。

(3)本地方法棧
用于支持native方法的執(zhí)行抓韩,存儲(chǔ)了每個(gè)native方法調(diào)用的狀態(tài)。本地方法棧和虛擬機(jī)方法棧運(yùn)行機(jī)制一致鬓长,它們唯一的區(qū)別就是谒拴,虛擬機(jī)棧是執(zhí)行Java方法的,而本地方法棧是用來執(zhí)行native方法的涉波,在很多虛擬機(jī)中(如Sun的JDK默認(rèn)的HotSpot虛擬機(jī))英上,會(huì)將本地方法棧與虛擬機(jī)棧放在一起使用。

(4)虛擬機(jī)棧
占用的是操作系統(tǒng)內(nèi)存啤覆,每個(gè)線程都對(duì)應(yīng)著一個(gè)虛擬機(jī)棧苍日,它是線程私有的,而且分配非常高效窗声。一個(gè)線程的每個(gè)方法在執(zhí)行的同時(shí)相恃,都會(huì)創(chuàng)建一個(gè)棧幀(Statck Frame),棧幀中存儲(chǔ)的有局部變量表嫌佑、操作站豆茫、動(dòng)態(tài)鏈接、方法出口等屋摇,當(dāng)方法被調(diào)用時(shí)揩魂,棧幀在JVM棧中入棧,當(dāng)方法執(zhí)行完成時(shí)炮温,棧幀出棧火脉。

(5)程序計(jì)算器
一個(gè)比較小的內(nèi)存區(qū)域,可能是CPU寄存器或者操作系統(tǒng)內(nèi)存,其主要用于指示當(dāng)前線程所執(zhí)行的字節(jié)碼執(zhí)行到了第幾行倦挂,可以理解為是當(dāng)前線程的行號(hào)指示器畸颅。

13.JVM垃圾回收機(jī)制

堆(heap) : 他是最大的一塊區(qū)域,用于存放對(duì)象實(shí)例和數(shù)組方援,是全局共享的.
棧(stack) : 全稱為虛擬機(jī)棧没炒,主要存儲(chǔ)基本數(shù)據(jù)類型,以及對(duì)象的引用犯戏,私有線程
方法區(qū)(Method Area) : 在class被加載后的一些信息 如常量送火,靜態(tài)常量這些被放在這里,在Hotspot里面我們將它稱之為永生代
新生代先匪、老年代

(1) 作用對(duì)象:超出了作用域或引用計(jì)數(shù)為空的對(duì)象种吸;從gc root開始搜索找不到的對(duì)象,而且經(jīng)過一次標(biāo)記呀非、清理坚俗,仍然沒有復(fù)活的對(duì)象。
(2) 作用時(shí)間:eden滿了minor gc岸裙,升到老年代的對(duì)象大于老年代剩余空間full gc猖败,或者小于時(shí)被HandlePromotionFailure參數(shù)強(qiáng)制full gc;gc與非gc時(shí)間耗時(shí)超過了GCTimeRatio的限制引發(fā)OOM哥桥,調(diào)優(yōu)諸如通過NewRatio控制新生代老年代比
(復(fù)制算法:將區(qū)域分成兩部分辙浑,其中一部分作為保留空間,另一部分作為使用空間拟糕、當(dāng)發(fā)生時(shí)判呕,首先檢查使用空間里有哪些對(duì)象是存活的,檢查完之后把存活的對(duì)象復(fù)制到保留空間(這樣復(fù)制過來的好處是減少了內(nèi)存碎片送滞,如果直接在使用空間清除的話侠草,那空間會(huì)很零散)里,然后清洗使用空間犁嗅。

這個(gè)eden就相當(dāng)于是使用空間边涕,survivor就相當(dāng)于是保留空間,通常情況下eden會(huì)比survivor大的多褂微,因?yàn)閑den和survivor都是屬于新生代(還有老生代功蜓,jvm 將堆分為新生代和老生代),新生代里的對(duì)象一般都是[朝生夕死]宠蚂,所以活下來的不多式撼,所以保留空間小一些就好了)

參考:http://blog.csdn.net/cy609329119/article/details/51771953

14.內(nèi)存溢出和內(nèi)存泄露

(1) 內(nèi)存泄漏:指程序申請(qǐng)內(nèi)存后,無法釋放

(2) 內(nèi)存溢出(OOM):指程序申請(qǐng)內(nèi)存時(shí)求厕,沒有足夠的內(nèi)存供調(diào)用
(內(nèi)存泄漏的堆積最終會(huì)導(dǎo)致內(nèi)存溢出)

(3)內(nèi)存溢出原因:
(a) 內(nèi)存中加載的數(shù)據(jù)量過于龐大著隆,如一次從數(shù)據(jù)庫(kù)取出過多數(shù)據(jù)扰楼;
(b) 集合類中有對(duì)對(duì)象的引用,使用完后未清空美浦,使得JVM不能回收弦赖;
(c) 代碼中存在死循環(huán)或循環(huán)產(chǎn)生過多重復(fù)的對(duì)象實(shí)體;
(d) 使用的第三方軟件中的BUG浦辨;
(e) 啟動(dòng)參數(shù)內(nèi)存值設(shè)定的過小

15.Redis和memcached

redis:Redis是一個(gè)開源的key-value存儲(chǔ)系統(tǒng)蹬竖。與Memcached類似,Redis將大部分?jǐn)?shù)據(jù)存儲(chǔ)在內(nèi)存中流酬,支持的數(shù)據(jù)類型包括:字符串案腺、哈希表、鏈表康吵、集合、有序集合以及基于這些數(shù)據(jù)類型的相關(guān)操作访递。

memchached:高性能分布式內(nèi)存緩存服務(wù)器晦嵌。其本質(zhì)上就是一個(gè)內(nèi)存key-value數(shù)據(jù)庫(kù),但是不支持?jǐn)?shù)據(jù)的持久化拷姿,服務(wù)器關(guān)閉之后數(shù)據(jù)全部丟失惭载。

比較:
(1) Redis支持服務(wù)器端的數(shù)據(jù)操作:Redis相比Memcached來說,擁有更多的數(shù)據(jù)結(jié)構(gòu)和并支持更豐富的數(shù)據(jù)操作响巢,通常在Memcached里描滔,你需要將數(shù)據(jù)拿到客戶端來進(jìn)行類似的修改再set回去。這大大增加了網(wǎng)絡(luò)IO的次數(shù)和數(shù)據(jù)體積踪古。在Redis中含长,這些復(fù)雜的操作通常和一般的GET/SET一樣高效。所以伏穆,如果需要緩存能夠支持更復(fù)雜的結(jié)構(gòu)和操作拘泞,那么Redis會(huì)是不錯(cuò)的選擇。

(2) 內(nèi)存使用效率對(duì)比:使用簡(jiǎn)單的key-value存儲(chǔ)的話枕扫,Memcached的內(nèi)存利用率更高陪腌,而如果Redis采用hash結(jié)構(gòu)來做key-value存儲(chǔ),由于其組合式的壓縮烟瞧,其內(nèi)存利用率會(huì)高于Memcached诗鸭。

(3) 性能對(duì)比:由于Redis只使用單核,而Memcached可以使用多核参滴,所以平均每一個(gè)核上Redis在存儲(chǔ)小數(shù)據(jù)時(shí)比Memcached性能更高强岸。而在100k以上的數(shù)據(jù)中,Memcached性能要高于Redis卵洗,雖然Redis最近也在存儲(chǔ)大數(shù)據(jù)的性能上進(jìn)行優(yōu)化请唱,但是比起Memcached弥咪,還是稍有遜色。

redis使用:

public abstract class BaseRedisDao {

    /**
     * logger
     */
    private static Logger logger = LoggerFactory.getLogger(BaseRedisDao.class);


    /**
     * Redis Save
     *
     * @param key   Redis key
     * @param value Redis value
     * @return true保存成功false保存失敗
     */
    public boolean save(final String key, final String value) {
        boolean result = getRedisTemplate().execute(new RedisCallback<Boolean>() {
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] byteKey = serializer.serialize(key);
                byte[] byteValue = serializer.serialize(value);
                return connection.setNX(byteKey, byteValue);
            }
        });
        return result;
    }
}
Redis配置
# Redis默認(rèn)不是以守護(hù)進(jìn)程的方式運(yùn)行十绑,可以通過該配置項(xiàng)修改聚至,使用yes啟用守護(hù)進(jìn)程
# 啟用守護(hù)進(jìn)程后,Redis會(huì)把pid寫到一個(gè)pidfile中本橙,在/var/run/redis.pid
daemonize no

# 當(dāng)Redis以守護(hù)進(jìn)程方式運(yùn)行時(shí)扳躬,Redis默認(rèn)會(huì)把pid寫入/var/run/redis.pid文件,可以通過pidfile指定
pidfile /var/run/redis.pid

# 指定Redis監(jiān)聽端口甚亭,默認(rèn)端口為6379
# 如果指定0端口贷币,表示Redis不監(jiān)聽TCP連接
port 6379

# 綁定的主機(jī)地址
# 你可以綁定單一接口,如果沒有綁定亏狰,所有接口都會(huì)監(jiān)聽到來的連接
# bind 127.0.0.1

# 當(dāng)客戶端閑置多長(zhǎng)時(shí)間后關(guān)閉連接役纹,如果指定為0,表示關(guān)閉該功能
timeout 0

# 指定日志記錄級(jí)別暇唾,Redis總共支持四個(gè)級(jí)別:debug促脉、verbose、notice策州、warning瘸味,默認(rèn)為verbose
# debug (很多信息, 對(duì)開發(fā)/測(cè)試比較有用)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel verbose

# 日志記錄方式,默認(rèn)為標(biāo)準(zhǔn)輸出够挂,如果配置為redis為守護(hù)進(jìn)程方式運(yùn)行旁仿,而這里又配置為標(biāo)準(zhǔn)輸出,則日志將會(huì)發(fā)送給/dev/null
logfile stdout

# 設(shè)置數(shù)據(jù)庫(kù)的數(shù)量孽糖,默認(rèn)數(shù)據(jù)庫(kù)為0枯冈,可以使用select <dbid>命令在連接上指定數(shù)據(jù)庫(kù)id
# dbid是從0到‘databases’-1的數(shù)目
databases 16

# 指定在多長(zhǎng)時(shí)間內(nèi)官份,有多少次更新操作肝断,就將數(shù)據(jù)同步到數(shù)據(jù)文件抗碰,可以多個(gè)條件配合
# Save the DB on disk:
#
#   滿足以下條件將會(huì)同步數(shù)據(jù):
#   900秒(15分鐘)內(nèi)有1個(gè)更改
#   300秒(5分鐘)內(nèi)有10個(gè)更改
#   60秒內(nèi)有10000個(gè)更改
#   Note: 可以把所有“save”行注釋掉伏伐,這樣就取消同步操作了

#save 900 1
save 300 10
#save 60 10000

# 指定存儲(chǔ)至本地?cái)?shù)據(jù)庫(kù)時(shí)是否壓縮數(shù)據(jù)宽涌,默認(rèn)為yes消返,Redis采用LZF壓縮偏陪,如果為了節(jié)省CPU時(shí)間汇在,可以關(guān)閉該選項(xiàng)铡恕,但會(huì)導(dǎo)致數(shù)據(jù)庫(kù)文件變的巨大
rdbcompression yes

# 指定本地?cái)?shù)據(jù)庫(kù)文件名琢感,默認(rèn)值為dump.rdb
dbfilename dump.rdb

# 工作目錄.
# 指定本地?cái)?shù)據(jù)庫(kù)存放目錄,文件名由上一個(gè)dbfilename配置項(xiàng)指定
# 注意探熔,這里只能指定一個(gè)目錄驹针,不能指定文件名
dir ./

# 主從復(fù)制。使用slaveof從 Redis服務(wù)器復(fù)制一個(gè)Redis實(shí)例诀艰。注意柬甥,該配置僅限于當(dāng)前slave有效
# 設(shè)置當(dāng)本機(jī)為slav服務(wù)時(shí)饮六,設(shè)置master服務(wù)的ip地址及端口,在Redis啟動(dòng)時(shí)苛蒲,它會(huì)自動(dòng)從master進(jìn)行數(shù)據(jù)同步
# slaveof <masterip> <masterport>

# 當(dāng)master服務(wù)設(shè)置了密碼保護(hù)時(shí)卤橄,slav服務(wù)連接master的密碼
# 下文的“requirepass”配置項(xiàng)可以指定密碼
# masterauth <master-password>

# 設(shè)置Redis連接密碼,如果配置了連接密碼臂外,客戶端在連接Redis時(shí)需要通過auth <password>命令提供密碼窟扑,默認(rèn)關(guān)閉
# requirepass foobared

# 設(shè)置同一時(shí)間最大客戶端連接數(shù),默認(rèn)無限制漏健,Redis可以同時(shí)打開的客戶端連接數(shù)為Redis進(jìn)程可以打開的最大文件描述符數(shù)嚎货,
# 如果設(shè)置maxclients 0,表示不作限制蔫浆。當(dāng)客戶端連接數(shù)到達(dá)限制時(shí)殖属,Redis會(huì)關(guān)閉新的連接并向客戶端返回max Number of clients reached錯(cuò)誤信息
# maxclients 128

# 指定Redis最大內(nèi)存限制,Redis在啟動(dòng)時(shí)會(huì)把數(shù)據(jù)加載到內(nèi)存中瓦盛,達(dá)到最大內(nèi)存后忱辅,Redis會(huì)先嘗試清除已到期或即將到期的Key,
# 當(dāng)此方法處理后谭溉,仍然到達(dá)最大內(nèi)存設(shè)置,將無法再進(jìn)行寫入操作橡卤,但仍然可以進(jìn)行讀取操作扮念。
# Redis新的vm機(jī)制,會(huì)把Key存放內(nèi)存碧库,Value會(huì)存放在swap區(qū)
# maxmemory <bytes>

# 指定是否在每次更新操作后進(jìn)行日志記錄柜与,Redis在默認(rèn)情況下是異步的把數(shù)據(jù)寫入磁盤,如果不開啟嵌灰,可能會(huì)在斷電時(shí)導(dǎo)致一段時(shí)間內(nèi)的數(shù)據(jù)丟失弄匕。
# 因?yàn)閞edis本身同步數(shù)據(jù)文件是按上面save條件來同步的,所以有的數(shù)據(jù)會(huì)在一段時(shí)間內(nèi)只存在于內(nèi)存中沽瞭。默認(rèn)為no
appendonly no
...

參考:https://www.cnblogs.com/zxtceq/p/7676911.html

16.MySQL的讀寫分離

可通過添加時(shí)間戳字段t迁匠,update時(shí)where t=XXX,匹配不到說明該條記錄已被修改驹溃,需重新查找該條記錄并帶入新的t值城丧;若有主從不可在sql中更新t=now(),因?yàn)橹鲝臄?shù)據(jù)庫(kù)存在時(shí)間差豌鹤,會(huì)導(dǎo)致數(shù)據(jù)不一致亡哄,需在java中帶入t值

17.MySQL的主從數(shù)據(jù)庫(kù)

(1) 主從搭建
參考:http://www.reibang.com/p/99f8aaa82f96
(2) 保證一致性(若檢測(cè)到數(shù)據(jù)庫(kù)數(shù)據(jù)不一致)
(a) 直接在主庫(kù)上將數(shù)據(jù)mysqlkdump出來,然后再灌進(jìn)從庫(kù)布疙。但是這樣做有一個(gè)缺陷蚊惯,如果在你dump出數(shù)據(jù)和灌入slave的過程中master的這張表又發(fā)生了變化怎么辦呢愿卸?而且有時(shí)候這樣做的代價(jià)可能會(huì)很高,比如有一個(gè)壹佰萬行的表上只有一行數(shù)據(jù)不一樣截型。
(b) percona toolkit的一個(gè)工具叫pt-table-sync可以解決上面的問題趴荸。
參照:http://blog.sina.com.cn/s/blog_c2839d2a0102wl54.html

18.sql的優(yōu)化

參考:http://blog.csdn.net/jie_liang/article/details/77340905

19.http請(qǐng)求/響應(yīng)報(bào)文結(jié)構(gòu)

HTTP請(qǐng)求報(bào)文

一個(gè)HTTP請(qǐng)求報(bào)文由四個(gè)部分組成:請(qǐng)求行、請(qǐng)求頭部菠劝、空行赊舶、請(qǐng)求數(shù)據(jù)。
(1) 請(qǐng)求行
請(qǐng)求行由請(qǐng)求方法字段赶诊、URL字段和HTTP協(xié)議版本字段3個(gè)字段組成笼平,它們用空格分隔。比如 GET /data/info.html HTTP/1.1
(2) 請(qǐng)求頭部
HTTP客戶程序(例如瀏覽器)舔痪,向服務(wù)器發(fā)送請(qǐng)求的時(shí)候必須指明請(qǐng)求類型(一般是GET或者 POST)寓调。如有必要,客戶程序還可以選擇發(fā)送其他的請(qǐng)求頭锄码。大多數(shù)請(qǐng)求頭并不是必需的夺英,但Content-Length除外。對(duì)于POST請(qǐng)求來說 Content-Length必須出現(xiàn)
(3) 空行
它的作用是通過一個(gè)空行滋捶,告訴服務(wù)器請(qǐng)求頭部到此為止痛悯。
(4) 請(qǐng)求數(shù)據(jù)
若方法字段是GET,則此項(xiàng)為空重窟,沒有數(shù)據(jù)
若方法字段是POST,則通常來說此處放置的就是要提交的數(shù)據(jù)

http請(qǐng)求報(bào)文.png

HTTP響應(yīng)報(bào)文

同樣的载萌,HTTP響應(yīng)報(bào)文也由三部分組成:響應(yīng)行、響應(yīng)頭巡扇、響應(yīng)體
(1) 響應(yīng)行
響應(yīng)行一般由協(xié)議版本扭仁、狀態(tài)碼及其描述組成 比如 HTTP/1.1 200 OK
其中協(xié)議版本HTTP/1.1或者HTTP/1.0,200就是它的狀態(tài)碼厅翔,OK則為它的描述乖坠。
常用404(意味著你請(qǐng)求的資源在web服務(wù)器中沒有)403(服務(wù)器拒絕訪問,權(quán)限不夠)
500~599:服務(wù)器端出現(xiàn)錯(cuò)誤刀闷,常用500
(2) 響應(yīng)頭
響應(yīng)頭用于描述服務(wù)器的基本信息熊泵,以及數(shù)據(jù)的描述,服務(wù)器通過這些數(shù)據(jù)的描述信息甸昏,可以通知客戶端如何處理等一會(huì)兒它回送的數(shù)據(jù)戈次。
(3) 響應(yīng)體
響應(yīng)體就是響應(yīng)的消息體,如果是純數(shù)據(jù)就是返回純數(shù)據(jù)筒扒,如果請(qǐng)求的是HTML頁(yè)面怯邪,那么返回的就是HTML代碼,如果是JS就是JS代碼花墩,如此之類悬秉。


http響應(yīng)報(bào)文.png

20.http三次握手和四次揮手

TCP(Transmission Control Protocol) 傳輸控制協(xié)議
TCP是主機(jī)對(duì)主機(jī)層的傳輸控制協(xié)議澄步,提供可靠的連接服務(wù),采用三次握手確認(rèn)建立一個(gè)連接:

image.png

參考:http://blog.csdn.net/yanxinrui0027/article/details/70243665

21.Linux常用命令

//查看java進(jìn)程          
ps -ef|grep java

//啟動(dòng)服務(wù)
nohup java -jar sostar-1.0.jar >console.log&

//查看日志文件
tail -f console.log

//卸載XXX包
adb uninstall com.house365.xiaomifeng

//查找占用
netstat -aon | findstr "5037"

//查看占用pid的進(jìn)程名稱
tasklist | findstr "6128" 

//殺進(jìn)程
taskkill /f /t /javaw.exe  

//macos解除安全
sudo spctl --master-disable

//jar包運(yùn)行
nohup java -jar sostar-1.0.jar  --spring.profiles.active=test >console.log &
nohup java -jar sostar-1.0.jar  --spring.profiles.active=pro>console.log &
nohup  java -jar -Xms6144m -Xmx6144m -Xmn1536m  sostar-1.0.jar  --spring.profiles.active=pro>console.log& 

//Mybatis 自動(dòng)生成文件
[Java](http://lib.csdn.net/base/java "Java 知識(shí)庫(kù)") -jar mybatis-generator-core-1.3.2.jar -configfile generatorConfig.xml -overwrite  

//查看進(jìn)程堆棧
 jmap -dump:live,format=b,file=heap.dmp 5699
 jmap -dump:format=b,file=201709251725 5699

22.深入理解String和泌、StringBuffrt村缸、StringBuilder

(1) 三者在執(zhí)行速度方面的比較:StringBuilder > StringBuffer > String

(2) StringBuffer做了同步處理,是線程安全的武氓,StringBuilder是非線程安全的梯皿。

(3) String和StringBuffer主要有2個(gè)區(qū)別:
(a) String類對(duì)象為不可變對(duì)象,一旦修改了String對(duì)象的值县恕,隱性重新創(chuàng)建了一個(gè)新的對(duì)象东羹,釋放原String對(duì)象,StringBuffer類對(duì)象為可修改對(duì)象忠烛,可以通過append()方法來修改值
(b) String類的性能遠(yuǎn)不如StringBuffer類属提。

(4) String:
(a) 是對(duì)象不是原始類型,是引用類型美尸。
(b) String 是final類冤议,不能被繼承,一旦被創(chuàng)建,就不能修改它的值.
(c) 底層用char[]來實(shí)現(xiàn)师坎。
(d) 在用”+”進(jìn)行字符串連接的時(shí)候恕酸,底層是新建一個(gè)String對(duì)象,通過新建一個(gè)StringBuilder或StringBuffer對(duì)象胯陋,調(diào)用其append方法尸疆,然后調(diào)用toString方法(在調(diào)用toString方法的時(shí)候會(huì)再創(chuàng)建一個(gè)String對(duì)象),返回給新建的String對(duì)象惶岭。其中會(huì)頻繁的創(chuàng)建新對(duì)象,增加了虛擬機(jī)GC的工作量犯眠,頻繁字符串連接的時(shí)候不推薦使用按灶。

(5)StringBuffer:
(a) 是一個(gè)可變對(duì)象,當(dāng)對(duì)他進(jìn)行修改的時(shí)候不會(huì)像String那樣重新建立對(duì)象。
(b) 底層用char[]來實(shí)現(xiàn)筐咧。
(c) 它只能通過構(gòu)造函數(shù)來創(chuàng)建:

StringBuffer sb1 = new StringBuffer(); //創(chuàng)建一個(gè)長(zhǎng)度為16的StringBuffer對(duì)象鸯旁,內(nèi)容為空。  
StringBuffer sb2 = new StringBuffer(10); //創(chuàng)建一個(gè)長(zhǎng)度為10+16的StringBuffer對(duì)象量蕊,內(nèi)容為空铺罢。  
StringBuffer sb3 = new StringBuffer("abc"); //創(chuàng)建一個(gè)長(zhǎng)度為3+16的StringBuffer對(duì)象。  

(d) 對(duì)象被建立以后,在內(nèi)存中就會(huì)分配內(nèi)存空間,并初始保存一個(gè)null.向StringBuffer中賦值的時(shí)候可以通過它的append()方法.
sb.append("hello");
在調(diào)用append()方法的時(shí)候會(huì)先判斷StringBuffer底層char[]的長(zhǎng)度残炮,如果長(zhǎng)度不夠用韭赘,就對(duì)char[]進(jìn)行擴(kuò)展,新長(zhǎng)度為原來長(zhǎng)度的2倍+2势就。

(6) 總結(jié)
(a) 在字符串連接操作中StringBuffer的效率要比String高泉瞻。
(b) 如果沒有頻繁的字符串連接脉漏,可以用String,如果有頻繁的字符串連接袖牙,推薦用StringBuffer(線程安全)或者StringBuilder(非線程安全)侧巨。
(c) StringBuffer之間的比較,要先調(diào)用toString()方法鞭达,再調(diào)用equals()方法作比較司忱。

23.redis和mysql的同步問題

方法1:

mysql 同步到redis:解析mysql的binlog,然后做同步處理畴蹭,可以使用的庫(kù)有:open-replicatorhttps://github.com/whitesock/open-replicator

方法2:

同步redis數(shù)據(jù)到mysql:(https://github.com/leonchen83/redis-replicator

redis讀取速度快坦仍,也沒有必要把所有的數(shù)據(jù)都放到redis里面,redis里面只放使用頻繁撮胧,用戶操作量較大的數(shù)據(jù)桨踪,或者用戶近期使用的數(shù)據(jù)。解決辦法:
(a) 讀取數(shù)據(jù)的時(shí)候先從redis里面查芹啥,若沒有锻离,再去數(shù)據(jù)庫(kù)查,同時(shí)寫到redis里面墓怀,并且要設(shè)置失效時(shí)間汽纠。
(b) 存數(shù)據(jù)的時(shí)候要具體情況具體分析,可以選擇同時(shí)插到數(shù)據(jù)庫(kù)和redis(要是存放到redis中傀履,最好設(shè)置失效時(shí)間)虱朵,也可以選擇直接插到數(shù)據(jù)庫(kù)里面,少考慮一些問題钓账。

參考:https://blog.csdn.net/Luomingkui1109/article/details/78403710

24.線程池參數(shù)問題

線程池的實(shí)現(xiàn)ThreadPoolExecutor
(1) corePoolSize
核心池的大小

(2) maxPoolSize
大于該值碴犬,表示已超出線程池的處理能力,線程池會(huì)拒絕處理任務(wù)而拋出異常

(3) keepAliveTime
表示線程沒有任務(wù)執(zhí)行時(shí)最多保持多久時(shí)間會(huì)終止梆暮。默認(rèn)情況下服协,只有當(dāng)線程池中的線程數(shù)大于corePoolSize時(shí),keepAliveTime才會(huì)起作用啦粹,直到線程池中的線程數(shù)不大于corePoolSize偿荷,即當(dāng)線程池中的線程數(shù)大于corePoolSize時(shí),如果一個(gè)線程空閑的時(shí)間達(dá)到keepAliveTime唠椭,則會(huì)終止跳纳,直到線程池中的線程數(shù)不超過corePoolSize。但是如果調(diào)用了allowCoreThreadTimeOut(boolean)方法贪嫂,在線程池中的線程數(shù)不大于corePoolSize時(shí)寺庄,keepAliveTime參數(shù)也會(huì)起作用,直到線程池中的線程數(shù)為0;
unit keepAliveTime的單位

(4) allowCoreThreadTimeout
是否允許核心線程空閑退出铣揉,默認(rèn)值為false饶深。

(5) workQueue
三種隊(duì)列
如果運(yùn)行的線程少于 corePoolSize,則 Executor始終首選添加新的線程逛拱,而不進(jìn)行排隊(duì)敌厘。(如果當(dāng)前運(yùn)行的線程小于corePoolSize,則任務(wù)根本不會(huì)存放添加到queue中朽合,而是直接抄家伙(thread)開始運(yùn)行)
如果運(yùn)行的線程等于或多于 corePoolSize俱两,則 Executor始終首選將請(qǐng)求加入隊(duì)列,而不添加新的線程曹步。
如果無法將請(qǐng)求加入隊(duì)列宪彩,則創(chuàng)建新的線程,除非創(chuàng)建此線程超出 maximumPoolSize讲婚,在這種情況下尿孔,任務(wù)將被拒絕。

(a) 直接提交 SynchronousQueue
(b) 無界隊(duì)列 LinkedBlockingQueue
(c) 有界隊(duì)列 ArrayBlockingQueue
參考:https://www.oschina.net/question/565065_86540

(6)4種策略
(a)CallerRunsPolicy:線程調(diào)用運(yùn)行該任務(wù)的 execute 本身筹麸。此策略提供簡(jiǎn)單的反饋控制機(jī)制活合,能夠減緩新任務(wù)的提交速度。
(b)DiscardPolicy:不能執(zhí)行的任務(wù)將被刪除
(c)AbortPolicy:處理程序遭到拒絕將拋出運(yùn)行時(shí)RejectedExecutionException
(d)DiscardOldestPolicy:如果執(zhí)行程序尚未關(guān)閉物赶,則位于工作隊(duì)列頭部的任務(wù)將被刪除白指,然后重試執(zhí)行程序(如果再次失敗,則重復(fù)此過程)

線程池按以下行為執(zhí)行任務(wù)
(1) 當(dāng)線程數(shù)小于核心線程數(shù)時(shí)酵紫,創(chuàng)建線程告嘲。
(2) 當(dāng)線程數(shù)大于等于核心線程數(shù),且任務(wù)隊(duì)列未滿時(shí)奖地,將任務(wù)放入任務(wù)隊(duì)列橄唬。
(3) 當(dāng)線程數(shù)大于等于核心線程數(shù),且任務(wù)隊(duì)列已滿
(a) 若線程數(shù)小于最大線程數(shù)参歹,創(chuàng)建線程
(b) 若線程數(shù)等于最大線程數(shù)仰楚,拋出異常,拒絕任務(wù)
例子:
  假如有一個(gè)工廠泽示,工廠里面有10個(gè)工人,每個(gè)工人同時(shí)只能做一件任務(wù)蜜氨。
  因此只要當(dāng)10個(gè)工人中有工人是空閑的械筛,來了任務(wù)就分配給空閑的工人做;
  當(dāng)10個(gè)工人都有任務(wù)在做時(shí)飒炎,如果還來了任務(wù)埋哟,就把任務(wù)進(jìn)行排隊(duì)等待;
  如果說新任務(wù)數(shù)目增長(zhǎng)的速度遠(yuǎn)遠(yuǎn)大于工人做任務(wù)的速度,那么此時(shí)工廠主管可能會(huì)想補(bǔ)救措施赤赊,比如重新招4個(gè)臨時(shí)工人進(jìn)來闯狱;
  然后就將任務(wù)也分配給這4個(gè)臨時(shí)工人做;
  如果說著14個(gè)工人做任務(wù)的速度還是不夠抛计,此時(shí)工廠主管可能就要考慮不再接收新的任務(wù)或者拋棄前面的一些任務(wù)了哄孤。
  當(dāng)這14個(gè)工人當(dāng)中有人空閑時(shí),而新任務(wù)增長(zhǎng)的速度又比較緩慢吹截,工廠主管可能就考慮辭掉4個(gè)臨時(shí)工了瘦陈,只保持原來的10個(gè)工人,畢竟請(qǐng)額外的工人是要花錢的波俄。
  這個(gè)例子中的corePoolSize就是10晨逝,而maximumPoolSize就是
14(10+4)

參考:https://www.2cto.com/kf/201711/695731.html

25.生產(chǎn)者消費(fèi)者代碼實(shí)現(xiàn)

參考:https://www.cnblogs.com/Ming8006/p/7243858.html

26.死鎖代碼實(shí)現(xiàn)

是指兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過程中,因爭(zhēng)奪資源而造成的一種互相等待的現(xiàn)象懦铺,若無外力作用捉貌,它們都將無法推進(jìn)下去。

public class MyTestSiSuo {  
    private static  Object o1 = new Object();  
    private static  Object o2 = new Object();  
    public static void main(String[] args) {  
        Thread t1 = new Thread(){  
            @Override  
            public void run(){  
                //搶占資源 o1  
                synchronized (o1) {  
                    try {  
                        Thread.sleep(1000);  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    }  
                    System.out.println("t1 ---Get o1");   
                    //需要資源o2 但是 t2 獨(dú)占(未釋放) -->互相競(jìng)爭(zhēng)資源-->死鎖  
                    synchronized(o2){  
                        System.out.println("t1 ---Get o2");  
                    }   
                }  
            }    
        };   

        Thread t2 = new Thread(){  
            @Override  
            public void run(){  
                //搶占資源o2  
                synchronized (o2) {  
                    System.out.println("t2 ---Get o2");     
                    //需要資源 o1,但是 t1 獨(dú)占(未釋放) -->互相競(jìng)爭(zhēng)資源-->死鎖  
                    synchronized (o1) {  
                        System.out.println("t2 ---Get o1");  
                    }  
                }       
            }       
        };       
        t1.start();  
        t2.start();  
    }  
}  

27.SpringMVC和Spring boot

(1) Spring MVC

提供了一種輕度耦合的方式來開發(fā)web應(yīng)用冬念。
Spring MVC是Spring的一個(gè)模塊趁窃,式一個(gè)web框架。通過Dispatcher Servlet, ModelAndView 和 View Resolver刘急,開發(fā)web應(yīng)用變得很容易棚菊。解決的問題領(lǐng)域是網(wǎng)站應(yīng)用程序或者服務(wù)開發(fā)——URL路由、Session叔汁、模板引擎统求、靜態(tài)Web資源等等。

(2) Spring Boot

Spring Boot實(shí)現(xiàn)了自動(dòng)配置据块,降低了項(xiàng)目搭建的復(fù)雜度码邻。
眾所周知Spring框架需要進(jìn)行大量的配置,Spring Boot引入自動(dòng)配置的概念另假,讓項(xiàng)目設(shè)置變得很容易像屋。Spring Boot本身并不提供Spring框架的核心特性以及擴(kuò)展功能,只是用于快速边篮、敏捷地開發(fā)新一代基于Spring框架的應(yīng)用程序己莺。也就是說,它并不是用來替代Spring的解決方案戈轿,而是和Spring框架緊密結(jié)合用于提升Spring開發(fā)者體驗(yàn)的工具凌受。同時(shí)它集成了大量常用的第三方庫(kù)配置(例如Jackson, JDBC, Mongo, Redis, Mail等等),Spring Boot應(yīng)用中這些第三方庫(kù)幾乎可以零配置的開箱即用(out-of-the-box)思杯,大部分的Spring Boot應(yīng)用都只需要非常少量的配置代碼胜蛉,開發(fā)者能夠更加專注于業(yè)務(wù)邏輯。

Spring Boot只是承載者,輔助你簡(jiǎn)化項(xiàng)目搭建過程的誊册。如果承載的是WEB項(xiàng)目领突,使用Spring MVC作為MVC框架,那么工作流程和你上面描述的是完全一樣的案怯,因?yàn)檫@部分工作是Spring MVC做的而不是Spring Boot君旦。

對(duì)使用者來說,換用Spring Boot以后殴泰,項(xiàng)目初始化方法變了于宙,配置文件變了,另外就是不需要單獨(dú)安裝Tomcat這類容器服務(wù)器了悍汛,maven打出jar包直接跑起來就是個(gè)網(wǎng)站捞魁,但你最核心的業(yè)務(wù)邏輯實(shí)現(xiàn)與業(yè)務(wù)流程實(shí)現(xiàn)沒有任何變化。

所以离咐,用最簡(jiǎn)練的語(yǔ)言概括就是:
Spring 是一個(gè)“引擎”谱俭;
Spring MVC 是基于Spring的一個(gè) MVC 框架 ;
Spring Boot 是基于Spring4的條件注冊(cè)的一套快速開發(fā)整合包宵蛀。

28.Spring boot實(shí)例創(chuàng)建

參考:https://www.cnblogs.com/moonlightL/p/7891803.html

29.動(dòng)態(tài)綁定

那些在類被加載時(shí)就已經(jīng)知道(final昆著、private、static修飾的方法以及構(gòu)造函數(shù))术陶,不需對(duì)象的創(chuàng)建就能訪問的凑懂,就是靜態(tài)綁定的內(nèi)容;需要等對(duì)象創(chuàng)建出來梧宫,使用時(shí)根據(jù)堆中的實(shí)例對(duì)象的類型才進(jìn)行取用的就是動(dòng)態(tài)綁定的內(nèi)容接谨。
方法表:表中記錄了這個(gè)類定義的方法的指針,每個(gè)表項(xiàng)指向一個(gè)具體的方法代碼塘匣。如果這個(gè)類重寫了父類中的某個(gè)方法脓豪,則對(duì)應(yīng)表項(xiàng)指向新的代碼實(shí)現(xiàn)處
參考:https://www.cnblogs.com/ygj0930/p/6554103.html

30.SpringMVC深入

spring工作原理:

(1)spring mvc請(qǐng)所有的請(qǐng)求都提交給DispatcherServlet,它會(huì)委托應(yīng)用系統(tǒng)的其他模塊負(fù)責(zé)負(fù)責(zé)對(duì)請(qǐng)求進(jìn)行真正的處理工作。
(2)DispatcherServlet查詢一個(gè)或多個(gè)HandlerMapping,找到處理請(qǐng)求的Controller.
(3)DispatcherServlet請(qǐng)請(qǐng)求提交到目標(biāo)Controller
(4)Controller進(jìn)行業(yè)務(wù)邏輯處理后忌卤,會(huì)返回一個(gè)ModelAndView
(5)Dispathcher查詢一個(gè)或多個(gè)ViewResolver視圖解析器,找到ModelAndView對(duì)象指定的視圖對(duì)象
(6)視圖對(duì)象負(fù)責(zé)渲染返回給客戶端扫夜。
參考:https://www.cnblogs.com/angelye/p/7506566.html
參考:https://www.cnblogs.com/baiduligang/p/4247164.html

31.事務(wù)

(1) 原子性:事務(wù)是數(shù)據(jù)庫(kù)的邏輯工作單位,而且是必須是原子工作單位驰徊,對(duì)于其數(shù)據(jù)修改笤闯,要么全部執(zhí)行,要么全部不執(zhí)行棍厂。
(2) 一致性:事務(wù)在完成時(shí)颗味,必須是所有的數(shù)據(jù)都保持一致狀態(tài)。在相關(guān)數(shù)據(jù)庫(kù)中勋桶,所有規(guī)則都必須應(yīng)用于事務(wù)的修改脱衙,以保持所有數(shù)據(jù)的完整性。
(3) 隔離性:在一個(gè)事務(wù)提交之前例驹,對(duì)其它事務(wù)不可見捐韩;
(4) 持久性:一個(gè)事務(wù)一旦提交,事物的操作便永久性的保存在DB中鹃锈。即使此時(shí)再執(zhí)行回滾操作也不能撤消所做的更改荤胁。

7種傳播級(jí)別:

l PROPAGATION_REQUIRED

默認(rèn)的Spring事務(wù)傳播級(jí)別,使用該級(jí)別的特點(diǎn)是:如果上下文中已經(jīng)存在事務(wù)屎债,那么就加入到事務(wù)中執(zhí)行仅政;如果當(dāng)前上下文中不存在事務(wù),則新建事務(wù)執(zhí)行盆驹。所以這個(gè)級(jí)別通常能滿足處理大多數(shù)的業(yè)務(wù)場(chǎng)景圆丹。

l PROPAGATION_SUPPORTS

從字面意思就知道,supports躯喇,支持辫封,該傳播級(jí)別的特點(diǎn)是:如果上下文存在事務(wù),則支持事務(wù)加入事務(wù)廉丽,如果沒有事務(wù)倦微,則使用非事務(wù)的方式執(zhí)行。所以說正压,并非所有的包含在TransactionTemplate.execute方法中的代碼都會(huì)有事務(wù)支持欣福。這個(gè)通常是用來處理那些并非原子性的非核心業(yè)務(wù)邏輯操作。應(yīng)用場(chǎng)景較少焦履。

l PROPAGATION_MANDATORY

該級(jí)別的事務(wù)要求上下文中必須要存在事務(wù)拓劝,否則就會(huì)拋出異常!配置該方式的傳播級(jí)別是有效的控制上下文調(diào)用代碼遺漏添加事務(wù)控制的保證手段裁良。比如一段代碼不能單獨(dú)被調(diào)用執(zhí)行凿将,但是一旦被調(diào)用,就必須有事務(wù)包含的情況价脾,就可以使用這個(gè)傳播級(jí)別牧抵。

l PROPAGATION_REQUIRES_NEW

從字面即可知道,new侨把,每次都要一個(gè)新事務(wù)犀变,該傳播級(jí)別的特點(diǎn)是:每次都會(huì)新建一個(gè)事務(wù),并且同時(shí)將上下文中的事務(wù)掛起秋柄,執(zhí)行當(dāng)前新建事務(wù)完成以后获枝,上下文事務(wù)恢復(fù)再執(zhí)行。

這是一個(gè)很有用的傳播級(jí)別骇笔,舉一個(gè)應(yīng)用場(chǎng)景:現(xiàn)在有一個(gè)發(fā)送100個(gè)紅包的操作省店,在發(fā)送之前嚣崭,要做一些系統(tǒng)的初始化、驗(yàn)證懦傍、數(shù)據(jù)記錄操作雹舀,然后發(fā)送100封紅包,然后再記錄發(fā)送日志粗俱,發(fā)送日志要求100%的準(zhǔn)確说榆,如果日志不準(zhǔn)確,那么整個(gè)父事務(wù)邏輯需要回滾寸认。

怎么處理整個(gè)業(yè)務(wù)需求呢签财?就是通過這個(gè)PROPAGATION_REQUIRES_NEW級(jí)別的事務(wù)傳播控制就可以完成。發(fā)送紅包的子事務(wù)不會(huì)直接影響到父事務(wù)的提交和回滾偏塞。

l PROPAGATION_NOT_SUPPORTED

這個(gè)也可以從字面得知唱蒸,not supported,不支持灸叼,當(dāng)前級(jí)別的特點(diǎn)是:若上下文中存在事務(wù)油宜,則掛起事務(wù),執(zhí)行當(dāng)前邏輯怜姿,結(jié)束后恢復(fù)上下文的事務(wù)慎冤。

這個(gè)級(jí)別有什么好處?可以幫助你將事務(wù)盡可能的縮小沧卢。我們知道一個(gè)事務(wù)越大蚁堤,它存在的風(fēng)險(xiǎn)也就越多。所以在處理事務(wù)的過程中但狭,要保證盡可能的縮小范圍披诗。比如一段代碼,是每次邏輯操作都必須調(diào)用的立磁,比如循環(huán)1000次的某個(gè)非核心業(yè)務(wù)邏輯操作呈队。這樣的代碼如果包在事務(wù)中,勢(shì)必造成事務(wù)太大唱歧,導(dǎo)致出現(xiàn)一些難以考慮周全的異常情況宪摧,所以事務(wù)的這個(gè)傳播級(jí)別就派上用場(chǎng)了。用當(dāng)前級(jí)別的事務(wù)模板包含起來就可以了。

l PROPAGATION_NEVER

該事務(wù)更嚴(yán)格,上面一個(gè)事務(wù)傳播級(jí)別只是不支持而已佛析,有事務(wù)就掛起,而PROPAGATION_NEVER傳播級(jí)別要求上下文中不能存在事務(wù)沿彭,一旦有事務(wù),就拋出runtime異常尖滚,強(qiáng)制停止執(zhí)行喉刘!這個(gè)級(jí)別上輩子跟事務(wù)有仇瞧柔。

l PROPAGATION_NESTED

從字面也可知道,nested睦裳,嵌套級(jí)別事務(wù)非剃。該傳播級(jí)別的特征是:如果上下文中存在事務(wù),則嵌套事務(wù)執(zhí)行推沸,如果不存在事務(wù),則新建事務(wù)券坞。

4種事務(wù)的隔離級(jí)別

l SERIALIZABLE

最嚴(yán)格的級(jí)別鬓催,事務(wù)串行執(zhí)行,資源消耗最大恨锚。

l REPEATABLE_READ

保證了一個(gè)事務(wù)不會(huì)修改已經(jīng)由另一個(gè)事務(wù)讀取但未提交(回滾)的數(shù)據(jù)宇驾。避免了“臟讀取”和“不可重復(fù)讀取”的情況,但是帶來了更多的性能損失猴伶。

l READ_COMMITTED

大多數(shù)主流數(shù)據(jù)庫(kù)的默認(rèn)事務(wù)等級(jí)课舍,保證了一個(gè)事務(wù)不會(huì)讀到另一個(gè)并行事務(wù)已修改但未提交的數(shù)據(jù),避免了“臟讀取”他挎。該級(jí)別適用于大多數(shù)系統(tǒng)筝尾。

l READ_UNCOMMITTED

保證了讀取過程中不會(huì)讀取到非法數(shù)據(jù)。

一些術(shù)語(yǔ)

l 臟讀(Dirty Reads)

所謂的臟讀办桨,其實(shí)就是讀到了別的事務(wù)回滾前的臟數(shù)據(jù)筹淫。比如事務(wù)B執(zhí)行過程中修改了數(shù)據(jù)X,在未提交前呢撞,事務(wù)A讀取了X损姜,而事務(wù)B卻回滾了,這樣事務(wù)A就形成了臟讀殊霞。

l 不可重復(fù)讀(Non-RepeatableReads)

不可重復(fù)讀字面含義已經(jīng)很明了了摧阅,比如事務(wù)A首先讀取了一條數(shù)據(jù),然后執(zhí)行邏輯的時(shí)候绷蹲,事務(wù)B將這條數(shù)據(jù)改變了棒卷,然后事務(wù)A再次讀取的時(shí)候,發(fā)現(xiàn)數(shù)據(jù)不匹配了祝钢,就是所謂的不可重復(fù)讀了娇跟。

l 幻讀

小的時(shí)候數(shù)手指,第一次數(shù)十10個(gè)太颤,第二次數(shù)是11個(gè)苞俘,怎么回事?產(chǎn)生幻覺了龄章?

幻讀也是這樣子吃谣,事務(wù)A首先根據(jù)條件索引得到10條數(shù)據(jù)乞封,然后事務(wù)B改變了數(shù)據(jù)庫(kù)一條數(shù)據(jù),導(dǎo)致也符合事務(wù)A當(dāng)時(shí)的搜索條件岗憋,這樣事務(wù)A再次搜索發(fā)現(xiàn)有11條數(shù)據(jù)了肃晚,就產(chǎn)生了幻讀。

參考:https://blog.csdn.net/sinat_33536912/article/details/51200630
https://blog.csdn.net/yang1982_0907/article/details/44408809

32.zookeeper

ZooKeeper是一個(gè)分布式的仔戈,開放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù)关串,是Google的Chubby一個(gè)開源的實(shí)現(xiàn),它是集群的管理者监徘,監(jiān)視著集群中各個(gè)節(jié)點(diǎn)的狀態(tài)根據(jù)節(jié)點(diǎn)提交的反饋進(jìn)行下一步合理操作晋修。最終,將簡(jiǎn)單易用的接口和性能高效凰盔、功能穩(wěn)定的系統(tǒng)提供給用戶

Zookeeper的特點(diǎn)
(1) 最終一致性:為客戶端展示同一視圖墓卦,這是zookeeper最重要的功能。
(2) 可靠性:如果消息被到一臺(tái)服務(wù)器接受户敬,那么它將被所有的服務(wù)器接受落剪。
(3) 實(shí)時(shí)性:Zookeeper不能保證兩個(gè)客戶端能同時(shí)得到剛更新的數(shù)據(jù),如果需要最新數(shù)據(jù)尿庐,應(yīng)該在讀數(shù)據(jù)之前調(diào)用sync()接口忠怖。
(4) 等待無關(guān)(wait-free):慢的或者失效的client不干預(yù)快速的client的請(qǐng)求。
(5) 原子性:更新只能成功或者失敗抄瑟,沒有中間狀態(tài)脑又。
(6) 順序性:所有Server,同一消息發(fā)布順序一致锐借。

Zookeeper工作原理
Zookeeper 的核心是原子廣播问麸,這個(gè)機(jī)制保證了各個(gè)Server之間的同步。實(shí)現(xiàn)這個(gè)機(jī)制的協(xié)議叫做Zab協(xié)議钞翔。Zab協(xié)議有兩種模式严卖,它們分別是恢復(fù)模式(選主)和廣播模式(同步)。當(dāng)服務(wù)啟動(dòng)或者在領(lǐng)導(dǎo)者崩潰后布轿,Zab就進(jìn)入了恢復(fù)模式哮笆,當(dāng)領(lǐng)導(dǎo)者被選舉出來,且大多數(shù)Server完成了和 leader的狀態(tài)同步以后汰扭,恢復(fù)模式就結(jié)束了稠肘。狀態(tài)同步保證了leader和Server具有相同的系統(tǒng)狀態(tài)。
為了保證事務(wù)的順序一致性萝毛,zookeeper采用了遞增的事務(wù)id號(hào)(zxid)來標(biāo)識(shí)事務(wù)项阴。所有的提議(proposal)都在被提出的時(shí)候加上了zxid。實(shí)現(xiàn)中zxid是一個(gè)64位的數(shù)字笆包,它高32位是epoch用來標(biāo)識(shí)leader關(guān)系是否改變环揽,每次一個(gè)leader被選出來略荡,它都會(huì)有一個(gè)新的epoch,標(biāo)識(shí)當(dāng)前屬于那個(gè)leader的統(tǒng)治時(shí)期歉胶。低32位用于遞增計(jì)數(shù)汛兜。

33.阻塞線程

sleep()

使當(dāng)前線程(即調(diào)用該方法的線程)暫停執(zhí)行一段時(shí)間,讓其他線程有機(jī)會(huì)繼續(xù)執(zhí)行通今,但它并不釋放對(duì)象鎖粥谬。也就是說如果有synchronized同步快,其他線程仍然不能訪問共享數(shù)據(jù)辫塌。注意該方法要捕捉異常漏策。
sleep()可以使低優(yōu)先級(jí)的線程得到執(zhí)行的機(jī)會(huì),當(dāng)然也可以讓同優(yōu)先級(jí)璃氢、高優(yōu)先級(jí)的線程有執(zhí)行的機(jī)會(huì)。

join()

使調(diào)用該方法的線程在此之前執(zhí)行完畢狮辽,也就是等待該方法的線程執(zhí)行完畢后再往下繼續(xù)執(zhí)行一也。注意該方法也需要捕捉異常。
//在一個(gè)線程中調(diào)用other.join(),將等待other執(zhí)行完后才繼續(xù)本線程喉脖。

yield()

該方法與sleep()類似椰苟,只是不能由用戶指定暫停多長(zhǎng)時(shí)間,并且yield()方法只能讓同優(yōu)先級(jí)的線程有執(zhí)行的機(jī)會(huì)树叽。

wait()和notify()舆蝴、notifyAll()

協(xié)調(diào)多個(gè)線程對(duì)共享數(shù)據(jù)的存取,必須在synchronized語(yǔ)句塊內(nèi)使用
wait()方法使當(dāng)前線程暫停執(zhí)行并釋放對(duì)象鎖標(biāo)示题诵,讓其他線程可以進(jìn)入synchronized數(shù)據(jù)塊洁仗,當(dāng)前線程被放入對(duì)象等待池中。當(dāng)調(diào)用notify()方法后性锭,將從對(duì)象的等待池中移走一個(gè)任意的線程并放到鎖標(biāo)志等待池中赠潦,只有鎖標(biāo)志等待池中線程能夠獲取鎖標(biāo)志;如果鎖標(biāo)志等待池中沒有線程草冈,則notify()不起作用她奥。
notifyAll()則從對(duì)象等待池中移走所有等待那個(gè)對(duì)象的線程并放到鎖標(biāo)志等待池中。

34.線程run和start

run(); 只是調(diào)用了一個(gè)普通方法怎棱,并沒有啟動(dòng)另一個(gè)線程哩俭,程序還是會(huì)按照順序執(zhí)行相應(yīng)的代碼。

start(); 則表示拳恋,重新開啟一個(gè)線程凡资,不必等待其他線程運(yùn)行完,只要得到cup就可以運(yùn)行該線程谬运。

把需要并行處理的代碼放在run() 中讳苦,start()啟動(dòng)線程將自動(dòng)調(diào)run()带膜,這是jvm機(jī)制決定的,并且run()方法必須是public 訪問權(quán)限鸳谜,然會(huì)類型為void

35.DispatcherServlet

主要用作職責(zé)調(diào)度工作膝藕,本身主要用于控制流程,主要職責(zé)如下:

1咐扭、文件上傳解析芭挽,如果請(qǐng)求類型是multipart將通過MultipartResolver進(jìn)行文件上傳解析;

2蝗肪、通過HandlerMapping袜爪,將請(qǐng)求映射到處理器(返回一個(gè)HandlerExecutionChain,它包括一個(gè)處理器薛闪、多個(gè)HandlerInterceptor攔截器)辛馆;

3、通過HandlerAdapter支持多種類型的處理器(HandlerExecutionChain中的處理器)豁延;

4昙篙、通過ViewResolver解析邏輯視圖名到具體視圖實(shí)現(xiàn);

5诱咏、本地化解析苔可;

6、渲染具體的視圖等袋狞;

7焚辅、如果執(zhí)行過程中遇到異常將交給HandlerExceptionResolver來解析。

36.dubbo+zookeeper分布式

參考:https://blog.csdn.net/noaman_wgs/article/details/70214612

37.ibatis和Mybatis

(1) ibatis配置sqlMapConfig.xml
如:

<sqlMapConfig>
    <settings cacheModelsEnabled="true" enhancementEnabled="true"
        lazyLoadingEnabled="false" errorTracingEnabled="true" maxRequests="32"
        maxSessions="20" maxTransactions="5" useStatementNamespaces="true" />
    <!-- 以下為代碼生成器自動(dòng)生成 -->
    <sqlMap resource="ibatis/HmcCallInfo.xml" />
    <sqlMap resource="ibatis/HmcCallInfoVitality.xml" />
    <sqlMap resource="ibatis/HmcConsultant.xml" />
    <!-- 以上為代碼生成器自動(dòng)生成 -->
</sqlMapConfig>

參考:https://blog.csdn.net/geyouchao/article/details/51354571
https://blog.csdn.net/bruce128/article/details/71914755

38.攔截器和過濾器的區(qū)別

1苟鸯、攔截器是基于java反射機(jī)制的同蜻,而過濾器是基于函數(shù)回調(diào)的。
2早处、過濾器依賴于servlet容器埃仪,而攔截器不依賴于servlet容器。
3陕赃、攔截器只能對(duì)Action請(qǐng)求起作用卵蛉,而過濾器則可以對(duì)幾乎所有請(qǐng)求起作用。
4么库、攔截器可以訪問Action上下文傻丝、值棧里的對(duì)象,而過濾器不能诉儒。
5葡缰、在Action的生命周期中,攔截器可以多次調(diào)用,而過濾器只能在容器初始化時(shí)被調(diào)用一次泛释。


image.png

39.重定向(redirect)和轉(zhuǎn)發(fā)(forward)

轉(zhuǎn)發(fā)(forward)

(1) 是服務(wù)器內(nèi)部的重定向滤愕,服務(wù)器直接訪問目標(biāo)地址的 url網(wǎng)址,把里面的東西讀取出來怜校,但是客戶端并不知道间影,因此用forward的話,客戶端瀏覽器的網(wǎng)址是不會(huì)發(fā)生變化的
(2) 關(guān)于request: 由于在整個(gè)定向的過程中用的是同一個(gè)request茄茁,因此forward會(huì)將request的信息帶到被重定向的jsp或者servlet中使用魂贬。

redirect(重定向):

(1) 是客戶端的重定向,是完全的跳轉(zhuǎn)裙顽。即服務(wù)器返回的一個(gè)url給客戶端瀏覽器付燥,然后客戶端瀏覽器會(huì)重新發(fā)送一次請(qǐng)求,到新的url里面愈犹,因此瀏覽器中顯示的url網(wǎng)址會(huì)發(fā)生變化键科。
(2) 因?yàn)檫@種方式比forward多了一次網(wǎng)絡(luò)請(qǐng)求,因此效率會(huì)低于forward漩怎。

40.java算法

參考:https://blog.csdn.net/l1028386804/article/details/51097928/

41.java設(shè)計(jì)模式

共23種
(1) 單例模式
(2) 工廠模式
(3) 生產(chǎn)者消費(fèi)者模式
(4) 觀察者模式
(5) 適配器模式
(6) 代理模式
參考:https://www.cnblogs.com/cr330326/p/5627658.html
https://blog.csdn.net/a394268045/article/details/51801258

42.java性能優(yōu)化

JVM
sql
代碼
gc
Java開發(fā)高并發(fā)的處理方法:

最基礎(chǔ)的地方做起勋颖,優(yōu)化我們寫的代碼,減少必要的資源浪費(fèi)

避免頻繁的使用new對(duì)象扬卷,對(duì)于整個(gè)應(yīng)用只需要存在一個(gè)實(shí)例的類牙言,我們可以使用單例模式酸钦。對(duì)于String連接操作怪得,使用 StringBuffer或StringBuilder,對(duì)于工具類可以通過靜態(tài)方法來訪問卑硫。

避免使用錯(cuò)誤的方式徒恋,盡量不用instanceof做條件判斷。使用java中效率高的類欢伏,比如ArrayList比Vector性能好入挣。

圖片服務(wù)器分離

對(duì)于web服務(wù)器來說,圖片是最消耗資源的硝拧,于是我們有必要把圖片與頁(yè)面進(jìn)行分離径筏,我們把圖片放到獨(dú)立的圖片服務(wù)器。這樣的架構(gòu)可以降低提供頁(yè)面訪問請(qǐng)求的服務(wù)器系統(tǒng)壓力障陶,并且可以保證系統(tǒng)不會(huì)因?yàn)閳D片的問題而崩潰滋恬。在圖片服務(wù)器上,我們可以對(duì)不同的配置進(jìn)行優(yōu)化抱究。

緩存

具體接觸過的緩存機(jī)制是hibernate的緩存機(jī)制恢氯。為了避免每次都向數(shù)據(jù)庫(kù)中取得數(shù)據(jù),我們把用戶常常訪問到的數(shù)據(jù)放到內(nèi)存中,甚至緩存十分大的時(shí)候我們可以把內(nèi)存中的緩存放到硬盤中勋拟。還有高級(jí)的分布式緩存數(shù)據(jù)庫(kù)使用勋磕,都可以增加系統(tǒng)的抗壓力。

分批傳送

在做某項(xiàng)目的時(shí)候敢靡,一次傳遞的參數(shù)太多挂滓,而且數(shù)據(jù)庫(kù)規(guī)定一次最多傳遞的參數(shù)最多是三萬條,當(dāng)時(shí)有五萬條記錄醋安,那怎么傳送呢杂彭?最終是分批傳送,電梯里一次乘不下那么多的人吓揪,會(huì)報(bào)超重的bug亲怠,那就分批把人送上去。

還有一次在考試系統(tǒng)中柠辞,如果那么多的考試人員同時(shí)提交到數(shù)據(jù)庫(kù)中团秽,數(shù)據(jù)庫(kù)的壓力增大,有時(shí)會(huì)被down掉叭首,當(dāng)時(shí)采用的方法是使用ajax異步傳輸习勤,沒有等待考生點(diǎn)擊提交按鈕的時(shí)候,就把考生的答案自動(dòng)提交焙格,這樣也避免了突然斷電考生前面做過的題出現(xiàn)丟失的現(xiàn)象图毕。

DB優(yōu)化

(a)索引的建立:建立索引要適當(dāng),如果一個(gè)表經(jīng)常用來被查詢眷唉,對(duì)于增加和修改很少被用到予颤,我們就可以為這個(gè)表建立索引,因?yàn)閷?duì)于增加和修改和刪除操作時(shí)冬阳,我們對(duì)索引的維護(hù)要大大超過索引給我們帶來的效率蛤虐。

(b)表字段的類型選擇要恰當(dāng)。包括字段的長(zhǎng)度肝陪、類型等驳庭,要根據(jù)實(shí)際存儲(chǔ)的數(shù)據(jù)進(jìn)行選擇,長(zhǎng)度不要過長(zhǎng)氯窍,否則會(huì)影響效率饲常。

(c)外鍵要慎用,因?yàn)橹麈I代表這一張表狼讨,而外鍵代表一群表贝淤,對(duì)表之間進(jìn)行了關(guān)聯(lián),在刪除修改等需要我們關(guān)聯(lián)熊楼。

(d)在數(shù)據(jù)庫(kù)操作上霹娄。 盡量使用prepareStatement能犯,少用Statement,因?yàn)镻repareStatement是進(jìn)行預(yù)編譯的犬耻。

public class PreparedStatementTest {  
    public static void main(String[] args) {  
        test_autoCommit();  
    }  
    public static  void test_autoCommit()  
    {  
        String driver="oracle.jdbc.driver.OracleDriver";  
        String url="jdbc:oracle:thin:@127.0.0.1:1521:orcl";  
        String user="briup";  
        String password="briup";  
        Connection conn=null;  
        PreparedStatement ps=null;  
        try {  
            //1踩晶、注冊(cè)驅(qū)動(dòng)  
            Class.forName(driver);  
            //2、獲取連接  
             conn= DriverManager.getConnection(url, user, password);  
             //System.out.println(conn);  
            //3枕磁、創(chuàng)建prepareStatement對(duì)象  
             String sql="insert into lover values(?,?,?)";  
             ps=conn.prepareStatement(sql);  
             //4渡蜻、執(zhí)行sql語(yǔ)句  
             ps.setInt(1,21);//代表設(shè)置給第一個(gè)?號(hào)位置的值為Int類型的21  
             ps.setString(2,"suwu150");//代表設(shè)置給第二個(gè)?號(hào)位置的值為String類型的suwu150  
             java.util.Date utilDate=new java.util.Date();//進(jìn)行類型轉(zhuǎn)換,由util類型的date轉(zhuǎn)化為sql類型的  
             ps.setDate(3, new java.sql.Date(utilDate.getTime()));  
             //ps.execute();//執(zhí)行  
             System.out.println(ps.execute());//執(zhí)行表輸出返回的結(jié)果计济,結(jié)果為false茸苇,因?yàn)闆]有返回的結(jié)果集  
             //5、處理結(jié)果集  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        finally{  
            //6沦寂、關(guān)閉資源  
            try {  
                if(ps!=null)ps.close();  
            } catch (SQLException e) {  
                e.printStackTrace();  
            }  
            try {  
                if(conn!=null)conn.close();  
            } catch (SQLException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
}  

(f)connection設(shè)置為readOnly学密,Connection是對(duì)書庫(kù)連接,屬于重量級(jí)传藏,我們使用即可腻暮。

連接池的使用,我們可以修改數(shù)據(jù)庫(kù)默認(rèn)的連接數(shù)毯侦。
參考:http://www.jb51.net/article/102831.htm

43.多線程同步

(1)同步方法:synchronized關(guān)鍵字修飾的方法

public synchronized void save(){}

注: synchronized關(guān)鍵字也可以修飾靜態(tài)方法哭靖,此時(shí)如果調(diào)用該靜態(tài)方法,將會(huì)鎖住整個(gè)類

(2)同步代碼塊 :synchronized關(guān)鍵字修飾的語(yǔ)句塊

synchronized(object){ 
}

注:同步是一種高開銷的操作侈离,因此應(yīng)該盡量減少同步的內(nèi)容试幽。
通常沒有必要同步整個(gè)方法,使用synchronized代碼塊同步關(guān)鍵代碼即可卦碾。

(3)用特殊域變量(volatile)實(shí)現(xiàn)線程同步
(a) volatile關(guān)鍵字為域變量的訪問提供了一種免鎖機(jī)制铺坞,
(b) 使用volatile修飾域相當(dāng)于告訴虛擬機(jī)該域可能會(huì)被其他線程更新,
(c) 因此每次使用該域就要重新計(jì)算蔗坯,而不是使用寄存器中的值
(d) volatile不會(huì)提供任何原子操作康震,它也不能用來修飾final類型的變量

(4)使用重入鎖實(shí)現(xiàn)線程同步
在JavaSE5.0中新增了一個(gè)java.util.concurrent包來支持同步燎含。
ReentrantLock類是可重入宾濒、互斥、實(shí)現(xiàn)了Lock接口的鎖屏箍,
它與使用synchronized方法和快具有相同的基本行為和語(yǔ)義绘梦,并且擴(kuò)展了其能力

 class Bank {

            private int account = 100;
            //需要聲明這個(gè)鎖
            private Lock lock = new ReentrantLock();
            public int getAccount() {
                return account;
            }
            //這里不再需要synchronized 
            public void save(int money) {
                lock.lock();
                try{
                    account += money;
                }finally{
                    lock.unlock();
                }
            }
        }

注:關(guān)于Lock對(duì)象和synchronized關(guān)鍵字的選擇:
(a) 最好兩個(gè)都不用,使用一種java.util.concurrent包提供的機(jī)制赴魁,
能夠幫助用戶處理所有與鎖相關(guān)的代碼卸奉。
(b) 如果synchronized關(guān)鍵字能滿足用戶的需求,就用synchronized颖御,因?yàn)樗芎?jiǎn)化代碼
(c) 如果需要更高級(jí)的功能榄棵,就用ReentrantLock類,此時(shí)要注意及時(shí)釋放鎖,否則會(huì)出現(xiàn)死鎖疹鳄,通常在finally代碼釋放鎖

(5)使用局部變量實(shí)現(xiàn)線程同步
如果使用ThreadLocal管理變量拧略,則每一個(gè)使用該變量的線程都獲得該變量的副本, 副本之間相互獨(dú)立瘪弓,這樣每一個(gè)線程都可以隨意修改自己的變量副本垫蛆,而不會(huì)對(duì)其他線程產(chǎn)生影響

 public class Bank{
            //使用ThreadLocal類管理共享變量account
            private static ThreadLocal<Integer> account = new ThreadLocal<Integer>(){
                @Override
                protected Integer initialValue(){
                    return 100;
                }
            };
            public void save(int money){
                account.set(account.get()+money);
            }
            public int getAccount(){
                return account.get();
            }
        }

注:ThreadLocal與同步機(jī)制
(a) ThreadLocal與同步機(jī)制都是為了解決多線程中相同變量的訪問沖突問題。
(b) 前者采用以”空間換時(shí)間”的方法腺怯,后者采用以”時(shí)間換空間”的方式

44.數(shù)據(jù)庫(kù)索引

創(chuàng)建索引:

(a) 普通索引:CREATE INDEX username ON mytable(username);
(b) 唯一索引:CREATE UNIQUE INDEX age ON mytable(age);
(唯一索引和主鍵索引與普通索引的區(qū)別是唯一袱饭,不重復(fù)。列值唯一呛占,但是唯一索引可以有空值)
(c) 主鍵索引:ALTER TABLE mytable ADD PRIMARY KEY (id);

刪除索引:

DROP INDEX 索引的名字 ON 索引的表;

組合索引

ALTER TABLE mytable ADD INDEX name_city_age (username,city,age);

1.選擇唯一性索引
唯一性索引的值是唯一的虑乖,可以更快速的通過該索引來確定某條記錄。例如晾虑,學(xué)生表中學(xué)號(hào)是具有唯一性的字段决左。為該字段建立唯一性索引可以很快的確定某個(gè)學(xué)生的信息。如果使用姓名的話走贪,可能存在同名現(xiàn)象佛猛,從而降低查詢速度。

2.為經(jīng)常需要排序坠狡、分組和聯(lián)合操作的字段建立索引
經(jīng)常需要ORDER BY继找、GROUP BY、DISTINCT和UNION等操作的字段逃沿,排序操作會(huì)浪費(fèi)很多時(shí)間婴渡。如果為其建立索引,可以有效地避免排序操作凯亮。

3.為常作為查詢條件的字段建立索引
如果某個(gè)字段經(jīng)常用來做查詢條件边臼,那么該字段的查詢速度會(huì)影響整個(gè)表的查詢速度。因此假消,為這樣的字段建立索引柠并,可以提高整個(gè)表的查詢速度。

4.限制索引的數(shù)目
索引的數(shù)目不是越多越好富拗。每個(gè)索引都需要占用磁盤空間臼予,索引越多,需要的磁盤空間就越大啃沪。修改表時(shí)粘拾,對(duì)索引的重構(gòu)和更新很麻煩。越多的索引创千,會(huì)使更新表變得很浪費(fèi)時(shí)間缰雇。

5.盡量使用數(shù)據(jù)量少的索引
如果索引的值很長(zhǎng)入偷,那么查詢的速度會(huì)受到影響。例如械哟,對(duì)一個(gè)CHAR(100)類型的字段進(jìn)行全文檢索需要的時(shí)間肯定要比對(duì)CHAR(10)類型的字段需要的時(shí)間要多盯串。

6.盡量使用前綴來索引
如果索引字段的值很長(zhǎng),最好使用值的前綴來索引戒良。例如体捏,TEXT和BLOG類型的字段,進(jìn)行全文檢索會(huì)很浪費(fèi)時(shí)間糯崎。如果只檢索字段的前面的若干個(gè)字符几缭,這樣可以提高檢索速度。

7.刪除不再使用或者很少使用的索引
表中的數(shù)據(jù)被大量更新沃呢,或者數(shù)據(jù)的使用方式被改變后年栓,原有的一些索引可能不再需要。數(shù)據(jù)庫(kù)管理員應(yīng)當(dāng)定期找出這些索引薄霜,將它們刪除某抓,從而減少索引對(duì)更新操作的影響。

8 . 最左前綴匹配原則惰瓜,非常重要的原則否副。
mysql會(huì)一直向右匹配直到遇到范圍查詢(>、<崎坊、between备禀、like)就停止匹配,比如a 1=”” and=”” b=”2” c=”“> 3 and d = 4 如果建立(a,b,c,d)順序的索引奈揍,d是用不到索引的曲尸,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調(diào)整男翰。

9 .=和in可以亂序另患。
比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意順序,mysql的查詢優(yōu)化器會(huì)幫你優(yōu)化成索引可以識(shí)別的形式

10 . 盡量選擇區(qū)分度高的列作為索引蛾绎。
區(qū)分度的公式是count(distinct col)/count(*)昆箕,表示字段不重復(fù)的比例,比例越大我們掃描的記錄數(shù)越少秘通,唯一鍵的區(qū)分度是1为严,而一些狀態(tài)敛熬、性別字段可能在大數(shù)據(jù)面前區(qū)分度就 是0肺稀,那可能有人會(huì)問,這個(gè)比例有什么經(jīng)驗(yàn)值嗎应民?使用場(chǎng)景不同话原,這個(gè)值也很難確定夕吻,一般需要join的字段我們都要求是0.1以上,即平均1條掃描10條 記錄

11 .索引列不能參與計(jì)算繁仁,保持列“干凈”涉馅。
比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很簡(jiǎn)單黄虱,b+樹中存的都是數(shù)據(jù)表中的字段值稚矿,但進(jìn)行檢索時(shí),需要把所有元素都應(yīng)用函數(shù)才能比較捻浦,顯然成本 太大晤揣。所以語(yǔ)句應(yīng)該寫成create_time = unix_timestamp(’2014-05-29’);

12 .盡量的擴(kuò)展索引,不要新建索引朱灿。
比如表中已經(jīng)有a的索引昧识,現(xiàn)在要加(a,b)的索引,那么只需要修改原來的索引即可
注意:選擇索引的最終目的是為了使查詢的速度變快盗扒。上面給出的原則是最基本的準(zhǔn)則跪楞,但不能拘泥于上面的準(zhǔn)則。讀者要在以后的學(xué)習(xí)和工作中進(jìn)行不斷的實(shí)踐侣灶。根據(jù)應(yīng)用的實(shí)際情況進(jìn)行分析和判斷甸祭,選擇最合適的索引方式。

45.主從數(shù)據(jù)庫(kù)怎么同步

從庫(kù)通過監(jiān)控主庫(kù)二進(jìn)制操作文件褥影,拷貝到從庫(kù)中繼文件淋叶,然后執(zhí)行同步二進(jìn)制文件

該過程的第一部分就是master記錄二進(jìn)制日志。在每個(gè)事務(wù)更新數(shù)據(jù)完成之前伪阶,master在二日志記錄這些改變煞檩。MySQL將事務(wù)串行的寫入二進(jìn)制日志,即使事務(wù)中的語(yǔ)句都是交叉執(zhí)行的栅贴。在事件寫入二進(jìn)制日志完成后斟湃,master通知存儲(chǔ)引擎提交事務(wù)。 下一步就是slave將master的binary log拷貝到它自己的中繼日志檐薯。首先凝赛,slave開始一個(gè)工作線程——I/O線程。I/O線程在master上打開一個(gè)普通的連接坛缕,然后開始binlog dump process墓猎。Binlog dump process從master的二進(jìn)制日志中讀取事件,如果已經(jīng)跟上master赚楚,它會(huì)睡眠并等待master產(chǎn)生新的事件毙沾。I/O線程將這些事件寫入中繼日志。 SQL slave thread(SQL從線程)處理該過程的最后一步宠页。SQL線程從中繼日志讀取事件左胞,并重放其中的事件而更新slave的數(shù)據(jù)寇仓,使其與master中的數(shù)據(jù)一致。只要該線程與I/O線程保持一致烤宙,中繼日志通常會(huì)位于OS的緩存中遍烦,所以中繼日志的開銷很小。 此外躺枕,在master中也有一個(gè)工作線程:和其它MySQL的連接一樣服猪,slave在master中打開一個(gè)連接也會(huì)使得master開始一個(gè)線程。復(fù)制過程有一個(gè)很重要的限制——復(fù)制在slave上是串行化的拐云,也就是說master上的并行更新操作不能在slave上并行操作

46.list蔓姚、map的數(shù)據(jù)結(jié)構(gòu)

集合

Collection(單列集合)

List(有序,可重復(fù))

ArrayList底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,查詢快,增刪慢線程不安全,效率高Vector底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,查詢快,增刪慢線程安全,效率低LinkedList底層數(shù)據(jù)結(jié)構(gòu)是鏈表,查詢慢,增刪快線程不安全,效率高Set(無序,唯一)

HashSet底層數(shù)據(jù)結(jié)構(gòu)是哈希表。哈希表依賴兩個(gè)方法:hashCode()和equals()執(zhí)行順序:首先判斷hashCode()值是否相同是:繼續(xù)執(zhí)行equals(),看其返回值是true:說明元素重復(fù)慨丐,不添加是false:就直接添加到集合否:就直接添加到集合最終:自動(dòng)生成hashCode()和equals()即可LinkedHashSet底層數(shù)據(jù)結(jié)構(gòu)由鏈表和哈希表組成坡脐。由鏈表保證元素有序。由哈希表保證元素唯一房揭。

TreeSet底層數(shù)據(jù)結(jié)構(gòu)是紅黑樹弊知。(是一種自平衡的二叉樹)如何保證元素唯一性呢?

   根據(jù)比較的返回值是否是0來決定如何保證元素的排序呢?兩種方式自然排序(元素具備比較性)讓元素所屬的類實(shí)現(xiàn)Comparable接口比較器排序(集合具備比較性)讓集合接收一個(gè)Comparator的實(shí)現(xiàn)類對(duì)象Map(雙列集合)A:Map集合的數(shù)據(jù)結(jié)構(gòu)僅僅針對(duì)鍵有效府树,與值無關(guān)戈鲁。B:存儲(chǔ)的是鍵值對(duì)形式的元素帚称,鍵唯一,值可重復(fù)蓬痒。

HashMap底層數(shù)據(jù)結(jié)構(gòu)是哈希表泻骤。線程不安全,效率高哈希表依賴兩個(gè)方法:

hashCode()和equals()執(zhí)行順序:首先判斷hashCode()值是否相同是:繼續(xù)執(zhí)行equals(),看其返回值是true:說明元素重復(fù)梧奢,不添加是false:就直接添加到集合否:就直接添加到集合最終:自動(dòng)生成hashCode()和equals()即可LinkedHashMap底層數(shù)據(jù)結(jié)構(gòu)由鏈表和哈希表組成狱掂。由鏈表保證元素有序。由哈希表保證元素唯一亲轨。

Hashtable底層數(shù)據(jù)結(jié)構(gòu)是哈希表趋惨。線程安全,效率低哈希表依賴兩個(gè)方法:

hashCode()和equals()執(zhí)行順序:首先判斷hashCode()值是否相同是:繼續(xù)執(zhí)行equals(),看其返回值是true:說明元素重復(fù)惦蚊,不添加是false:就直接添加到集合否:就直接添加到集合最終:自動(dòng)生成hashCode()和equals()即可TreeMap底層數(shù)據(jù)結(jié)構(gòu)是紅黑樹器虾。(是一種自平衡的二叉樹)如何保證元素唯一性呢?根據(jù)比較的返回值是否是0來決定如何保證元素的排序呢?兩種方式自然排序(元素具備比較性)讓元素所屬的類實(shí)現(xiàn)Comparable接口比較器排序(集合具備比較性)讓集合接收一個(gè)Comparator的實(shí)現(xiàn)類對(duì)象

2:到底使用那種集合(自己補(bǔ)齊)看需求。

 是否是鍵值對(duì)象形式:是:Map鍵是否需要排序:是:TreeMap否:HashMap不知道蹦锋,就使用HashMap兆沙。否:Collection元素是否唯一:是:Set元素是否需要排序:是:TreeSet否:HashSet不知道,就使用HashSet否:    List要安全嗎:是:Vector(其實(shí)我們也不用它,后面我們講解了多線程以后莉掂,我在給你回顧用誰)   否:ArrayList或者LinkedList增刪多:LinkedList查詢多:ArrayList不知道葛圃,就使用ArrayList不知道,就使用ArrayList3:集合的常見方法及遍歷方式Collection:add()remove()contains()iterator()size()遍歷:增強(qiáng)for迭代器|--Listget()遍歷:普通for|--SetMap:put()remove()containskey(),containsValue()keySet()get()value()entrySet()size()遍歷:根據(jù)鍵找值根據(jù)鍵值對(duì)對(duì)象分別找鍵和值作業(yè):我講解過的任意一個(gè)集合,我要求你存儲(chǔ)什么装悲,你就能夠存儲(chǔ)什么昏鹃。并且尚氛,還要能夠遍歷出來诀诊。

4:ArrayList,LinkedList,HashSet,HashMap(掌握)存儲(chǔ)字符串和自定義對(duì)象數(shù)據(jù)并遍歷5:集合的嵌套遍歷(理解)

注:
1.其中的Arralist 代碼中大量的用了System.arraycopy () 方法 進(jìn)行數(shù)組進(jìn)行復(fù)制
System.arraycopy(elementData, index+1, elementData, index,
numMoved);

47.控制反轉(zhuǎn)IOC和依賴注入DI

Spring所倡導(dǎo)的是所有的類都會(huì)在spring容器中登記,告訴spring你是個(gè)什么東西阅嘶,你需要什么東西属瓣,然后spring會(huì)在系統(tǒng)運(yùn)行到適當(dāng)?shù)臅r(shí)候,把你要的東西主動(dòng)給你讯柔,同時(shí)也把你交給其他需要你的東西抡蛙。所有的類的創(chuàng)建、銷毀都由 spring來控制魂迄,也就是說控制對(duì)象生存周期的不再是引用它的對(duì)象粗截,而是spring。對(duì)于某個(gè)具體的對(duì)象而言捣炬,以前是它控制其他對(duì)象熊昌,現(xiàn)在是所有對(duì)象都被spring控制,所以這叫控制反轉(zhuǎn)湿酸。

IoC的一個(gè)重點(diǎn)是在系統(tǒng)運(yùn)行中婿屹,動(dòng)態(tài)的向某個(gè)對(duì)象提供它所需要的其他對(duì)象。這一點(diǎn)是通過DI來實(shí)現(xiàn)的

參考:https://blog.csdn.net/qq_22654611/article/details/52606960/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末推溃,一起剝皮案震驚了整個(gè)濱河市昂利,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铁坎,老刑警劉巖蜂奸,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異硬萍,居然都是意外死亡窝撵,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門襟铭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碌奉,“玉大人,你說我怎么就攤上這事寒砖〈土樱” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵哩都,是天一觀的道長(zhǎng)魁兼。 經(jīng)常有香客問我,道長(zhǎng)漠嵌,這世上最難降的妖魔是什么咐汞? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任盖呼,我火速辦了婚禮,結(jié)果婚禮上化撕,老公的妹妹穿的比我還像新娘几晤。我一直安慰自己,他們只是感情好植阴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布蟹瘾。 她就那樣靜靜地躺著,像睡著了一般掠手。 火紅的嫁衣襯著肌膚如雪憾朴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天喷鸽,我揣著相機(jī)與錄音众雷,去河邊找鬼。 笑死做祝,一個(gè)胖子當(dāng)著我的面吹牛砾省,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播剖淀,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼纯蛾,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了纵隔?” 一聲冷哼從身側(cè)響起翻诉,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎捌刮,沒想到半個(gè)月后碰煌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绅作,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年芦圾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俄认。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡个少,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出眯杏,到底是詐尸還是另有隱情夜焦,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布岂贩,位于F島的核電站茫经,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜卸伞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一抹镊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧荤傲,春花似錦垮耳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)儡炼。三九已至妓湘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間乌询,已是汗流浹背榜贴。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留妹田,地道東北人唬党。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像鬼佣,于是被迫代替她去往敵國(guó)和親驶拱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理晶衷,服務(wù)發(fā)現(xiàn)蓝纲,斷路器,智...
    卡卡羅2017閱讀 134,659評(píng)論 18 139
  • 從三月份找實(shí)習(xí)到現(xiàn)在晌纫,面了一些公司税迷,掛了不少,但最終還是拿到小米锹漱、百度箭养、阿里、京東哥牍、新浪毕泌、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,253評(píng)論 11 349
  • 從前對(duì)不起閱讀 174評(píng)論 0 1
  • 機(jī)器學(xué)習(xí)的幾類 線性分類器如垃圾郵件 眾所周知嗅辣,我們使用qq郵箱時(shí)候撼泛,有一些郵箱會(huì)被標(biāo)記為垃圾郵件。算法會(huì)根據(jù)里面...
    王強(qiáng)兒閱讀 442評(píng)論 0 1