各種筆記

2020-08-12 15:26:09

nginx中的if和後面的()中間必須有空格

查詢阿裡有關的Java視訊資料

三目運算子多條件使用

Boolean ? 結果a : Boolean ? 結果b : 結果c;

SQl的執行順序

(1)from
(3) join
(2) on
(4) where
(5)group by(開始使用select中的別名,後面的語句中都可以使用)
(6) avg,sum…
(7)having
(8) select
(9) distinct
(10) order by

CMS介面開發

檔案上傳

MySQL讀寫分離

SpringCloud+SpringBoot

RabbitMQ搭建

SpringSecurity Oauth2

課程管理

SpringBoot+SpringDataJPA:操作簡單的增刪改查+Mybatis:多表聯查等

搜尋

媒資管理

SpringSecurity

分佈式事務

反射

SpringBoot如何建立一個新專案

分佈式事務

SpringCloud

數據庫範式

JS&JQ物件轉化

SpringJPA

DOM BOM

泛型

四種參照

MySQL檢視

SpringMVC的工作流程

  • 請求發送到伺服器之後,被封裝爲request物件(tomcat封裝)進入到之後DispatcherServlet(springmvc的入口)
  • 接下來到達HanlderMapping(處理器對映器)之後來選擇對映
    • 根據註解@RequestMapping註解的路徑和tomcat封裝好的請求路徑來進行匹配
  • 接下來進入到處理器執行鏈(HandlerExecutionChain)
    • 呼叫控制器對應的攔截器
    • 接下來呼叫處理器適配器(HandlerAdapter)
    • 通過處理器適配器來呼叫我們寫的controller
    • 然後統一返回modelandview物件
  • 在轉發前,會把model中的數據存入request作用域中
    • 再由檢視解析器(viewResolver)將檢視名轉換爲最終的jsp路徑,並轉發到jsp
  • 如果執行過程中出現了異常:
    • 異常解析器(exceptionhandlerexceptionresolver)進行處理
  • jsp動態生成html程式碼並返迴響應

九種域物件

SpringBoot

1).所有的模組都要繼承spring-boot-starter-parent
@SpringBootApplication註解,是核心註解,具有包掃描的作用,預設掃描當前包及其子包,標識當前類是引導類,若需要掃描其他包,那麼在此註解下新增@ComponentScan(basePackage=("需要掃描的全包名","com.lzh..."))
藉助main執行SpringApplication.run方法,表示要執行SpringBoot的引導類,run方法的參數就是SpringBoot引導類的位元組碼物件(誰有註解誰是引導類)
2).熱部署:在pom.xml中新增spring-boot-devtools座標
3).**起步依賴** parent:依賴於dependencies(通過<dependencyManagement>來統一管理依賴的版本)

4).起步依賴 web:依賴傳遞,依賴於parent,parent依賴於dependencies
5).**自動設定**:@SpringBootApplication由三個註解組成(@SpringBootConfiguration:宣告當前類是Spring的一個設定類
@ComponentScan:進行包掃描的註解,預設掃描當前包及其子包
@EnableAutoConfiguration:自動設定的核心註解,是否自動設定的開關)



Redis的穿透

解決方案 使用string儲存數據 若查詢不到那麼將請求參數設定null值並存入快取,同時設定過期時間,那麼在過期時間內將不會再存取數據庫
所有的請求不會存取數據庫,只存取redis,設定定時任務,定期更新redis中的數據

Redis的擊穿

高併發情況下,快取失效,造成大量請求瞬間請求數據庫
設定條件,同樣的請求只能有一個執行緒去存取數據庫,再使用互斥鎖(trylock)

Redis的雪崩

大量的高併發的快取同時失效,造成的數據庫壓力過大(整點搶購活動)
解決方案:設定不同的過期時間,
只查redis,通過定時任務定時更新redis

設計模式

