小技巧(一)
2020-03-18
liunx不常見但實用的命令
# 統計行數 字數 字符數
wc 123.txt
# 找到并洗掉30天以前的符合格式的檔案
find /home/midou/logs// -mtime +30 -name "*.log.gz" -exec rm -rf {} \;
# 比較檔案不同
diff testA.txt testB.txt
2020-03-19
快速創建相似表陳述句
CREATE TABLE order_record like order_today;
事務模式 2PC(兩階段提交),3PC(三階段提交),TCC(補償事務)的問題
2PC可能帶來的三大問題
- 第二階段提交程序若網路抖動或不穩定導致一方參與者沒有收到commit訊息,可能導致資料不一致
- 網路超時問題帶來的網路同步阻塞問題,參與者占用的資源得不到釋放
- 事務管理器單點問題,一旦協調者故障,它所造成的阻塞問題,哪怕有重新選舉出協調者也不能解決前一個的遺留問題
3PC可能帶來的問題
- 兩階段和三階段的本質區別我理解就是加入了詢問參與者事務是否可以提交階段,一旦因為網路抖動不能執行這一步,超時后協調者會向所有參與者發送abort中斷命令,加入第二階段的意義在于,確保提交前狀態一致
- 第三階段同樣若沒有收到參與者成功回應,也會發送abort中斷事務,若協調者故障,參與者一直沒收到commit信號,則會自動提交事務
- 簡單來講就是 => 是否可以提交請求->事務是否可以正常執行->統一提交事務
- 3PC還存在問題,不能確保在協調者故障后,自動提交的一致性,可能協調者呼叫參與者A是通知abort中斷事務,但參與者B由于網路問題,沒有接收到,自動提交,導致不一致問題
TCC的問題
- 事務補償機制,是通過業務層代碼實作,侵入性太強,每個操作都需要try confirm cancel三個介面操作
- 開發難度大,較難維護,要確保資料一致性,confirm和cancel還要保證冪等性
mybatis需要注意問題
- mybatis Integer型別不能判!='',否則0值傳不進來
2020-03-23
記一次k8s節點一直重啟問題排查
查找
- 經初步排查,發現由于記憶體溢位導致節點重啟
查節點
- top 發現dockered占用了3個G
- pidof dockered 查id
- lsof -p id | wc -l 查看打開檔案數,上萬肯定多了
- sudo lsof -p 4364|grep 137f8a0eb714 | wc -l 查看容器節點檔案打開數
- 一般每個容器打開節點數為5個上下,若因為單個容器的原因導致檔案打開節點數過多,可以專門針對該容器處理,最簡單的就是重啟它
- 而我發現我的問題是docker.sock 有非常多,似乎是容器本身打開了很多節點,沒查出具體原因,但解決方法很簡單,比較徹底的就是重啟ECS,或許重啟docker也行
2020-03-24
JVM引數優化
- 用以分析優化JVM引數和剛開始配置該引數
Java執行緒Dump分析
- 用以分析dump資料
Java記憶體Dump分析
- 用以分析JVM記憶體
匯出hprof
jmap -dump:format=b,file=/home/admin/logs/heap.hprof 6214
匯出dump
jstack -l 6111 > xxx.dump
2020-03-25
idea技巧
ctrl+alt+shift+N可以直接查spring上的mapping,比如/user/getPhone- 點idea中
database的表,再ctrl+Q可以快速查看表創建陳述句,索引創建陳述句,和開頭10條資料 shift+alt+c查詢最近作出的改變
資料庫優化技巧(不常見)
- 使用
left join的時候,左邊表盡量小,更節省開銷,有條件的盡量放到左邊處理 - exist & in的合理利用
select * from A where deptId in (select deptId from B);
select * from A where exists (select 1 from B where A.deptId = B.deptId);
mysql優化原則,就是小表驅動大表,小的資料集驅動大的資料集,從而讓性能更優,
因此,我們要選擇最外層回圈小的,也就是,如果B的資料量小于A,適合使用in,如果B的資料量大于A,即適合選擇exist,
- LIMIT n, m的效率是十分低的,一般可以通過在WHERE條件中指定范圍來優化 WHERE id > ? limit 10
2020-03-26
mysql知識點補充
- explain的key_len表示使用到的索引長度,可以用來對比哪個索引沒有用到
show profile進行sql調優
show VARIABLES like 'profiling'判斷是否開啟調優set profiling=on開啟show profiles- 使用
show profile cpu,block io for query Query_ID;進行針對sql診斷
①converting HEAP to MyISAM:查詢結果太大,記憶體不夠,資料往磁盤上搬了,
②Creating tmp table:創建臨時表,先拷貝資料到臨時表,用完后再洗掉臨時表,
③Copying to tmp table on disk:把記憶體中臨時表復制到磁盤上,危險!!!
④locked,
如果在show profile診斷結果中出現了以上4條結果中的任何一條,則sql陳述句需要優化,
全域查詢日志開啟(生產環境別開)
show VARIABLES like '%general%%'查看是否開啟set global general_log=1;開啟set global log_output='TABLE';可通過sql查詢查詢過的sql
表鎖判斷與解決
show open tables where in_use>0;則in_use大于0則表示有鎖unlock tables;解鎖表show status like 'table%';,其中Table_locks_waited出現表級鎖定爭用而發生等待的次數(不能立即獲取鎖的次數,每等待一次鎖該值加1),此值高則說明存在較嚴重的表級鎖爭用情況
行鎖判斷與解決
show status like 'innodb_row_lock%';
Innodb_row_lock_current_waits 0
Innodb_row_lock_time 39122
Innodb_row_lock_time_avg 4890
Innodb_row_lock_time_max 23008
Innodb_row_lock_waits 8
①Innodb_row_lock_current_waits:當前正在等待鎖定的數量,
②Innodb_row_lock_time:從系統啟動到現在鎖定的時長,
③Innodb_row_lock_time_avg:每次等待鎖所花平均時間,
④Innodb_row_lock_time_max:從系統啟動到現在鎖等待最長的一次所花的時間,
⑤Innodb_row_lock_waits:系統啟動后到現在總共等待鎖的次數,
2020-03-31
Spring回圈依賴問題
- 分為建構式依賴,屬性依賴,建構式依賴不能解決只會報例外
- 屬性依賴Spring采用提前暴露物件的方式
- Spring的單例物件初始化主要分為三部:
- 實體化物件,會呼叫構造方法;createBeanInstance
- 屬性填充,包括依賴的物件填充;populateBean
- 呼叫xml中init初始化方法;InitializeBean
- Spring解決回圈依賴使用的是三級快取,分別指
- singletonFactories 單例工廠cache
- earlySingletonObjects 提早曝光的單例物件cache
- singletonObjects 單例物件cache
2020-04-02
Kafka為什么這么快
- 訊息批量壓縮發送,減少網路IO損耗
- 通過Memory Mapped Files(mmap)記憶體映射檔案提高IO速度,資料尾部寫入速度最優
- 基于sendfile,減少內核到用戶空間的拷貝程序,提升讀取速度
tomcat限流
- tomcat有server.tomcat.accept-count這個引數,如果設定的比較小,超出的請求不會被處理,也可以減少tomcat執行緒的占用,比改代碼風險小的多
arthas
安裝啟動
wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar --target-ip 0.0.0.0
熱修改代碼
- jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java 保存反編譯檔案
- sc -d *UserController | grep classLoaderHash 找到類加載編號
- mc -c 1be6f5c3 /tmp/UserController.java -d /tmp 編譯
- redefine /tmp/com/example/demo/arthas/user/UserController.class 重新加載
jad --source-only com.onegene.biology.biologywork.util.ReportUtil > /tmp/ReportUtil.java
sc -d *ReportUtil | grep classLoaderHash
mc -c 66b1b2c /tmp/ReportUtil.java -d /tmp
redefine /tmp/com/onegene/biology/biologywork/util/ReportUtil.class
2020-04-10
Mapper
tk-mybatis除了Mapper介面其實還提供了更多便捷介面
2020-04-15
通用日期格式化jackson配置
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
// 通過該方法對mapper物件進行設定,所有序列化的物件都將按改規則進行系列化
// Include.Include.ALWAYS 默認
// Include.NON_DEFAULT 屬性為默認值不序列化
// Include.NON_EMPTY 屬性為 空("") 或者為 NULL 都不序列化,則回傳的json是沒有這個欄位的,這樣對移動端會更省流量
// Include.NON_NULL 屬性為NULL 不序列化
objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 允許出現特殊字符和轉義符
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
// 允許出現單引號
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
return objectMapper;
}
2020-04-17
@EnableAutoConfiguration配合META-INF/spring-factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration
2020-04-18
- 比較兩個內容是否有變化,只需要比較兩者的md5值
2020-04-23
@Vaildator在Controller層物件的屬性若是物件,屬性需要加上@Vaild注解,屬性物件內的引數注解才會起作用
2020-04-24
- idea可以條件斷電
2020-04-25
CaseFormat來自guava的駝峰轉換工具
CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelNameUpperCamel))
2020-04-27
- 誤刪資料庫恢復辦法,前提是資料庫有備份或開啟binlog日志
2020-05-09
raft協議
- 所有節點都會以follower狀態開始,如果沒有收到leader的來信,那么他們都可以成為候選人
- 選舉超時,指follower成為candidate之前所等待的時間,等待超時后,follower成為candidate開始新的選舉任期
- 最先選舉超時的節點,會先投自己一票,并向別的所有節點請求投票,如果其它節點在term任期內還沒有投票則會投給它
- 一旦候選人candidate獲得大多數投票,便成為leader,leader持續向follower發送心跳
- 一旦leader掛了,在選舉超時后,有節點會成為candidate開始新一輪投票選舉
- 當有兩個節點同時發起候選人投票請求,且票數一致,會在這兩個candidate中重設選舉超時時間,先到時間的會再發起請求投票,確定leader
- 當發生網路磁區,可能會產生兩個領導者,客戶端請求兩個領導者產生不同的資料,但肯定磁區資料復制不能達到半數節點,只有達到半數節點的磁區能完成日志提交,當網路恢復時,將會以更高的term為準,未提交的資料將會回滾
ZAB協議
特性
- 保障已經在Leader服務器上提交的事務最終被所有的服務器提交
- 確保丟棄那些只在leader上被提出而沒有被提交的事務
Zab協議原理
- 發現:zk集群必須選舉出一個leader行程,同時leader會維護一個follower可用客戶端串列
- 同步:leader負責將本身的資料和follower完成同步,做到多副本存盤
- 廣播:leader接收客戶端新的事務Proposal請求,并廣播給所有的follower
協議程序
包括了崩潰恢復和訊息廣播
2020-05-11
資料庫亂碼
- 資料庫的亂碼,可能只需要在mysql的url后加
&characterEncoding=UTF-8
界面化介面定義工具Hasor
2020-05-12
分布式鎖的優化思路:購買商品,當有10000個請求同時并發過來,可以嘗試用分段鎖+合并庫存的方式,比如將10000個庫存拆分成10個1000個庫存,相當于10個鎖,可分配到不同機器上,當庫存不夠時,再鎖別的庫存合并
2020-05-14
Mybatis
- 一級快取 session級別
- 二級快取 namespace 即mapper級別的
2020-05-15
TODO用法
- TODO添加,設計代碼目錄
Redis sortedset 實作延遲佇列
- score放時間戳,用zrangebyscore拉一定時間的資料,時間延遲讀取
2020-05-18
- synchronize 編譯后通過monitorenter 和 monitorexit指令實作互斥同步
2020-05-27
synchronized和ReentrantLock的區別
首先synchronized和ReentrantLock都是可重入鎖
區別:
- synchronized是JVM層面實作,reentrantLock是JDK代碼層面實作
- synchronized非公平鎖,ReentrantLock可實作公平鎖
- ReentrantLock可中斷鎖
- ReentrantLock可指定喚醒執行緒 Condition
2020-05-28
ThreadLocal
- ThreadLocal方法后 最好手動呼叫remove()方法,否則value不會被垃圾回收,其key為弱參考,value為強參考,可能導致key為null而value一直存在的情況
ThreadPoolExecutor 飽和策略
- ThreadPoolExecutor.AbortPolicy:拋出 RejectedExecutionException來拒絕新任務的處理,
- ThreadPoolExecutor.CallerRunsPolicy:呼叫執行自己的執行緒運行任務,您不會任務請求,但是這種策略會降低對于新任務提交速度,影響程式的整體性能,另外,這個策略喜歡增加佇列容量,如果您的應用程式可以承受此延遲并且你不能任務丟棄任何一個任務請求的話,你可以選擇這個策略,
- ThreadPoolExecutor.DiscardPolicy: 不處理新任務,直接丟棄掉,
- ThreadPoolExecutor.DiscardOldestPolicy: 此策略將丟棄最早的未處理的任務請求,
AQS
AQS核心思想是,如果被請求的共享資源空閑,則將當前請求資源的執行緒設定為有效的作業執行緒,并且將共享資源設定為鎖定狀態,如果被請求的共享資源被占用,那么就需要一套執行緒阻塞等待以及被喚醒時鎖分配的機制,這個機制AQS是用CLH佇列鎖實作的,即將暫時獲取不到鎖的執行緒加入到佇列中,
2020-06-02
@Transactional
在@Transactional注解中如果不配置rollbackFor屬性,那么事物只會在遇到RuntimeException的時候才會回滾
HyperLogLog
- 用戶基數統計,比如訪問用戶數uv,同一用戶去重,存在一定誤差
Redis的發布訂閱問題
- 沒有Ack機制,不保證資料的連續,如果沒有一個消費者,那么訊息會被直接丟棄,
- 不持久化訊息,如果Redis宕機,所有訊息都會直接丟棄
2020-06-04
Netty知識點
特點
Netty是一個基于NIO的網路通信框架,具有高并發,傳輸快,封裝好的特點
option
ChannelOption.SO_BACKLOG,標識當服務器請求處理執行緒全滿時,用于臨時存放已完成三次握手的請求的佇列的最大長度,如果未設定或所設定的值小于1,Java將使用默認值50,ChannelOption.SO_KEEPALIVE,是否啟用心跳保活機制,在雙方TCP套接字建立連接后(即都進入ESTABLISHED狀態)并且在兩個小時左右上層沒有任何資料傳輸的情況下,這套機制才會被激活,ChannelOption.TCP_NODELAY,如果要求高實時性,有資料發送時就馬上發送,就將該選項設定為true關閉Nagle演算法;如果要減少發送次數減少網路互動,就設定為false等累積一定大小后再發送,默認為false,ChannelOption.SO_RCVBUF AND ChannelOption.SO_SNDBUF,定義接識訓者傳輸的系統緩沖區buf的大小ChannelOption.ALLOCATOR
Netty4使用物件池,重用緩沖區
bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
bootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
handler()和childHandler()
handler()和childHandler()的主要區別是,handler()是發生在初始化的時候,childHandler()是發生在客戶端連接之后
佇列
原則:都是先入先出
- add 添加成功回傳true,失敗拋例外
- poll 獲取一個佇列資料并洗掉,不存在回傳null
- put 阻塞試的放入佇列,佇列滿了則阻塞等待別的執行緒取走資料才能放入
- take 佇列有資料則直接獲取并洗掉一個,沒資料阻塞等待其它執行緒放入資料
- offer 添加資料,佇列滿了不阻塞,直接回傳false表示添加失敗
- peek 獲取佇列資料且不洗掉,獲取不到則回傳null
2020-06-05
Mysql更新陳述句執行程序

