作的是用html5 + 一些vue , mui, 阿拉丁的一些js 融合的框架, 作的嵌套開發,不是原生頁面, 作的是插件,是放在別人的app平臺進行部署。
共享鎖下其它用戶能夠併發讀取,查詢數據。但不能增刪改數據和資源共享,加了共享鎖能夠繼續加共享鎖,不能加排他鎖; 排他鎖下不能加其餘鎖,排他鎖內能夠讀寫, 其餘用戶只能等當前用戶鎖釋放掉後,才能讀寫; 共享鎖只用於表級, 使用lock命令 ,排他鎖用於行級 ,使用for update; 解鎖須要dba的權限,找到當前鎖的sid, 而後kill掉便可。
Spring+springmvc+mybatis 框架 , Dubbo, zookeeper, maven, log4j, redis , 經常使用的一些設計模式思想要記, socket , rocketmq , quartz , ESB, webservice
簡單工廠(例如在配置文件中定義一個bean), 單例模式(能夠在xml中指定使用單例仍是每次new新的實例), 適配器, 觀察者模式(監聽器的實現), 策略模式(定義不一樣算法,根據不一樣客戶需求調用不一樣方法), 模板方法(jdbc鏈接池這塊,將變化的東西集中寫在一個地方,而後經過傳入回調給模板對象,即完成調用),
AOP切面編程, 實現原理是基於動態代理實現的。動態代理至關於中轉,全部客戶端的請求,我能夠集中到一份方法進行處理,能夠根據我本身的處理邏輯控制是否進行轉接, 也至關於加強,在實際調用的過程當中,順帶執行點其餘任務 ;使用場景:安全校驗,事務,權限管理,日誌等。 Ioc 控制反轉,xml中bean的注入, 咱們須要的對象不須要本身手動去new了,全都交給spring容器進行管理,用到什麼直接從spring中取就好了。
Bean的定義, 靜態文件過濾, 上傳下載文件配置,數據庫鏈接池配置,事務配置,持久層配置,外包文件引入, 經常使用註解, 緩存配置:@AspectJ(註解切面, @EnableAspectJAutoProxy註解開啓Spring對AspectJ代理的支持), xml中可配置bean是否單例模式使用,自定義監聽器, 自定義攔截器, @Import(導入配置項), @Scheduled(配置定時任務),事務註解@Transactional
用過, xml中引入tx標籤,定義事務; 項目service層使用@Transactional註解,實現事務操做,可聲明只讀或寫; 使用攔截器配置事務;xml中定義bean, 裝配spring的事務類,經過屬性賦值,實現事務配置;
反射,jvm在類的編譯加載過程當中,將對應的類,屬性登記在冊,而後反射經過在類加載運行過程當中,經過對應的類的名稱或者他的一個實例對象,去找對應這個類的全部方法和屬性,若是明確知道哪一個方法,還能夠經過傳參來執行這個方法。
@Aspect(配置切面) @Before(前置加強,都會執行) @After(後置加強,都會執行) @AfterReturning(後置加強,目標方法執行成功後纔會執行) @AfterThrowing(後置加強, 拋出異常後會執行) @Around(環繞加強, 至關於前置加強和後置目標方法執行成功後會執行) @annotation(能夠指定切面執行時,只要有請求就能夠執行,不用指定具體的代碼層級)
Concat: 字符串拼接, 或者 || Instr: 指定字符串位置 Length: 長度 Trim: 去空格 Lower: 小寫 Upper:大寫 Nvl: 判斷空 Replace: 替換 Substr: 截取 Floor: 向下取整 To_number: To_char: To_date: Decode: 判斷函數等等
對於查詢頻率高的字段建立索引html
索引的數目不宜太多前端
選擇惟一性索引vue
儘可能使用列數據量少的索引html5
儘可能使用前綴來索引java
刪除再也不使用或者不多使用的索引git
select *,可能會致使不走索引web
索引列上存在null值,可能不能走索引面試
索引列上有函數運算,致使不走索引redis
隱式類型轉換致使不走索引算法
!=或者<>(不等於),可能致使不走索引
使用like, in 等, 可能致使不走索引
樂觀鎖適用於寫比較少的狀況下(多讀場景); 通常多寫的場景下用悲觀鎖就比較合適(共享資源每次只給一個線程使用,其它線程阻塞,用完後再把資源轉讓給其它線程)
大類有iterator, collection , map ,array Iterator包括: ListIterator, Collection包括: list, set, linkedlist, arraylist,hashset, linkedhashset, treeset(使用二叉樹排序), sortedset Map包括: hashmap, ConcurrentHashMap , treemap , sortedmap 自定義集合內部排序,須要實現comparable 接口
- 存儲方式是以鍵值對存儲的,怎麼根據key找到對應的值的? map中有兩個hash值是同樣的, 怎麼找到對應的value 或者key ? 存儲的方式是鍵值對,底層是數組和鏈表的形式存在,實現類是Entry - 總結:HashMap的實現原理: 利用key的hashCode從新hash計算出當前對象的元素在數組中的下標 存儲時,若是出現hash值相同的key,此時有兩種狀況。(1)若是key相同,則覆蓋原始值;(2)若是key不一樣(出現衝突),則將當前的key-value放入鏈表中 獲取時,直接找到hash值對應的下標,在進一步判斷key是否相同,從而找到對應值。 理解了以上過程就不難明白HashMap是如何解決hash衝突的問題,核心就是使用了數組的存儲方式,而後將衝突的key的對象放入鏈表中,一旦發現衝突就在鏈表中作進一步的對比。 - Jdk7,8的區別: jdk8添加了紅黑樹,在元素個數超過8個纔會使用, jdk7中有一個內部類Entry, jdk8使用的是Node類, 使用hashmap要注意若是key存儲的是對象,則必定要從新hashcode和equal方法 Map先根據key的hash值到table數組中找對應的下標,獲取對應的entry, 若是一個位置存在多個entry,那麼hash值確定也是相等的,遍歷全部entry, 去比較entry的key值,若是與傳遞過來的key值相等,則返回entry對應的value值, 最後都沒有找到則返回null
建立線程有4種方式: 實現runnable接口, 繼承thread類, 使用線程池Executor,實現callable經過建立FutureTask類對象,這個能夠自定義返回類型。 Run方法是普通的方法,有方法體,若是使用run方法,程序須要一步一步走完,才能執行下一個方法,就達不到多線程的目的,使用start方法,將線程放在等待開始調用隊列中,等待cpu去調度,jvm去運行。
Less, cat, ll , la, grep , tail , curl, vi, top, telnet , rm –rf , scop , mkdir , mv , pwd ,
印象深入:有一天凌晨4點,是我作的一個xx項目關聯繫統上線,須要作止付和解止付接口驗證操做,須要生產上經過調用個人接口驗證他們的功能上線是否成功, 把我留在公司一整宿,驗證完沒有問題,系統驗證搞得我很緊張,還擔憂本身的功能出問題,結果一晚上很精神,就直接在公司打代碼到早上上班,這是我第一次通宵在公司打代碼到次日早上上班。 比較自豪:18年初,後端架構升級到微服務開發部署,前端架構改造使用新的框架vue, 後端是我本身看着api文檔一步步搭建起來的,各個組件拆分部署也是本身弄的, 另外新架構那時候剛開始引入git, vue, 10幾個java開發,還都是我最早用起來,而且抽空給他們開會作過幾回技術培訓。並且如今我在項目中無論是開發問題查找,業務需求仍是環境,部署問題
1.不要直接將項目總體作優化,要有確切的定位哪些確實須要優化,哪些不須要優化; 2.檢查須要優化的代碼部分,使用分析器來定位性能瓶頸在哪些地方; 3.常常定義一些日誌在關鍵的地方,用來定位分析性能卡頓的代碼,而且分析性能瓶頸; 4.儘可能使用基本類型來代替使用包裝類型; 5.避免使用bigInteger, bigDecimal 由於佔用內存過高; 6.使用日誌前,判斷當前日誌級別是否能被顯示; 7.儘量使用緩存來來避免執行耗時或頻繁使用的代碼片斷; 8.慎用線程同步的方法; 9.儘可能使用局部變量,由於局部變量保存在棧中,方法結束就會被gc清理,速度也快, 而類變量保存在堆中,耗費內存,訪問也慢; 10.建立集合儘可能指定一個初始大小; 11.儘可能在適合的場合使用單例,例如數據共享,資源併發訪問等;
tps比較低的話, 找幾個地方進行分析:1. 網絡帶寬限制;2.鏈接池大小資源限制(例如tomcat與數據庫鏈接池大小限制,超過則等待);3. 數據庫sql性能影響;4.硬件資源限制(內存,cpu等);5. 業務邏輯較爲複雜;6. 緩存策略或配置等;7. Java編碼方式問題; 使用過jmeter開多併發來測試過;
瞭解; 架構搭建部署有幾個點須要注意: 總體敏捷度,組件拆分合理性;部署方面,模塊之間耦合度; 單元測試是否方便;性能方面;開發便捷性和代碼重用性;
開閉原則:開閉原則就是說對擴展開放,對修改關閉。在程序須要進行拓展的時候,不能去修改原有的代碼。 針對接口編程,真對接口編程,依賴於抽象而不依賴於具體。 儘可能使用合成/聚合的方式,而不是使用繼承。 一個實體應當儘可能少的與其餘實體之間發生相互做用,使得系統功能模塊相對獨立。 使用多個隔離的接口,比使用單個接口要好。 里氏代換原則:(1)子類的能力必須大於等於父類,即父類可使用的方法,子類均可以使用。(2)返回值也是一樣的道理。假設一個父類方法返回一個List,子類返回一個ArrayList,這固然能夠。若是父類方法返回一個ArrayList,子類返回一個List,就說不通了。這裏子類返回值的能力是比父類小的。(3)還有拋出異常的狀況。任何子類方法能夠聲明拋出父類方法聲明異常的子類。 而不能聲明拋出父類沒有聲明的異常
1.使用synchronized修飾方法實現同步機制; 2.使用volatile修飾變量實現線程同步; 3.使用阻塞隊列實現線程同步;
jdk經過發射的方式來調用 cglib 經過繼承類的方式來調用,爲代理類和被代理類各生成一個class,而且分配一個index方法,經過index方法直接定位要執行的方法進行調用,不用反射調用,因此效率比較高一點。
1. 生產上的話, 經過觀察日誌, 2. 使用性能分析工具, 與eclipse集成的幾款工具,profile, jConsole, 使用cat監控工具
1. 使用jmeter工具,模擬高併發請求,觀察tps 2. 或者本身使用多線程模擬高併發來觀察接口壓力狀況
spring提供了一整套流程處理,包括業務層,數據層,事務支持等,而且提供了兩大核心功能aop(面向切面,能夠用來解決一些公共問題)和ioc(bean的建立和注入簡化並便於維護), Springmvc主要做爲控制層來實現,從請求到controller,業務處理完成後,返回視圖和數據給客戶端。 2)springmvc的流程: 一、 用戶發送請求至前端控制器DispatcherServlet; 二、DispatcherServlet收到請求調用HandlerMapping處理器映射器; 三、處理器映射器根據請求url找到具體的處理器,生成處理器對象及處理器攔截器(若是有則生成)一併返回給DispatcherServlet; 四、DispatcherServlet經過HandlerAdapter處理器適配器調用處理器,執行處理器(Controller,也叫後端控制器); 五、Controller執行完成返回ModelAndView,並返回給HandlerAdapter,HandlerAdapter將結果返回給DispatcherServlet; 六、DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器,ViewReslover解析後返回具體View給DispatcherServlet; 七、DispatcherServlet對View進行渲染視圖(即將模型數據填充至視圖中)後返回給給客戶
服務端通訊有幾種方式: socket方式通訊,短鏈接(通訊完立馬斷掉),長鏈接(同步和異步方式) mq方式同步或者通訊 Webervice方式 Redis發佈訂閱
Name Server 爲 producer 和 consumer 提供路由信息; Broker 接收來自生產者的消息,儲存以及爲消費者拉取消息的請求作好準備; 生產者(Producer); 消費者(Consumer); 2). 首先從生產者方面考慮,每條消息發送成功與否都會有一個狀態對應,若是失敗狀態,則重發一遍便可。而且還能夠日誌來查詢是否發送併成功存儲進boker塊當中; 3)從broker塊分析,消息支持持久化到日誌裏面,即便宕機重啓,未讀消息仍是能夠加載出來,並且broker支持主從同步,使得消息也不會丟失; 4)從消費者角度考慮,消費者自身維護一個持久化的offset,標記已經成功消費或者消費失敗時,發給broker的消息下標,若是消費失敗,而且borker掛掉了,那麼消費者會定時重試發送動做,若是消費者和broker一塊兒掛了, 那麼重啓後,會繼續從拉去offset以前的消息到本地。 a) mq有發送日誌記錄,每條發送消息都有對應的消息id, 他發送給消費者時會自動判斷並去重, 還有就是能夠本身在業務端處理重複問題。
持久化,就是把數據寫到內存中; Redis支持數據類型: list , hash , set , zset , String ; Redis有一種通信協議RESP,能夠實現客戶端於服務端通訊, 類型websocket ; Redis有幾種架構部署模式: 單機模式: 搭建簡單,內存容量有限,沒法擴容 集羣模式:節點之間經過數據共享, 哨兵模式:經過間隔時間監聽master節點,出現master節點不可用時,會經過投票選舉新的master, 節點直接數據也是經過master同步到各個節點,master寫壓力比較大 主從複製:有一個master主節點,多個slave從節點,數據更新的話, master都會同步到slave從節點,用來保證數據一致,沒法保證高可用,master寫壓力比較大
一個是線程安全,一個不是線程安全的, 由於concurrentmap使用了分段鎖,將map數據分紅一段一段存儲,而後給每一段數據加上一把鎖,就實現了高併發。
樂觀鎖假設認爲數據通常狀況下不會形成衝突,因此在數據進行提交更新的時候,纔會正式對數據的衝突與否進行檢查,(經過對比版本號,查詢的時候會帶一個數據庫版本號,更新的時候用來作對比) 悲觀鎖, 每次它去拿數據的時候都會上鎖,知道鎖釋放,別人才能操做,不適用於高併發
final修飾類是不能被繼承; final修飾對象不能在被建立; fianl修飾方法不能在子類中被覆蓋; final修飾變量,稱爲常量,初始化之後不能改變值。
equals 一般用來比較兩個對象的內容是否相等, ‘==’ 一般用來比較兩個對象的地址是否相等 equals默認等同於‘==’ 若是判斷一個類或對象是否相等, 若是沒有重寫equals方法,則判斷方式就按照‘==’判斷
Javabean注入有兩種方式: 構造函數注入,set/get方式注入 Spring注入bean有以下幾種方式: Xml注入;使用註解@Autowired; 使用java方式注入;經過構建applicationContext對象方式注入
Spring的ioc容器會進行檢查,若是是經過xml中經過set屬性注入, 對於不是propertype屬性注入的bean,spring能夠提早緩存建立的bean,若是存在就直接使用。
其實也沒有什麼技術難點,基本遇到的問題都能及時解決,例如sql中<,> 號,sql結尾加了;,沒有寫#號等等, 都能根據報錯提示很快定位並進行修正。
Mybatis-generators 自動生成dao,xml,bean的反向生成插件 Mybatis-plugins 自動關聯dao,xml文件,並能夠檢測屬性值是否錯誤 Mybatis-pagehelper 分頁插件, 是經過spring的aop實現的,能夠在執行sql的時候,把相關數據在執行一遍, 將當前表做爲臨時表,預編譯sql以後執行
Aop方式能夠在xml配置中體現出來,經過配置加強來實現事務的配置; 可是還有一種比較方便的配置方式,在xml中配置一行代碼tx:annotation-driven , 而後在要實現事務的方法上添加@transaction註解, 事務回滾的狀況,超時,拋異常都會致使事務回滾
首先存儲的時候,根據key值經過散列算法得出對應的下標,算法會盡量隨機均勻的將數據分佈在每一個數組下,而擴容時根據對應的算法進行實現。 https://www.cnblogs.com/williamjie/p/9358291.html
sleep方法: 屬於Thread類中的方法;會致使程序暫停執行指定的時間,讓出cpu該其餘線程,可是他的監控狀態依然保持着,當指定時間到了以後,又會自動恢復運行狀態;在調用sleep方法的過程當中,線程不會釋放對象鎖。(只會讓出CPU,不會致使鎖行爲的改變) wait方法: 屬於Object類中的方法;在調用wait方法的時候,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify方法後本線程才進入對象鎖定池準備。獲取對象鎖進入運行狀態。(不只讓出CPU,還釋放已經佔有的同步資源鎖)
添加同步鎖,wait則是釋放當前同步鎖,並讓出cpu資源 https://my.oschina.net/HerrySun/blog/714156
Synchronized
1.使用volitail, 2.使用wait , nofity, 3.使用synchronized, 4.使用ThreadLocal線程變量 1.首先synchronized是java內置關鍵字,在jvm層面,Lock是個java類; 2.synchronized沒法判斷是否獲取鎖的狀態,Lock能夠判斷是否獲取到鎖; 3.synchronized會自動釋放鎖(a 線程執行完同步代碼會釋放鎖 ;b 線程執行過程當中發生異常會釋放鎖),Lock需在finally中手工釋放鎖(unlock()方法釋放鎖),不然容易形成線程死鎖; 4.用synchronized關鍵字的兩個線程1和線程2,若是當前線程1得到鎖,線程2線程等待。若是線程1阻塞,線程2則會一直等待下去,而Lock鎖就不必定會等待下去,若是嘗試獲取不到鎖,線程能夠不用一直等待就結束了; 5.synchronized的鎖可重入、不可中斷、非公平,而Lock鎖可重入、可判斷、可公平(二者皆可) 6.Lock鎖適合大量同步的代碼的同步問題,synchronized鎖適合代碼少許的同步問題。
Jvm將.java文件編譯成..class文件,而後經過classloader類加載器將類信息加載到虛擬機內存中,在使用的時候在去建立這個對象。
高併發: 高併發是一種狀態,若是大量請求訪問網關接口。這種狀況會發生大量執行操做,如數據庫操做、資源請求、硬件佔用等。這就須要對接口進行優化,而多線程是處理高併發的一種手段 多線程:是一種異步處理的一種方式,在同一時刻最大限度的利用計算機資源
核心線程數,最大線程數,線程存活時間,線程隊列 好比去火車站買票, 有10個售票窗口, 但只有5個窗口對外開放. 那麼對外開放的5個窗口稱爲核心線程數, 而最大線程數是10個窗口.若是5個窗口都被佔用, 那麼後來的人就必須在後面排隊, 但後來售票廳人愈來愈多, 已經人滿爲患, 就相似於線程隊列已滿.這時候火車站站長下令, 把剩下的5個窗口也打開, 也就是目前已經有10個窗口同時運行. 後來又來了一批人,10個窗口也處理不過來了, 並且售票廳人已經滿了, 這時候站長就下令封鎖入口,不容許其餘人再進來, 這就是線程異常處理策略.而線程存活時間指的是, 容許售票員休息的最長時間, 以此限制售票員偷懶的行爲.
將私有線程和該線程存放的副本對象作一個映射,各個線程變量之間互不影響,不共享數據,線程安全,通常存儲爲靜態類型,能夠在其餘地方進行調用
非檢查異常:Error 和 RuntimeException 以及他們的子類;這樣的異常多半是代碼寫的有問題, 數組越界,強制類型轉換等。 檢查異常:除了Error 和 RuntimeException 以及他們的子類以外的異常;程序自己運行環境中出現的異常,須要使用try .. catch撲捉。 - 內存溢出博文:http://outofmemory.cn/c/java-outOfMemoryError - 致使OutOfMemoryError異常的常見緣由有如下幾種: 內存中加載的數據量過於龐大,如一次從數據庫取出過多數據; 集合類中有對對象的引用,使用完後未清空,使得JVM不能回收; 代碼中存在死循環或循環產生過多重複的對象實體; 使用的第三方軟件中的BUG; 啓動參數內存值設定的太小 - 錯誤常見的錯誤提示: tomcat:java.lang.OutOfMemoryError: PermGen space tomcat:java.lang.OutOfMemoryError: Java heap space weblogic:Root cause of ServletException java.lang.OutOfMemoryError resin:java.lang.OutOfMemoryError java:java.lang.OutOfMemoryError - 須要重點排查如下幾點: 檢查代碼中是否有死循環或遞歸調用。 檢查是否有大循環重複產生新對象實體。 檢查對數據庫查詢中,是否有一次得到所有數據的查詢。通常來講,若是一次取十萬條記錄到內存,就可能引發內存溢出。這個問題比較隱蔽,在上線前,數據庫中數據較少,不容易出問題,上線後,數據庫中數據多了,一次查詢就有可能引發內存溢出。所以對於數據庫查詢儘可能採用分頁的方式查詢。 檢查List、MAP等集合對象是否有使用完後,未清除的問題。List、MAP等集合對象會始終存有對對象的引用,使得這些對象不能被GC回收。
(1)導入dubbo、zookeeper依賴 (2)在服務提供者端,編寫服務接口,服務接口的實現類,編寫配置文件 (3)修改web.xml讀取配置文件 (4)在服務消費者,即客戶端,調用服務接口,調用服務實現類,編寫配置文件 這樣系統間就能夠互相通訊,從而感受像在本地使用同樣。
· 服務容器負責啓動,加載,運行服務提供者。 · 服務提供者在啓動時,向註冊中心註冊本身提供的服務。 · 服務消費者在啓動時,向註冊中心訂閱本身所需的服務。 · 註冊中心返回服務提供者地址列表給消費者,若是有變動,註冊中心將基於長鏈接推送變動數據給消費者。 · 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,若是調用失敗,再選另外一臺調用。 · 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
枚舉(Enumeration) 位集合(BitSet) 向量(Vector) 棧(Stack) 字典(Dictionary) 哈希表(Hashtable) 屬性(Properties) 數組array 鏈表linkedList Collection Map
簡單的說,就是一次大的操做由不一樣的小操做組成,這些小的操做分佈在不一樣的服務器上,且屬於不一樣的應用,分佈式事務須要保證這些小操做要麼所有成功,要麼所有失敗。本質上來講,分佈式事務就是爲了保證不一樣數據庫的數據一致性。
是由於一個是數組,一個是鏈表存儲,數組下表具備連續性,能夠經過偏移量查詢,鏈表存儲內存是不連續的,須要經過所有便利查詢
一、經過類名.class方式得到,Class<?> cType = ClassName.class; 二、經過Class.forName()方法得到,Class<?> cType = Class.forName("類全名"); 三、經過對象名.getClass()方法獲取,Class<?> cType3 = objName.getClass(); 總結:三種方式均可以得到Class對象,區別是方法一不執行靜態塊和動態構造塊,方法二執行靜態塊、不執行動態構造塊,方法三須要建立對象,靜態塊和動態構造塊均會執行; 注意:靜態塊僅在類加載時執行一次,若類已加載便再也不重複執行;而動態構造塊在每次new對象時均會執行
1.HashTable Map<String, String> hashtable = new Hashtable<>(); HashTable使用synchronized來保證線程安全的,全部線程競爭同一把鎖,效率低 2.ConcurrentHashMap Map<String, String> concurrentHashMap = new ConcurrentHashMap<>(); 使用鎖分段技術:它包含一個segment數組,將數據分段存儲,給每一段數據配一把鎖,效率高 Java8中使用CAS算法 3.Synchronized Map Map<String, String> synchronizedHashMap = Collections.synchronizedMap(new HashMap<String, String>()); 調用synchronizedMap()方法後會返回一個SynchronizedMap類的對象,而在SynchronizedMap類中使用了synchronized同步關鍵字來保證對Map的操做是安全的。
在mybatis框架中,寫dao層的mapper接口時,是不能夠進行方法的重載的, 重載時,會出現異常: mybatis中mapper.xml是不會準確映射到Java中的重載方法的。最好不要在mapper接口中使用方法重載。 Dao層,編譯不會報錯,運行會報錯