設計模式五大原則和一法則

  • 單一職責原則(Single Responsibility Principle)(高內聚,低耦合):一個類只負責一項職責,對一個類而言,只能有一個引起他變化的原因

  • 裡氏替換原則(LSP liskov substitution principle):子類可以擴充套件父類別的功能,但不能改變父類別原有的功能(增強程式的健壯性)

  • 依賴倒置原則(dependence inversion principle)**:面向介面程式設計,上層模組不應該依賴下層模組,兩者應依賴其抽象

  • 介面隔離(interface segregation principle)**:建立單一介面,類之間的依賴關係應該建立在最小的介面上,用戶端不應該依賴不需要的介面【介面粒度越小,系統越靈活,但複雜性越高,維護性降低】

  • 迪米特原則(law of demeter LOD):最少知道原則,儘量降低類於類之間的耦合;一個物件應該對其他物件有最少的瞭解

  • 總:開閉原則(open closed principle):用抽象構建架構,用實現擴充套件原則

	1.工廠模式:****
		類別:建立型模式;
		功能:提供了一種建立物件的最佳方式;
		優點:1、一個呼叫者想建立一個物件,只要知道其名稱就可以了。 2、擴充套件性高,如果想增加一個產品,只要擴充套件一個工廠類就可以。 3、遮蔽產品的具體邏輯實現,呼叫者只關心產品的介面;
		缺點:適合複雜物件適合工廠模式,使得系統中的類的個數成倍增加會增加系統複雜度和具體類的依賴;
		使用場景:1、日誌記錄器:記錄可能記錄到本地硬碟、系統事件、遠端伺服器等,使用者可以選擇記錄日誌到什麼地方。 
		2、數據庫存取,當使用者不知道最後系統採用哪一類數據庫,以及數據庫可能有變化時。 	3、設計一個連線伺服器的框架,需要三個協定,"POP3"、"IMAP"、"HTTP",可以把這三個作爲產品類,共同實現一個介面。 
	2.抽象工廠模式:*****
		類別:建立型模式;
		功能:提供了一種建立物件的最佳方式;
		優點:當一個產品族中的多個物件被設計成一起工作時,它能保證用戶端始終只使用同一個產品族中的物件;
		缺點:產品族擴充套件非常困難,要增加一個系列的某一產品,既要在抽象的 Creator 裡加程式碼,又要在具體的裏面加程式碼。
	3.單例模式:****
		類別:建立型模式;
		功能:提供了一種建立物件的最佳方式;
		優點:1、在記憶體裡只有一個範例,減少了記憶體的開銷,尤其是頻繁的建立和銷燬範例(比如管理學院首頁頁面快取)。2、避免對資源的多重佔用(比如寫檔案操作);
		缺點:沒有介面,不能繼承,與單一職責原則衝突,一個類應該只關心內部邏輯,而不關心外面怎麼樣來範例化。;
		使用場景:     	
		1、要求生產唯一序列號。
	    2、WEB 中的計數器,不用每次重新整理都在數據庫裡加一次,用單例先快取起來。
	    3、建立的一個物件需要消耗的資源過多,比如 I/O 與數據庫的連線等。
	4.建造者模式:**
		類別:建立型模式
		功能:使用多個簡單的物件一步一步構建成一個複雜的物件
		優點:建造者獨立,易於擴充套件,便於控制細節風險
		缺點:產品需有共同點,範圍有限制,內部變化複雜,輝有很多的建造類
		使用場景:
		1、需要生成的物件具有複雜的內部結構
		2、需要生成的物件內部屬性本身相互依賴
		**與工廠模式的區別是:建造者模式更加關注零件裝配的順序。
	5.原型模式:***
		類別:建立型模式
		功能:用於建立重複的物件,同時又能保證效能。提供了建立物件的最佳方式,在執行期建立和刪除原型
		關鍵程式碼:繼承Cloneable重寫clone()方法
		優點:效能提高,避開建構函式的約束
		缺點:對於已有的類不支援序列化的間接物件或含有回圈結構,需實現Cloneable介面
		使用場景:
		1、資源優化場景
		2、類的初始化需要消耗非常多的資源
		3、效能和安全要求的場景
		4、通過new產生一個物件需要非常多的數據準備或,存取許可權
		5、一個物件或多個修改者的場景
		6、一個物件需要被多個物件存取且修改時可以拷貝多個物件給他們用
		7、原型模式一般結合工廠方法模式一起出現,通過clone的方法建立一個物件,通過工廠方法提供給呼叫者,
		======((((這個模式和volatile有啥區別))))=====
	6.適配器模式(轉換器)****
		類別:結構型模式
		功能:將一個類的介面轉換成另一個介面,使不相容的類可以一起工作
		關鍵程式碼:適配器繼承或依賴已有物件,實現想要的目標介面
		優點:可以讓兩個沒有關聯的類一起執行,提高了類的複用,增加了類的透明度,靈活性好
		缺點:過多使用會讓系統零亂,不易整體把握。Java單繼承,最多適配一個適配者類
		使用場景:有動機的修改一個正常執行的系統的介面,可以考慮使用適配器模式
		**適配器是解決正在服役的專案問題
	7.橋接模式***
		類別:結構型模式
		功能:使實體類的功能獨立於介面實現類,這兩種型別的類可被結構化改變而互不影響。(將抽象部分和實現部分分離,使他們可以獨立變化)
		關鍵程式碼:抽象類依賴實現類
		優點:抽象和實現的分離,擴充套件能力強,實現細節對客戶透明
		缺點:因聚合關聯關係建立在抽象層,要求開發者針對抽象進行設計與變成
		使用場景:1、一個系統需要在構件的抽象化角色和具體化角色之間增加靈活性,避免在兩個層次之間建立靜態的繼承聯繫,通過橋接模式可以使他們在抽象層建立一個關聯關係2、對於不希望使用繼承,或因多層次繼承導致系統類的個數增加過多的系統3、一個類存在兩個獨立變化的緯度且這兩個類都需要進行擴充套件
		**對於兩個獨立變化的維度,使用橋接模式非常合適
	8.過濾器模式(或標準模式)
		類別:結構型模式
		功能:獲得符合多個條件的物件
		使用場景:對一組數據進行分組的情況下,可以定義一個介面,通過實現介面重寫過濾方法,比如傳入一個集合,將集閤中姓劉的人篩選出來,定義方法,遍歷傳入的集合,將符合條件的數據加入新的集合併返回,總的來說就是傳入數據,去掉不符合條件的並返回
	9.組合模式(部分整體模式)****
		類別:結構型模式
		功能:使客戶程式與複雜元素的內部結構解耦(動態的給一個物件新增一些額外的職責)
		關鍵程式碼:樹枝和葉子實現統一介面,數值內部組合該介面
		範例:算術表達式包括[運算元,操作符,另一個運算元],另一個操作符也可以是運算元、操作符和另一個運算元。
		優點:高層模組呼叫簡單,節點自由增加
		缺點:其葉子和樹枝的宣告都是實現類,而不是介面,違反了依賴倒置原則
		使用場景:部分,整體場景,樹形選單,檔案,資料夾的管理
	10.裝飾器模式***
		類別:結構型模式(建立了一個裝飾類用來包裝原有的類)
		功能:保持類方法簽名完整性的前提下,提供了額外的功能
		關鍵程式碼:
			1.Component類充當抽象角色,不應該具體實現
			2.修飾類參照和繼承Component類,具體擴充套件類重寫父類別的方法
		範例:孫悟空72變,本質還是猴子
		優點:裝飾類和被裝飾類可以獨立發展,不會相互耦合,裝飾模式是繼承的一個替代模式,可以動態的擴充套件一個實現類的功能
		缺點:多層裝飾比較複雜
		使用場景:擴充套件一個類的功能,動態的增加功能,動態復原
	11.外觀模式*****
		類別:結構型模式
		功能:爲子系統中的一組介面提供一個一致的介面,降低存取複雜系統的內部子系統的複雜度,簡化用戶端與其的介面
		關鍵程式碼:在用戶端和複雜系統之間再加一層,在這一層將呼叫順序和依賴關係處理好
		範例:西京醫院便民門診(ps:哈哈哈哈秀emmm雖然便民關了)
		優點:減少系統相互依賴,提高靈活性,安全性
		缺點:不符合開閉原則,若要改東西,那麼將會很麻煩
		使用場景:1.爲複雜的模組或子系統提供外界存取的模組
				2.子系統相對獨立
				3.預防低水平人員帶來的風險
	12.享元模式*
		類別:結構型模式
		功能:嘗試重用現有的同類物件,若無則建立新物件
		關鍵程式碼:用HashMap儲存這些物件
		範例:String型別的字串,如果有那麼返回,如果沒有,那麼建立一個字串儲存在字串快取池裏;數據庫的數據池
		優點:大大減少了物件的建立,降低系統的記憶體,使效率提高
		缺點:提高了系統的複雜度,需要分離出外部狀態和內部狀態,否則可能會引起執行緒安全問題,這些類需要有一個工廠物件加以控制.
		使用場景:系統有大量相似物件,需要緩衝池的場景
		我的問題:爲什麼需要分離外部狀態和內部狀態,爲什麼會引起執行緒安全問題,爲什麼需要工廠物件加以控制,如string建立時的過程,工廠是誰?怎麼分離的狀態
	13.代理模式****
		類別:結構型模式
		功能:爲其他物件提供一種代理以控制對這個物件的存取,
		關鍵程式碼:實現與被代理類組合
		範例:應用的快捷方式,spring aop,火車票代售點,kfc甜品站(emm)
		優點:職責清晰,擴充套件性高,智慧化
		缺點:有些型別的代理模式可能會造成請求的處理速度變慢,某些代理模式特別複雜
		使用場景:1、遠端代理。2、虛擬代理。3、copy-on-write代理。4、保護代理。5、cache代理。6、防火牆代理。7、同步化代理。8、只能參照代理。
		注意:1、和適配器模式的區別:適配器模式主要考慮物件的介面,而代理模式不能改變所代理類的介面。2、和裝飾器模式的區別:裝飾器模式爲了增強功能,而代理模式是爲了加以控制。
	14.責任鏈模式**
		類別:行爲模式
		功能:讓多個物件都有可能接受請求,責任鏈上的處理者負責處理請求,客戶只需要將請求發送到責任鏈上即可,無需關心請求的處理細節和請求的傳遞,所以責任鏈將請求的發送者和請求的處理者解耦了,一般用在處理訊息時過濾很多道
		關鍵程式碼:Handler裏面聚合它自己,在HandlerRequest裡判斷是否合適,若妹達到條件則向下傳遞,向誰傳遞之前set進去
		範例:Javaweb中tomacat對encoding的處理,jsp servlet的filter
		優點:
			1、降低請求的發送者和接收者的耦合度
			2、簡化物件,使物件不需要知道鏈的結構
			3、增強給物件指派職責的靈活性,通過改變鏈內的成員或調動他們的次序,允許動態地增加或刪除責任
			4、增加新的請求處理類很方便(實現介面就好??)
		缺點:影響系統效能,不能保證請求一定被接受,不容易觀察執行時的特徵影響除錯
		使用場景:
				1、多個物件處理同一個請求
				2、在不明確指定接收者的情況下,想多個物件中的一個提交一個請求
				3、可動態制定一組物件處理請求
				
				
	15.命令模式****
		類別:行爲模式
		功能:將一個請求封裝成一個物件,傳給呼叫物件,呼叫物件尋找可以處理該命令的合適的物件,並將該命令傳給響應的物件,該物件執行傳入的請求物件。
		關鍵程式碼:定義三個角色:
			1、received真正的命令執行物件
			2、Command
			3、invoker使用命令物件的入口
		優點:降低了系統耦合度,新的命令可以很容易的新增到系統中
		缺點:可能導致系統由過多的具體命令類
		使用場景:需要對行爲進行記錄、復原/重做、事務等處理,需要將行爲請求者和行爲實現者解耦,那麼就需要將一組行爲抽象爲物件從而實現松耦合
		範例:springmvc中doget,dopost;實現一個控制器轉發到多個模型,定義介面,讓所有模型實現這個介面那麼就可以轉發過去;
	16.直譯器模式*
		類別:行爲模式
		功能:該介面解釋一個特定的上下文
		關鍵程式碼:構建環境類,包含直譯器之外的一些全域性資訊,一般是使用hashmap
		優點:擴充套件性好,易於實現簡單文法
		缺點:可利用場景較少,難維護,一般採用的遞回呼叫
		使用場景:將解釋執行的語言中的句子表示爲一個抽象語法樹,重複出現的問題可以用一種簡單的語言來表達
		**在Java中可以用expression4j代替
    17.迭代器模式*****
		類別:行爲模式
		功能:順序存取集合物件的元素,不需要知道集合物件的底層表示
		關鍵程式碼:定義介面hasNext,next
		優點:
			1、支援不同的方式遍歷一個聚合物件
			2、迭代器簡化了聚合類
			3、在同一個聚合上可以有多個遍歷
			4、增加新的聚合類和迭代器類都很方便,無需修改原有程式碼
		缺點:增加了系統的複雜性。
        使用場景:
        1、存取一個聚合物件的內容而無須暴露它的內部表示。 
        2、需要爲聚合物件提供多種遍歷方式。
        3、爲遍歷不同的聚合結構提供一個統一的介面。
        範例:iterator
	18.中介者模式**
    	類別:行爲模式
    	功能:降低多個物件和類之間的通訊複雜性,使程式碼易於維護
    	關鍵程式碼:物件之間的通訊封裝到一個類中單獨處理
    	優點:降低了類的複雜度,解耦,符合迪米特原則
    	缺點:中介者複雜龐大難以維護
    	使用場景:物件之間存在比較複雜的參照關係,難以複用
    	範例:MVC框架 controller是model和view的中介者
    19.備忘錄模式**
    	類別:行爲模式
    	功能:儲存一個物件的某個狀態,用於適當的時候恢復物件
    	關鍵程式碼:客戶不與備忘錄耦合,與備忘錄管理類耦合
    	優點:方便的找回曆史狀態,實現了資訊的封裝,不需要關心狀態的儲存細節
    	缺點:消耗資源
    	使用場景:需要恢復數據的場景,提供回滾的操作
    	範例:數據庫事務,ctrl+z
    20.策略模式****
    	類別:行爲模式
    	功能:隨着策略物件的改變從而使用不同的演算法
    	關鍵程式碼:實現同一個介面
    	優點:演算法可以自由切換,避免使用多重條件判斷,擴充套件性好
    	缺點:策略類會增多,所有策略類都需要對外暴露服務
    	使用場景:動態的讓一個物件在許多行爲中選擇一個,系統需要動態的在集中演算法中選擇一種
    	範例:webmagic,java AWT中的LayoutManager
    	**若策略多於四個需要考慮使用混合模式
    21.存取者模式*
    	類別:行爲模式
    	功能:將數據結構和數據操作分離
    	關鍵程式碼:在數據基礎類裡有一個方法接受存取者,將自身傳入存取者
    	優點:符合單一職責原則,優秀的擴充套件性,靈活性
    	缺點:
    		1、具體元素對存取者公佈細節,違反了迪米特原則
    		2、具體元素變更比較困難
    		3、違反了依賴倒置原則,依賴了具體類,沒有依賴抽象
    	使用場景:物件結構中物件對應的類很少改變,需要對物件結構中的物件進行很多不同且不相關的操作
    	範例:報表,UI,攔截器,過濾器
    22.模板模式***
    	類別:行爲模式
    	功能:一些方法通用,卻在每一個子類都重寫了這個方法
    	關鍵程式碼:在抽象類實現,其他不通用的方法在子類實現
    	優點:
    		1、封裝不變的部分,擴充套件可變部分
    		2、提取公共程式碼,便於維護
    		3、行爲又父類別控制,子類實現
    	缺點:每一個不同的實現都需要一個子類來實現,類會過多
    	使用場景:重要的複雜的方法可以考慮作爲模板方法
    	範例:spring對hibernate的支援
    	**爲防止惡意操作,一般模板方法都加上 final 關鍵詞
    23.狀態模式***
    	類別:行爲模式
    	功能:允許物件在內部狀態發生改變時改變他的行爲,物件看起來好像修改了他的類
    	關鍵程式碼:狀態模式的介面中有一個或者多個方法
    	優點:
    		1、封裝了轉換規則
    		2、列舉可能的狀態
    		3、將所有與某個狀態有關的行爲放到一個類中,並且可以方便的增加新的狀態,只需要改變物件狀態就可以改變物件的行爲
    		4、允許狀態邏輯轉換與狀態物件合成一起
    		5、可以讓多個環境物件共用一個狀態物件,從而減少系統中物件的個數
    	缺點:
    		1、會增加系統類和物件的個數
    		2、對開閉原則的支援並不友好
    	使用場景:行爲隨狀態改變而改變的場景,條件分支語句的代替者
    	範例:比賽時的狀態,一般,及格,超長
     24.觀察者模式***
    	類別:行爲模式
    	功能:當一個物件被修改時,自動通知他的依賴物件
    	關鍵程式碼:在抽象類中有一個ArrayList存放觀察者
    	優點:觀察者和被觀察者是抽象耦合的,建立了一套觸發機制 機製
    	缺點:
    		1、若觀察者過多,消耗資源會過多
    		2、若觀察者和觀察目標之間有依賴回圈的話,可能導致回圈呼叫(類似遞回無出口)
    		3、沒有相應的機制 機製讓觀察者知道目標是怎麼發生變化的
    	使用場景:一個物件的改變將導致其他一個多個物件也發生改變,a影響b,b影響c
    	注意:
    		1、java中已經有對觀察者模式支援的類
    		2、避免回圈參照
    		3、一般採用非同步方式。順序執行可能會導致系統卡殼
   
			