臟頁是什么?
就是記憶體資料頁與磁盤記憶體頁的內容不一致時的記憶體頁叫做臟頁,記憶體頁資料寫入磁盤后,資料一致了,就是干凈頁了,
MVCC的實作原理是怎么樣的?
mvcc主要適用于提交讀,可重復讀,可以解決幻讀的問題,
innodb在解決幻讀的問題主要是通MVVC 多版本并發版本控制來實作的
就是每一行資料中額外保存兩個隱藏的列,創建時的版本號,洗掉時的版本號(可能為空),滾動指標(指向undo log中用于事務回滾的日志記錄)
事務在對資料修改后,進行保存時,如果資料行的當前版本號與事務開始取得資料的版本號一致就保存成功,否則保存失敗,
B樹與B+樹的區別是什么?
- B樹每個節點會保存關鍵字,索引和資料,而B+樹只有葉子節點保存資料,其他節點只保存關鍵字和索引,有更低的樹高,所以相同的記憶體空間可以容納更多的節點元素,
- B+樹的所有資料都存在葉子節點上,所以查詢會更加穩定,而且相鄰的葉子節點都是連接在一起的,更加適合區間查找和搜索,
為什么不用紅黑樹?
紅黑樹等平衡樹也可以用來實作索引,但是檔案系統及資料庫系統普遍采用 B+ Tree 作為索引結構,主要有以下兩個原因:
(一)更少的查找次數
平衡樹查找操作的時間復雜度和樹高 h 相關,O(h)=O(logdN),其中 d 為每個節點的出度,
紅黑樹的出度為 2,而 B+ Tree 的出度一般都非常大,所以紅黑樹的樹高 h 很明顯比 B+ Tree 大非常多,查找的次數也就更多,
(二)利用磁盤預讀特性
為了減少磁盤 I/O 操作,磁盤往往不是嚴格按需讀取,而是每次都會預讀,而B+數中存盤的葉子節點在記憶體中是相鄰的,這樣可以讀取會快一些,
hashMap鍵值對添加程序