java內部類的特點

靜態內部類纔可以宣告靜態方法
靜態方法不可以使用非靜態變數
抽象方法不可以有函數體

1.爲什麼使用內部類?
使用內部類最吸引人的原因是:每個內部類都能獨立地繼承一個(介面的)實現,所以無論外圍類是否已經繼承了某個(介面的)實現,
對於內部類都沒有影響
1.1.使用內部類最大的優點就在於它能夠非常好的解決多重繼承的問題,使用內部類還能夠爲我們帶來如下特性:
(1)、內部類可以用多個範例,每個範例都有自己的狀態資訊,並且與其他外圍物件的資訊相互獨。
(2)、在單個外圍類中,可以讓多個內部類以不同的方式實現同一個介面,或者繼承同一個類。
(3)、建立內部類物件的時刻並不依賴於外圍類物件的建立。
(4)、內部類並沒有令人迷惑的「is-a」關係,他就是一個獨立的實體。
(5)、內部類提供了更好的封裝,除了該外圍類,其他類都不能存取。
2.內部類分類:
(一).成員內部類:
	
public class Outer{
        private int age = 99;
        String name = "Coco";
        public class Inner{
            String name = "Jayden";
            public void show(){
                System.out.println(Outer.this.name);
                System.out.println(name);
                System.out.println(age);
            }
        }
        public Inner getInnerClass(){
            return new Inner();
        }
        public static void main(String[] args){
            Outer o = new Outer();
            Inner in = o.new Inner();
            in.show();
        }
    }
1.Inner 類定義在 Outer 類的內部,相當於 Outer 類的一個成員變數的位置,Inner 類可以使用任意存取控制符,
如 public 、 protected 、 private 等
2.Inner 類中定義的 show() 方法可以直接存取 Outer 類中的數據,而不受存取控制符的影響,
如直接存取 Outer 類中的私有屬性age
3.定義了成員內部類後,必須使用外部類物件來建立內部類物件,而不能直接去 new 一個內部類物件,
即:內部類 物件名 = 外部類物件.new 內部類( );
4.編譯上面的程式後,會發現產生了兩個 .class 檔案: Outer.class,Outer$Inner.class{}
5.成員內部類中不能存在任何 static 的變數和方法,可以定義常數:
(1).因爲非靜態內部類是要依賴於外部類的範例,而靜態變數和方法是不依賴於物件的,僅與類相關,
簡而言之:在載入靜態域時,根本沒有外部類,所在在非靜態內部類中不能定義靜態域或方法,編譯不通過;
非靜態內部類的作用域是範例級別
(2).常數是在編譯器就確定的,放到所謂的常數池了
★★友情提示:
1.外部類是不能直接使用內部類的成員和方法的,可先建立內部類的物件,然後通過內部類的物件來存取其成員變數和方法;
2.如果外部類和內部類具有相同的成員變數或方法,內部類預設存取自己的成員變數或方法,如果要存取外部類的成員變數,
可以使用 this 關鍵字,如:Outer.this.name
(二).靜態內部類: 是 static 修飾的內部類,
1.靜態內部類不能直接存取外部類的非靜態成員,但可以通過 new 外部類().成員 的方式存取
2.如果外部類的靜態成員與內部類的成員名稱相同,可通過「類名.靜態成員」存取外部類的靜態成員;
如果外部類的靜態成員與內部類的成員名稱不相同,則可通過「成員名」直接呼叫外部類的靜態成員
3.建立靜態內部類的物件時,不需要外部類的物件,可以直接建立 內部類 物件名 = new 內部類();
public class Outer{
            private int age = 99;
            static String name = "Coco";
            public static class Inner{
                String name = "Jayden";
                public void show(){
                    System.out.println(Outer.name);
                    System.out.println(name);                  
                }
            }
            public static void main(String[] args){
                Inner i = new Inner();
                i.show();
            }
        }
(三).方法內部類:其作用域僅限於方法內,方法外部無法存取該內部類
(1).區域性內部類就像是方法裏面的一個區域性變數一樣,是不能有 public、protected、private 以及 static 修飾符的
(2).只能存取方法中定義的 final 型別的區域性變數,因爲:
當方法被呼叫執行完畢之後,區域性變數就已消亡了。但內部類物件可能還存在,
直到沒有被參照時纔會消亡。此時就會出現一種情況,就是內部類要存取一個不存在的區域性變數;
==>使用final修飾符不僅會保持物件的參照不會改變,而且編譯器還會持續維護這個物件在回撥方法中的生命週期.
區域性內部類並不是直接呼叫方法傳進來的參數,而是內部類將傳進來的參數通過自己的構造器備份到了自己的內部,
自己內部的方法呼叫的實際是自己的屬性而不是外部類方法的參數;
防止被篡改數據,而導致內部類得到的值不一致
   /*
        使用的形參爲何要爲 final???
         在內部類中的屬性和外部方法的參數兩者從外表上看是同一個東西,但實際上卻不是,所以他們兩者是可以任意變化的,
         也就是說在內部類中我對屬性的改變並不會影響到外部的形參,而然這從程式設計師的角度來看這是不可行的,
         畢竟站在程式的角度來看這兩個根本就是同一個,如果內部類該變了,而外部方法的形參卻沒有改變這是難以理解
         和不可接受的,所以爲了保持參數的一致性,就規定使用 final 來避免形參的不改變
         */
        public class Outer{
            public void Show(){
                final int a = 25;
                int b = 13;
                class Inner{
                    int c = 2;
                    public void print(){
                        System.out.println("存取外部類:" + a);
                        System.out.println("存取內部類:" + c);
                    }
                }
                Inner i = new Inner();
                i.print();
            }
            public static void main(String[] args){
                Outer o = new Outer();
                o.show();
            }
        }    
(3).注意:在JDK8版本之中,方法內部類中呼叫方法中的區域性變數,可以不需要修飾爲 final,匿名內部類也是一樣的,主要是JDK8之後增加了 Effectively final 功能
http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html
反編譯jdk8編譯之後的class檔案,發現內部類參照外部的區域性變數都是 final 修飾的
(四).匿名內部類:
(1).匿名內部類是直接使用 new 來生成一個物件的參照;
(2).對於匿名內部類的使用它是存在一個缺陷的,就是它僅能被使用一次,建立匿名內部類時它會立即建立一個該類的範例,
該類的定義會立即消失,所以匿名內部類是不能夠被重複使用;
(3).使用匿名內部類時,我們必須是繼承一個類或者實現一個介面,但是兩者不可兼得,同時也只能繼承一個類或者實現一個介面;
(4).匿名內部類中是不能定義建構函式的,匿名內部類中不能存在任何的靜態成員變數和靜態方法;
(5).匿名內部類中不能存在任何的靜態成員變數和靜態方法,匿名內部類不能是抽象的,它必須要實現繼承的類或者實現的介面的所有抽象方法
(6).匿名內部類初始化:使用構造程式碼塊!利用構造程式碼塊能夠達到爲匿名內部類建立一個構造器的效果
	
  public class OuterClass {
            public InnerClass getInnerClass(final int   num,String str2){
                return new InnerClass(){
                    int number = num + 3;
                    public int getNumber(){
                        return number;
                    }
                };        /* 注意:分號不能省 */
            }
            public static void main(String[] args) {
                OuterClass out = new OuterClass();
                InnerClass inner = out.getInnerClass(2, "chenssy");
                System.out.println(inner.getNumber());
            }
        }
        interface InnerClass {
            int getNumber();
        }         

常用Linux指令

 1.ps 檢視當前伺服器上的進程 -ef | grep xxx -- color  檢視xxx是否在進程中
 2.top檢視資源
 3.tail 顯示檔案尾部 通常配合 -f /logs/catalina.out 檢視日誌檔案
 4.free 檢視當前伺服器的記憶體總數 -m 是將結果已m的形式展示
 5.檢視磁碟剩餘空間 desk

反射的特點

  反射指的是在執行時能夠分析類的能力的程式。
  反射機制 機製可以用來:
1.在執行時分析類的能力--檢查類的結構--所用到的就是java.lang.reflect包中的Field、Method、Constructor,分別用於描述類的與、方法和構造器。A中的Class類在java.lang中。
2.在執行時檢視物件。
3.實現通用的陣列操作程式碼。
反射機制 機製的功能:
在執行時判斷任意一個物件所屬的類;在執行時構造任意一個類的物件;在執行時判斷任意一個類所具有的成員變數和方法;在執行時呼叫任意一個物件的方法;生成動態代理。
反射機制 機製常見作用:
動態載入類、動態獲取類的資訊(屬性、方法、構造器);動態構造物件;動態呼叫類和物件的任意方法、構造器;動態呼叫和處理屬性;獲取泛型資訊(新增型別:ParameterizedType,GenericArrayType等);處理註解(反射API:getAnnotationsdeng等)。
反射機制 機製效能問題:
反射會降低效率。
void setAccessible(boolean flag):是否啓用存取安全檢查的開關,true遮蔽Java語言的存取檢查,使得物件的私有屬性也可以被查詢和設定。禁止安全檢查,可以提高反射的執行速度。
可以考慮使用:cglib/javaassist操作。

紅黑樹的基本原則

性質1. 節點是紅色或黑色。
性質2. 根節點是黑色。
性質3. 每個葉子的子節點都是黑色的空節點 
性質4. 每個紅色節點的兩個子節點都是黑色。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)
性質5. 從任一節點到其每個葉子的所有路徑都包含相同數目的黑色節點。

TDD的三個原則

1)沒有測試之前不要寫任何功能程式碼
2)只編寫恰好能夠體現一個失敗情況的測試程式碼
3)只編寫恰好能通過測試的功能程式碼

在實際開發過程中,可能並不需要嚴格遵守這三個原則。即便只是大體上應用TDD到複雜功能開發,就能發揮很大的作用。
具體來說,首先在開發前期,按照TDD的原則不斷在新增測試用例和開發功能程式碼之間切換。
在這個回圈迭代過程中,不斷地通過重構和麪向物件思想,完善程式碼設計。
並且可以引入業界公認的設計模式使自己的程式碼更加專業、優美。

這樣做的優點:
一是幫助思考。對於很複雜的功能需要迭代開發,不可能一下子就把邏輯實現全想明白。於是可以先實現最簡單功能,再逐步完善;
二是快速偵錯。有了單元測試,可以通過失敗的用例直接找到對應出問題的程式碼,幾乎不需要太多偵錯了;
三是通過TDD不斷迭代出的程式碼,設計比較合理,後期更加容易維護。