HashMap 非執行緒安全
HashMap是非執行緒安全的,(例如多個執行緒插入多個鍵值對,如果兩個鍵值對的key哈希沖突,可能會使得兩個執行緒在操作同一個鏈表中的節點,導致一個鍵值對的value被覆寫)
ConcurrentHash鍵值對添加程序

- 鏈表長度大于等于8,且陣列長度大于64時,才會轉換紅黑樹
ConcurrentHashMap 執行緒安全
ConcurrentHashMap是執行緒安全的,主要是通過CAS操作+synchronized來保證執行緒安全的,
2020-06-08
kafka怎么保證資料不丟失
- 每個topic至少設定2個partition
- 設定leader至少感知有一個follower活著
- 設定ack=all即每天資料都得到回應后才認為寫成功
2020-06-09
Mysql知識點
!=特定值,查詢結果不包含null
2020-06-15
spring aop事務呼叫方式,呼叫同一類中B方法
((ServiceA ) AopContext.currentProxy()).insert();
2020-06-22
Kubeasz
k8s快速安裝
2020-06-28
IO多路復用理解
模式有 select,poll,epoll
- select的最大連接數默認1024存在限制;資料需要從用戶態拷貝到內核態,開銷也比較大;對socket掃描采用輪詢的方法,效率較低
- poll和select的區別,取消了最大連接數的限制
2020-07-08
Filter和Interceptor區別
- 實作原理Filter使用函式回呼,通過doFilter()方法實作;interceptor通過反射動態代理實作
- 使用范圍Filter依賴Tomcat等容器,只能在web程式中使用;interceptor依賴Spring管理,不僅僅可以用在web程式
- 觸發時機不同
2020-07-09
下載PDF檔案,中文名亂碼解決
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;fileName=" + new String((fileName + ".pdf").getBytes("UTF-8"), "iso-8859-1"));
顯示SQL優化后陳述句
explain后加show warnings;一起執行
SQL快速造資料
DELIMITER ;;
CREATE PROCEDURE insertData()
BEGIN
declare i int;
set i = 1 ;
WHILE (i < 1000000) DO
INSERT INTO student(`name`,class,`page`,`status`)
VALUES(CONCAT('class_', i),
CONCAT('class_', i),
i, (SELECT FLOOR(RAND() * 2)));
set i = i + 1;
END WHILE;
commit;
END;;
CALL insertData();
simpread(簡悅)
一款超好用的閱讀插件,可以幫我們聚焦需要閱讀的內容
GitHub地址:https://github.com/Kenshin/simpread
2020-07-14
一款Redis客戶端,window和mac都有
Github地址:https://github.com/qishibo/AnotherRedisDesktopManager
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/103712.html
標籤:Java
下一篇:Git 的這個神技,學會爽歪歪~