當然凡事都是有利有弊的,TDD也有它的缺點和侷限:
一是前期進開發稍慢一些,因爲需要編寫單元測試(但是TDD往往在開發中後期會讓你的開發進度越來越快,
TDD節省下來的時間將遠遠超過編寫和維護測試用例的時間。這就好比玩即時戰略遊戲,前期的精心佈局將在中後期看到效果);
二是對於簡單功能並不適用,要注意應用場景。

CAS(比較並交換)

​ 應用:自旋鎖

public class SpinLock {

  private AtomicReference<Thread> sign =new AtomicReference<>();

  public void lock(){
    Thread current = Thread.currentThread();
    while(!sign .compareAndSet(null, current)){
    }
  }

  public void unlock (){
    Thread current = Thread.currentThread();
    sign .compareAndSet(current, null);
  }
}

AtomicInteger 的 incrementAndGet()

    public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }
複製程式碼

與自旋鎖有異曲同工之妙,就是一直while,直到操作成功爲止。

令牌桶限流器

所謂令牌桶限流器,就是系統以恆定的速度向桶內增加令牌。每次請求前從令牌桶裏面獲取令牌。如果獲取到令牌就纔可以進行存取。當令牌桶內沒有令牌的時候,拒絕提供服務。我們來看看 eureka 的限流器是如何使用 CAS 來維護多執行緒環境下對 token 的增加和分發的。

public class RateLimiter {

    private final long rateToMsConversion;

    private final AtomicInteger consumedTokens = new AtomicInteger();
    private final AtomicLong lastRefillTime = new AtomicLong(0);

    @Deprecated
    public RateLimiter() {
        this(TimeUnit.SECONDS);
    }

    public RateLimiter(TimeUnit averageRateUnit) {
        switch (averageRateUnit) {
            case SECONDS:
                rateToMsConversion = 1000;
                break;
            case MINUTES:
                rateToMsConversion = 60 * 1000;
                break;
            default:
                throw new IllegalArgumentException("TimeUnit of " + averageRateUnit + " is not supported");
        }
    }

    //提供給外界獲取 token 的方法
    public boolean acquire(int burstSize, long averageRate) {
        return acquire(burstSize, averageRate, System.currentTimeMillis());
    }

    public boolean acquire(int burstSize, long averageRate, long currentTimeMillis) {
        if (burstSize <= 0 || averageRate <= 0) { // Instead of throwing exception, we just let all the traffic go
            return true;
        }

        //新增token
        refillToken(burstSize, averageRate, currentTimeMillis);

        //消費token
        return consumeToken(burstSize);
    }

    private void refillToken(int burstSize, long averageRate, long currentTimeMillis) {
        long refillTime = lastRefillTime.get();
        long timeDelta = currentTimeMillis - refillTime;

        //根據頻率計算需要增加多少 token
        long newTokens = timeDelta * averageRate / rateToMsConversion;
        if (newTokens > 0) {
            long newRefillTime = refillTime == 0
                    ? currentTimeMillis
                    : refillTime + newTokens * rateToMsConversion / averageRate;

            // CAS 保證有且僅有一個執行緒進入填充
            if (lastRefillTime.compareAndSet(refillTime, newRefillTime)) {
                while (true) {
                    int currentLevel = consumedTokens.get();
                    int adjustedLevel = Math.min(currentLevel, burstSize); // In case burstSize decreased
                    int newLevel = (int) Math.max(0, adjustedLevel - newTokens);
                    // while true 直到更新成功爲止
                    if (consumedTokens.compareAndSet(currentLevel, newLevel)) {
                        return;
                    }
                }
            }
        }
    }

    private boolean consumeToken(int burstSize) {
        while (true) {
            int currentLevel = consumedTokens.get();
            if (currentLevel >= burstSize) {
                return false;
            }

            // while true 直到沒有token 或者 獲取到爲止
            if (consumedTokens.compareAndSet(currentLevel, currentLevel + 1)) {
                return true;
            }
        }
    }

    public void reset() {
        consumedTokens.set(0);
        lastRefillTime.set(0);
    }
}

複製程式碼

所以梳理一下 CAS 在令牌桶限流器的作用。就是保證在多執行緒情況下,不阻塞執行緒的填充token 和消費token。

歸納

通過上面的三個應用我們歸納一下 CAS 的應用場景:

  • CAS 的使用能夠避免執行緒的阻塞。
  • 多數情況下我們使用的是 while true 直到成功爲止。

CAS 缺點

  1. ABA 的問題,就是一個值從A變成了B又變成了A,使用CAS操作不能發現這個值發生變化了,處理方式是可以使用攜帶類似時間戳的版本AtomicStampedReference
  2. 效能問題,我們使用時大部分時間使用的是 while true 方式對數據的修改,直到成功爲止。優勢就是相應極快,但當執行緒數不停增加時,效能下降明顯,因爲每個執行緒都需要執行,佔用CPU時間。

總結

CAS 是整個程式設計重要的思想之一。整個計算機的實現中都有CAS的身影。微觀上看彙編的 CAS 是實現操作系統級別的原子操作的基石。從程式語言角度來看 CAS 是實現多執行緒非阻塞操作的基石。宏觀上看,在分佈式系統中,我們可以使用 CAS 的思想利用類似Redis的外部儲存,也能實現一個分佈式鎖。

從某個角度來說架構就將微觀的實現放大,或者底層思想就是將宏觀的架構進行微縮。計算機的思想是想通的,所以說了解底層的實現可以提升架構能力,提升架構的能力同樣可加深對底層實現的理解。計算機知識浩如煙海,但是套路有限。抓住基礎的幾個套路突破,從思想和思維的角度學習計算機知識。不要將自己的精力花費在不停的追求新技術的腳步上,跟隨‘start guide line’只能寫一個demo,所得也就是一個demo而已。

停下腳步,回顧基礎和經典或許對於技術的提升更大一些。

vue中獲取url的參數 this.$rote.使用params.參數名,可以獲取到參數 獲取問號左邊參數使用query獲取問號右邊參數

Angular教學

概述:SoC關注點分離,拆解,分塊處理
SOLID:物件導向的五個原則
MVC:面向架構
框架基本都灌輸了上述兩個設計:通過設計理解框架
MDN來學習CSS,理解CSS設計思路
主語言是TypeScript
	完善的型別系統,嚴格的語法檢查,強力的IDE支援
設計很像Spring
	可以複用自己的經驗,起步較容易
風格更重嚴謹而不是靈活
	靈活意味着失控
可以看一下angular的風格指南
一件起步Angular CLI不用關webpack,一條命令生成專案元件和服務
一步到位,angular選擇了TypeScript和RxJs

學習路線
angular.cn
快速上手->搭建環境->開發中按需查API

IDE(需安裝外掛);Chrome外掛:Augury;NodeJS最新版
元件庫
	Angular Material
	ng-zorro-antd
	lonic(行動端,h5應用)
擴充套件文件(閱讀被angular依賴,MQ的設計和rxjs比較像)
	RxJS:http://rxjs.dev
深度剖析Angular(Angular In Depth)
閱讀原始碼的話從Angular Material或CDK元件開發工具的原始碼

	

	
	

介面定義

目的是實現需求
1.瞭解介面請求什麼,響應什麼
2.定義出模型類,最終使用統一模型類響應結果

Dockers

元件:
	用戶端,伺服器端,映象,容器,註冊中心
啓動:systemctl start/stop/restart/status/enable(開機自啓) docker
映象:
	檢視docker images
	網上查詢映象 docker search 關鍵字
	下載 docker pull 關鍵字
	刪除映象 docker rmi 映象名稱/映象id
	檢視執行狀態 docker ps
	進入容器(互動式) docker run/exit -it --name=mycentos01 centos:7 /bin/bash
	建立容器 docker exec -it mycentos02 centos:7
	進入容器(守護式) docker exec -it mycentos02 /bin/bash
	開啓容器 docker start/stop mycentos01
	埠對映 docker run -di --name=my_mysql -p 33306:3306 -e MYSQL_ROOT_PASSWORD=root mysql
	
	目錄對映 docker run -di --name=my_tomacat -p 8080:8080 -v /usr/local/webapps:usr/local/tomcat/webapps --privileged=true tomcat:7-jre7
	檔案複製
	docker op /usr/local/1.txt my_tomcat:/usr/local
	檢視ip docker inspect my_tomc
	Docker的備份和遷移:容器(commit)-映象(save)-.tar(load)-映象容器(docker run)
	

springmvc的controller執行緒安全嗎?怎麼解決

不安全,預設情況,也就是單例模式下需要執行緒安全的話必須使用ThreadLocal來封裝變數ThreadLocal<Integer> tl = new ThreadLocal<>(); 才能 纔能保證執行緒安全
若是多例在controller上新增@Scope(value = "prototype"),使controller變成多例的那麼,在沒有靜態成員變數的情況下他是執行緒安全的,但是若使用了靜態成員變數,那麼因爲靜態成員變數的建立時跟隨類的載入而載入的所以無法保證執行緒安全,所以要想保證執行緒安全须使用ThreadLocal來封裝這個變數

long型別對應mysql裡的哪種型別

Long型id數據對應MySQL數據庫中 bigint或numeric 數據型別;
java類 	  	           				   mysql數據庫
java.lang.Byte 			byte 			TINYINT
java.lang.Short 		short 			SMALLINT
java.lang.Integer 		integer 		INGEGER
java.lang.Long 			long 			BIGINT
java.lang.Float 		float 			FLOAT
java.lang.Double 		double 			DOUBLE
java.lang.BigDecimal 	big_decimal 	NUMERIC
java.lang.Boolean 		boolean 		BIT
java.lang.String 		string 			VARCHAR
java.lang.Boolean 		yes_no 			CHAR(1)('Y'或'N')
java.lang.Boolean 		true_false	 	CHAR(1)(‘Y’或'N')
java.uitl/sql.Date 		date 			DATE
java.sql.Time 			time 			TIME
java.sql.Timestamp 		timestamp 		TIMESTAMP
java.uitl.Calendar 		celendar 		TIMESTAMP
java.uitl.Calendar 		calendar 		TIMESTAMP
java.io.Serializable 	serializable 	VARBINARY/BLOB
java.sql.Clob 			clob 			CLOB
java.sql.Blob 			blob 			BLOB
java.lang.Class 		class 			VARCHAR
java.uitl.Locale 		locale 			VARCHAR
java.uitl.TimeZone 		timezone 		VARCHAR
java.uitl.Currency 		currency 		VARCHAR
 

類載入器

  JVM中的類的載入器主要有三種:啓動類載入器,拓展類載入器,應用類載入器。

     啓動類載入器(Bootstrap classLoader):又稱爲引導類載入器,由C++編寫,無法通過程式得到。主要負責載入JAVA中的一些核心類庫,主要是位於<JAVA_HOME>/lib/rt.jar中。

     拓展類載入器(Extension classLoader):主要載入JAVA中的一些拓展類,位於<JAVA_HOME>/lib/ext中,是啓動類載入器的子類。

     應用類載入器(System/Application classLoader):    又稱爲系統類載入器,主要用於載入CLASSPATH路徑下我們自己寫的類,是拓展類載入器的子類。

算數運算子優先順序排名

 口訣:淡雲一筆安洛三福 單目>算數運算子>移位>比較>按位元>邏輯>三目>賦值;單運移比按邏三賦

SQL中的行轉列,成績轉換使用CASE WHEN 列名 THEN ELSE END

jdk1.8支援的鎖有:讀寫鎖,自旋鎖,樂觀鎖

1、Mysql中儲存過程和儲存函數的區別?

  • 儲存過程(Stored Procedure)
    • 是一組爲了完成特定功能的SQL語句集,經編譯後儲存在數據庫中,使用者通過指定儲存過程的名字並給定參數(如果該儲存過程帶有參數)來呼叫執行它,儲存過程是可程式化的函數,在數據庫中建立並儲存,也可以由SQL語句和控制結構組成.簡單點說就是一堆有邏輯控制的SQL的合併
      • 一般使用在比較複雜的業務中,使用儲存過程的系統更加穩定
      • 儲存過程只在創造時進行編譯,以後每次儲存過程都不需要重新編譯,所以使用儲存過程也可以提高數據庫執行速度
      • 當對數據庫進行復雜操作時(入對多個表進行增刪改查時),可以將此複雜操作用儲存過程封裝起來域數據庫提供的事物處理結合一起使用.這些操作如果不結合起來的話需要多次鏈接數據庫,如果傳承儲存過程那麼只需要連線一次數據庫
      • 安全性高,可設定只有此使用者才具有對指定儲存過程的使用權
  • 儲存函數(stored function)

transient和volatile

transient用於序列化物件時標記此物件不被序列化

volatile修飾的成員變數每次被執行緒存取時都會使執行緒強迫去在共用記憶體中讀取該成員變數的值,當成員變數變化時,該變數修飾符會強迫執行緒將變化值寫回到共用記憶體, 結論:任何時刻不同的執行緒看到的成員變數都是最新的值

Java關鍵字和保留字

  • 關鍵字列表 (依字母排序 共50組):

    • abstract, assert, boolean, break, byte, case, catch, char, class, const(保留關鍵字), continue, default, do, double, else, enum, extends, final, finally, float, for, goto(保留關鍵字), if, implements, import, instanceof, int, interface, long, native, new, package, private, protected, public, return, short, static, strictfp, super, switch, synchronized, this, throw, throws, transient, try, void, volatile, while
  • 保留字列表 (依字母排序 共14組),Java保留字是指現有Java版本尚未使用,但以後版本可能會作爲關鍵字使用:

    • byValue, cast, false, future, generic, inner, operator, outer, rest, true, var, goto (保留關鍵字) , const (保留關鍵字) , null

java中控制數位精度

使用BigDecimal類來控制精度

HashMap

ConcurrentHashMap
使用segment來分段和管理鎖,segment繼承自ReentrantLock,因此ConcurrentHashMap使用ReentrantLock來保證執行緒安全。

類的載入順序

首先,需要明白類的載入順序

(1) 父類別靜態程式碼塊(包括靜態初始化塊,靜態屬性,但不包括靜態方法)

(2) 子類靜態程式碼塊(包括靜態初始化塊,靜態屬性,但不包括靜態方法 )

​ (3) 父類別非靜態程式碼塊( 包括非靜態初始化塊,非靜態屬性 )

​ (4) 父類別建構函式

​ (5) 子類非靜態程式碼塊 ( 包括非靜態初始化塊,非靜態屬性 )

​ (6) 子類建構函式

​ 其中:類中靜態塊按照宣告順序執行,並且(1)和(2)不需要呼叫new類範例的時候就執行了(意思就是在類載入到方法區的時候執行的)

2.其次,需要理解子類覆蓋父類別方法的問題,也就是方法重寫實現多型問題。

​ Base b = new Sub();它爲多型的一種表現形式,宣告是Base,實現是Sub類, 理解爲 b 編譯時表現爲Base類特性,執行時表現爲Sub類特性。

​ 當子類覆蓋了父類別的方法後,意思是父類別的方法已經被重寫,題中 父類別初始化呼叫的方法爲子類實現的方法,子類實現的方法中呼叫的baseName爲子類中的私有屬性。

​ 由1.可知,此時只執行到步驟4.,子類非靜態程式碼塊和初始化步驟還沒有到,子類中的baseName還沒有被初始化。所以此時 baseName爲空。 所以爲null。

Request中的方法

  • 設定字元編碼格式:request.setCharacterEncoding(「UTF-8」)
  • 獲取請求方式:request.getMethod()
  • 獲取http協定版本:request.getProtocol
  • 獲取請求的URL和URI:request.getRequestURLURI()(URI統一資源識別符號的子集是URL是具體的URI提供了定位該資源的資訊和URN用特定名稱空間的名字標識資源
  • 獲取請求頭欄位名列表:Request.getHeaderNames()
  • 獲取請求頭欄位值:Request.getHeader(headerName)
  • 獲取請求參數值:Request.getParameter(parameterName)
  • 獲取某個請求參數的多個值:Request.getParameterValues(「參數名」);會返回一個數組
  • 獲取實體內容,適用於POST方法的請求:Request.getInputStream()

Restful風格

  • 如果通過表單只能提交get和post請求

  • 如果通過ajax那麼可以指定多種請求型別

    • @RequestParam是把請求中指定名稱的參數給控制器中的形參賦值

      @RequestBody是獲取請求體

      @RequestHeader是獲取指定請求頭

      @PathVariable:

      用於系結 url 中的佔位符。例如:請求 url 中 /delete/{id},這個{id}就是 url 佔位符

      url 支援佔位符是 spring3.0 之後加入的。是 springmvc 支援 rest 風格 URL 的一個重要標誌

tomcat中的編碼問題

  • get請求tomcat7以下
  • [外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-3vJdaRIj-1597217156795)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566634597144.png)]
  • post請求需要在web.xml中設定全域性過濾器
  • [外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-QB4Qzlgi-1597217156797)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566634648019.png)]

禁用cookie的情況下session怎樣工作

  • cookie每次都會攜帶在請求中不禁用時jsessionid攜帶在cookie中
  • 如果禁止了cookie那麼需要將jsessionid攜帶在地址後面,需要在響應時使用response.encodeRedirectURL("/index.jsp"),將session的關聯從請求頭中放到請求地址中[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-pt4IkWaP-1597217156799)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566625926555.png)]

Timer不建議用,建議使用Excutorsquartz企業級定時任務建議使用的框架

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-I66Njdz8-1597217156801)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566626116260.png)]

間隔一秒鐘,執行上述控制檯的輸出.

建議使用Excutors.newScheduledThreadPool(2)建立延時執行執行緒

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-ejkFWunG-1597217156802)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566626413924.png)]

類之間的幾種關係>

**USES-A:**依賴關係,A類會用到B類,這種關係具有偶然性,臨時性。但B類的變化會影響A類。這種在程式碼中的體現爲:A類方法中的參數包含了B類。

**關聯關係:**A類會用到B類,這是一種強依賴關係,是長期的並非偶然。在程式碼中的表現爲:A類的成員變數中含有B類。

HAS-A:聚合關係,擁有關係,是關聯關係的一種特例,是整體和部分的關係。比如鳥羣和鳥的關係是聚合關係,鳥羣中每個部分都是鳥。

**IS-A:**表示繼承。父類別與子類,這個就不解釋了。

要注意:還有一種關係:組合關係也是關聯關係的一種特例,它體現一種contains-a的關係,這種關係比聚合更強,也稱爲強聚合。它同樣體現整體與部分的關係,但這種整體和部分是不可分割的。

java 中\n\r\t\f的區別

符號 意義
\n 遊標換行
\r 遊標回到第一個字元
\t 相當於tab
\f 換頁,print中木有意義

相對路徑和絕對路徑的理解

在資原始檔前加上/叫做絕對路徑,總是以webapp目錄爲起點

在資原始檔前不加/叫做相對路徑,相對於存取時的路徑列如

重定向和轉發

相應頭中包含資訊:302和location=地址(告訴瀏覽器去存取這個地址再次發送請求)

mybatis中的#{},${}的區別

Mybatis中 對映檔案中使用#{}和${}佔位符的區別 推薦使用#{}

${} 不會使用佔位符而是直接使用字串進行拼接
#{}會將其變爲?佔位符 底層使用where first_name=? preparedStatment.setString

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-NOeOJUHS-1597217156806)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566119062232.png)]
#更安全,sql</font><fontcolor=red>有sql注入風險</font> <font color = red>可以拼接sql中的任意部分,如:
select *from KaTeX parse error: Expected 'EOF', got '&' at position 22: …name} order by &̲{column} 可以將其中…{}括號內可以進行運算,#{}括號中不能進行運算
列如分頁時計算limi後面的索引和每頁顯示條數[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-SAVyFDn3-1597217156806)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566453255998.png)]
$可以在對映檔案中使用(mapper)也可以在覈心組態檔中使用#{}只能在對映檔案中使用

xml解析

dom 一次解析完

sax 以流的方式一行一行的讀

Java中vector和ArrayList的相關特性

1、vector執行緒安全Arraylist執行緒不安全

2、當集閤中使用的數據量較大時使用vector會比較有優勢,因爲擴容時vector增加一倍而ArrayList只增加一半

3、當查詢一個指定位置的數據他們所用的時間是相同的

JVM

常數池的數據結構是hashtable 在開源的jdk中有一個vm檔案下的class檔案中的c++檔案中實現的,string是,string建立時按照設計模式所說是new了一個再去比較,若無那麼複製到常數池中,

j*.exe

java,exe是java虛擬機器

javadoc.exe用來製作java文件

jdb.exe是java的偵錯程式

javaprof,exe是剖析工具

JVM記憶體的組成及其作用

分類兩大塊 Java記憶體和非Java記憶體(外堆)
Java記憶體有
	方法區(共用):
	虛擬機器棧(私有):執行緒內呼叫一次方法就會產生一個棧幀(一個方法就是一個棧幀,正在執行的叫活動棧幀),棧幀內包含方法內的區域性變數,方法參數,返回地址等
	本地方法棧(私有):其他語言寫的用native
	程式計數器(私有):記錄程式碼執行到哪一行
	堆空間(共用):
非Java記憶體(堆外記憶體)
	元空間:執行時常數池,類物件,類載入器,靜態變數,
	直接記憶體:NIO進行IO操作時用到的數據緩衝記憶體

位元組長度

位元組型別 長度
byte 1
short 2
int 4
long 8
double 8
float 4
boolean 2
char 1

對於JVM記憶體設定參數:

-Xss設定虛擬機器棧

-Xmx10240m -Xms10240m -Xmn5120m -XXSurvivorRatio=3

-Xmx:最大堆記憶體大小

-Xms:最小堆記憶體大小

-Xmn:堆記憶體中年輕代大小

-XXSurvivorRatio:年輕代中Eden區和Survivor區的大小比值

年輕代中Survivor區有兩個

常見的程式碼優化技術

複寫傳播,刪除死程式碼,強度削弱,歸納變數刪除

複寫傳播:

图片说明

  • 複寫語句:形式爲f = g 的賦值
    • 優化過程中會大量引入複寫
    • 複寫傳播變換的做法是在複寫語句f = g後,儘可能用g代表f
    • 複寫傳播變換本身並不是優化,但它給其他優化帶來機會
      • 常數合併(編譯時可完成的計算)
      • 死程式碼刪除
死程式碼刪除
  • 死程式碼是指計算的結果決不被參照的語句
  • 一些優化變換可能會引起死程式碼
程式碼外提
  • 程式碼外提是回圈優化的一種
  • 回圈優化的其它重要技術
    • 歸納變數刪除
    • 強度削弱
      • hash值計算時使用31是31的乘法可以使用移位和減法替換

例:

`while``(i <= limit - ``2``) ...``// 程式碼外提後變成``t = limit - ``2``;``while``(i <= t) ...`
歸納變數刪除
`j = j - ``1``t4 = ``4` `* j``t5 = a[t4]``if` `t5 > value ``goto` `B3`
  • j和t4的值步伐一致地變化,這樣的變數叫作歸納變數
  • 在回圈中有多個歸納變數時,也許只需要留下一個
  • 這個操作由歸納變數刪除過程來完成
  • 對本例可以先做強度削弱,它給刪除歸納變數創造機會
強度削弱
  • 強度削弱的本質是把強度大的運算換算成強度小的運算,例如將乘法換成加法運算。

執行緒安全

成員變數和靜態成員變數

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-x2BVkHmp-1597217156808)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566193874731.png)]

執行緒安全的類

Vector,Hashtable,Stack

執行緒不安全的類

ArrayList Hashmap

陣列不是原生類

控制切面通知的執行順序

首先先將通知分爲多個切面,每個切面一個通知,使用order來控制

對於前置通知,order小的在前面,對於後置通知,order小的在後面

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-eEP7pFlB-1597217156809)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566124159206.png)]

用註解設定宣告式事務

xml

事務管理器

​ 1、事務管理器

​ 2、tx:annotation-driven/

​ 在程式碼中

​ @Transactional可以加在方法或者類上 有很多屬性

Mybatis

​ 持久層

​ ORM mapping

​ 開發步驟

​ 1、匯入座標

​ 2、表,實體類

​ 3、對映檔案(sqlmapconfig組態檔)

<mapper namespace=名稱空間>
    <select id=唯一標識 resulttype=對應的java型別 parameterType=參數型別>select。。from 。。where
    </select>
</mapper>    


[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-r4OxvMsi-1597217156810)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566175653671.png)]

​ 4、核心組態檔

​ 數據源

<mapper resource=對映檔案路徑></mapper>
<typeAliases><package name=包名> </typeAliases>
將數據庫中的下劃線變爲java中的駝峯命名法
    

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-2eJvNQUP-1597217156811)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566175930789.png)]

$時直接拼接字串有sql注入的風險

sql中出現特殊字元

使用<![CDATA[出現特殊字元的語句]]>

這樣就不會將特殊字元進行跳脫 如sql語句中有小於號大於號

分頁查詢

邏輯分頁

sql語句是查詢所有 java中 public Listfindbypage(RowBounds rb);

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-0jPZst3u-1597217156811)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566184127921.png)]

物理分頁

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-TlCaHRoJ-1597217156812)(C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566184091021.png)]

mybatis generator外掛的使用

第一步匯入依賴[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-xvNZVvRZ-1597217156813)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566204555197.png)]

第二步 編寫組態檔

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-wYxGcxxh-1597217156815)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566204697848.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-u2V0tMVW-1597217156816)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566204716002.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-fa3CbKK5-1597217156817)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566204829215.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-guAhH9Qv-1597217156817)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566204837090.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-QWoLBe5L-1597217156818)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566204941059.png)]

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-lRs6BVIT-1597217156819)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566205064579.png)]

sql查詢時使用模糊查詢儘量不寫前%,這樣就能使用索引來告訴查詢

多表查詢

property是屬性對應的是類中的屬性

association是關聯標籤

要是有物件那麼就用assocation標籤將查出來的數據封裝在物件中

主鍵使用id標籤其他使用result標籤 標籤的屬性colum是表中查出來的值 property是類中的屬性名 association標籤中的property是類中的屬性名

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-PN33cFnq-1597217156820)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566358095210.png)]

使用autoMapping標籤屬性時,可以省略標籤中的result中屬性名與列名一樣的result標籤

jdk1.7中抽象類和介面的區別

介面(interface)可以說成是抽象類的一種特例,介面中的所有方法都必須是抽象的。介面中的方法定義預設爲public abstract型別,介面中的成員變數型別預設爲public static final。另外,介面和抽象類在方法上有區別:

  1. 抽象類中可以包含靜態方法,介面中不能包含靜態方法
  2. 抽象類和介面中都可以包含靜態成員變數,抽象類中的靜態成員變數的存取型別可以任意,但介面中定義的變數只能是public static final型別,並且預設即爲public static final型別
  3. 一個類可以實現多個介面,但只能繼承一個抽象類。二者在應用方面也有一定的區別:介面更多的是在系統架構設計方法發揮作用,主要用於定義模組之間的通訊契約。而抽象類在程式碼實現方面發揮作用,可以實現程式碼的重用,例如,模板方法設計模式是抽象類的一個典型應用,假設某個專案的所有Servlet類都要用相同的方式進行許可權判斷、記錄存取日誌和處理異常,那麼就可以定義一個抽象的基礎類別,讓所有的Servlet都繼承這個抽象基礎類別,在抽象基礎類別的service方法中完成許可權判斷、記錄存取日誌和處理異常的程式碼,在各個子類中只是完成各自的業務邏輯程式碼。
  4. 抽象類中的抽象方法的存取型別可以是public,protected和預設型別
  5. 抽象類中可以有普通成員變數,介面中沒有普通成員變數
  6. 抽象類中可以包含非抽象的普通方法,介面中的所有方法必須都是抽象的,不能有非抽象的普通方法。
  7. 抽象類可以有構造方法,介面中不能有構造方法。

Mybatis中多對多查詢流程

數據庫中有三個表abc,其中b表中的內容時a的id對應的c的id,比如a是一個人,c是這個人所擁有的技能:語數英;所以說可以有多個人有多種技能,此時b表就展示了多個人對應的多個技能,比如李青精通語數,薇恩精通英數,蔚精通語數英.這三張表就是一種多對多的表關係;在這種多表查詢中我們應該先使用左外連線查出來這個人所擁有的技能的編號,再使用內連線查詢這個編號對應的技能

select a.*,b.* from a left join b on a.id=b.a_id 
inner join c on c_id=c.id

第一行sql就是使用左外連線查詢出來這個人對應的技能編號,第二行sql就是將查詢出來的這個技能編號的id作爲內連線的查詢條件來查詢具體的技能是什麼.

mybatis註解開發

第一步在測試類中新增成員方法上邊新增@Before 來載入資原始檔,獲取session mapper

第二部進行數據測試 將介面中對應的crud方法上新增對應的註解

@Insert:實現新增

@Update:實現更新

@Delete:實現刪除

@Select:實現查詢

註解括號中寫入sql字串代表需要該介面的抽象方法實現時的方法

多對一 一對一使用@ONE

一對多多對多使用@Many

集合封裝使用@Result({多個@Result(Colum="",property="")})註解

@Result:實現結果集封裝

@Results:可以與@Result 一起使用,封裝多個結果集

@One:實現一對一結果集封裝

@Many:實現一對多結果集封裝

使用註解一對一查詢時相當於第一次查詢結果的結果集中有一個物件這個物件通過第一次查詢的結果的一列數據作爲條件再去查詢第二張表;就是a表和b表,a表中有一個數據是匹配的b表的id 通過這個id再區查詢b這就是一對一

mybatis的sql一級快取優化

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-qRzlHf5V-1597217156821)(/C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/1566377664918.png)]

弄了個map 鍵爲sql語句 值爲sql的結果,map隨着session的關閉而消失

mybatis的sql二級快取優化

設定:新增@CacheNamespace

或在xml中新增標籤

註解新增在需要使用的介面上

在user物件上新增序列化介面

是所有sqlsession共用的

前端學習

資訊

樣式

互動

查:MDN-HTML/CSS/JS的一切知識

練:實踐出真知-Chrome DevTools

想:理解架構-MVC->MVVM

換:切換思維方式

HTML

把html想象成word文件
區分內容與非內容
列如麪包屑中的大於號應該是CSS中的
HTML不是隻共螢幕顯示使用
a11y,可能是給盲人翻譯閱讀,所以需要區分內容和非內容

CSS

從粗糙到精緻的遞進式還原:相當於建樓
做CSS框架的使用者
MDN和《CSS設計指南》
理解CSS的思維模型:
如同畫畫:構圖->物體->着色
CSS:佈局->元件->定製

CSS原理

爲什麼叫層疊樣式表:先看到細部規則(若無規則)->區域性規則(若無規則)->全域性規則>
爲什麼需要選擇器:只有選擇器才能 纔能確定他是什麼規則
樣式繼承是怎麼回事:通常出現在文字樣式如字型
總之:責任鏈模式:
實踐 - Chrome DevTools;與UX共同作業

不建議使用!important 病毒特性,若此處定義了優先順序,其他地方若是需要高於此優先順序那麼也需要使用!important

JS和TS

動態語言中常見的鴨子型別

​ 如果兩個型別的形態和行爲一致,那麼他們兩個可以被稱爲一個型別但java不行

靜態語言中常見的型別系統

優點:自文件化,對讀者友好,型別資訊,對IDE友好,模組化,對團隊友好;外掛型別資訊,對遺留程式碼友好;Anders和HejLsberg,對…粉絲友好(hhh)

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-0cofn8GQ-1597217156822)(…/桌面背景/1572525503510.png)]

docker的兩種不同的導出命令

  • export->import–>容器的匯入導出
    • 僅儲存容器導出時的狀態
    • docker commit 將容器變爲映象
    • docker images --tree 僅有當前層的數據
  • load->save–>映象的匯入導出:
    • 會儲存映象的所有歷史紀錄(包含歷史層)
    • docker images --tree 有所有可以回滾的數據