前言
一名Java后端在重慶面試親身經歷,每一場面試腦海中印象比較深刻的問題記錄下來,并且總結,找出答案,分享出來,
現在面試問的問題都相對來說比較深入
話不多說上題目:
JWT使用
客戶端接收服務器回傳的JWT,將其存盤在Cookie或localStorage中,
此后,客戶端將在與服務器互動中都會帶JWT,如果將它存盤在Cookie中,就可以自動發送,但是不會跨域,因此一般是將它放入HTTP請求的Header Authorization欄位中,
Authorization: Bearer
當跨域時,也可以將JWT被放置于POST請求的資料主體中,
參考博文:https://www.jianshu.com/p/cb886f995e86
token是如何生成
微服務鏈路檢測
鏈路追蹤
SkyWalking or Zipkin
ZipKin:服務呼叫的請求和回應中加入ID,標明上下游請求的關系,利用這些資訊,可以可視化地分析服務呼叫鏈路和服務間的依賴關系
Spring Cloud Sleuth是對Zipkin的一個封裝,對于Span、Trace等資訊的生成、接入HTTP Request,以及向Zipkin Server發送采集資訊等全部自動完成,
參考博文:
https://www.cnblogs.com/duanxz/p/7552857.html
https://www.cnblogs.com/duanxz/p/7552857.html
泛型的實作
泛型的實作是靠型別擦除技術, 型別擦除是在編譯期完成的, 也就是在編譯期, 編譯器會將泛型的型別引數都擦除成它的限定型別,如果沒有則擦除為object型別之后在獲取的時候再強制型別轉換為對應的型別, 在運行期間并沒有泛型的任何資訊,因此也沒有優化,
cglib的實作
動態代理
有哪些開發規范
REST full
你對雪崩效應的看法
看過哪些源代碼
熔斷器的使用
在啟動類中,需要添加 @EnableCircuitBreaker 注解
定義 Hystrix 處理類
OrderClientServiceFallbackFactory implements FallbackFactory<OrderClientService>
重寫 create方法
里面再重寫熔斷的默認回傳
配合feign在介面上面加上工廠類
@FeignClient(value = "MICROSERVICE-ORDER", fallbackFactory = OrderClientServiceFallbackFactory.class)
開啟熔斷
feign:
hystrix:
enabled: true
參考博文: https://blog.csdn.net/eson_15/article/details/86628622
高并發場景
服務器方面
nginx 使用負載均衡
使用服務器集群
業務實作方面
使用佇列Kafka、RabitMQ等
處理秒殺 搶購等高并發場景保證資料安全
使用快取Redis、Memcache等
盡量使用快取,包括用戶快取,資訊快取等,可以大量減少與資料庫的互動,提高性能,
使用多執行緒
部分功能使用多執行緒后臺執行 不阻塞主執行緒
資料庫方面
優化資料庫查詢陳述句
優化資料庫結構,多做索引,提高查詢效率
統計相關功能最好定時統計,避免實時查詢
代碼方面
代碼構造的時候盡量避免不必要的資源浪費,提高性能
如:不要頻繁使用new物件 使用單例模式等
string的連接操作,使用stringbuffer(速度慢,執行緒安全)或者stringbuilder(速度快,執行緒不安全)
utility型別的類通過靜態方法來訪問
mybatis一級快取,二級快取
- 一級快取:mybatis每次在查詢后,會將陳述句和引數相同的查詢SQL的結果集存放進快取,待下一次有相同的陳述句和引數時,mybatis直接將快取內的結果集回傳,而不再查詢資料庫,
- 二級快取:需要手動開啟,一級快取在同一個SqlSession內,以SqlSession為快取單位;二級快取在不同的SqlSession間,以mapper為單位,不同的SqlSession間可以共享相同的mapper下介面查詢的資料
docker (k8s)
docker-compose
參考博文:https://www.jianshu.com/p/7893af4976d9
JVM調優
XX:MetaspaceSize=128m (元空間默認大小)
XX:MaxMetaspaceSize=128m (元空間最大大小)
Xms1024m (堆最大大小)
Xmx1024m (堆默認大小)
Xmn256m (新生代大小)
Xss256k (棧最大深度大小)
XX:SurvivorRatio=8 (新生代磁區比例 8:2)
XX:+UseConcMarkSweepGC (指定使用的垃圾收集器,這里使用CMS收集器)
XX:+PrintGCDetails (列印詳細的GC日志)
參考博文:https://blog.csdn.net/sun1021873926/article/details/78002118
springcloud用過什么組件
- spring cloud eureka : 注冊中心,可以看到各個服務運行狀態,并且各個微服務呼叫都通過注冊中心來找到內網ip進行呼叫
- spring cloud gateway:
對外的網關,分為zuul版本和F版本,兩者最大區別是底層容器不同,zuul版本是servlet,F版本的是webFlux框架,并且F版本可設定統一過濾器,單個微服務過濾器,限流過濾器,相同的是都有負載均衡,熔斷機制,重試規則 - spring cloud config: 配置中心,可以分為本地掃描配置和從git倉庫拉取快取,在spring cloud
bus的配合下,可實作實時動態重繪組態檔 - spring cloud bus: 訊息總線z,實作各個微服務之間的通信,整合java訊息的發送和接收
- spring cloud Ribbon: 負載均衡
- spring cloud Feign: PRC 遠程服務呼叫
- spring cloud Hystrix: 熔斷機制
- spring cloud zipkin: 鏈路追蹤,分為http追蹤和rabbitmq追蹤,提供前端頁面顯示各個介面之間的復雜的互相呼叫
- spring boot admin:
顯示各個服務運行的詳細狀態,執行緒池,記憶體環境,系統環境屬性,spring各種bean運行狀態,可以把阿里資料庫連接池druid的監控結合到了監控頁面,可以監控到各個sql執行時間等等 - spring cloud oauth2: 鑒權服務, 四種模式: 用戶名密碼模式, 客戶端模式, 授權碼模式,簡化模式過于復雜.
說明一下,目前微服務一般是使用Spring Cloud Alibaba
阿里開源組件 - Nacos:一個更易于構建云原生應用的動態服務發現、配置管理和服務管理平臺,
- Sentinel:把流量作為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性,
- RocketMQ:開源的分布式訊息系統,基于高可用分布式集群技術,提供低延時的、高可靠的訊息發布與訂閱服務,
- Dubbo:這個就不用多說了,在國內應用非常廣泛的一款高性能 Java RPC 框架,
- Seata:阿里巴巴開源產品,一個易于使用的高性能微服務分布式事務解決方案,
- Arthas:開源的Java動態追蹤工具,基于位元組碼增強技術,功能非常強大,
CAP理論(C——資料一致性,A——服務可用性,P——服務對網路磁區故障的容錯性),
Euraka 和 dubbo ,zookeeper
- Euraka: 是分布式系統中的AP
- dubbo的注冊中心一般選用zookeeper: zookeeper保證的是cp
- 在P在網路磁區發生故障的時候,zookeeper 要進行選舉,euraka: 可以快速切換到另外一個節點
java反射原理
jvm在運行程序中載入class檔案,得到class物件后反向獲取物件的各種資訊
zookeeper 呼叫流程處理方法,呼叫方式
微服務呼叫元素
Java淺拷貝和深拷貝的理解和實作方式
淺拷貝(淺復制、淺克隆):
被復制物件的所有變數都含有與原來的物件相同的值,而所有的對其他物件的參考仍然指向原來的物件,
換言之,淺拷貝僅僅復制所拷貝的物件,而不復制它所參考的物件,
深拷貝(深復制、深克隆):
被復制物件的所有變數都含有與原來的物件相同的值,除去那些參考其他物件的變數,那些參考其他物件的變數將指向被復制過的新物件,而不再是原有的那些被參考的物件,
換言之,深拷貝把要復制的物件所參考的物件都復制了一遍
java悲觀鎖和樂觀鎖區別
定義:
悲觀鎖(Pessimistic Lock):
每次獲取資料的時候,都會擔心資料被修改,所以每次獲取資料的時候都會進行加鎖,確保在自己使用的程序中資料不會被別人修改,使用完成后進行資料解鎖,由于資料進行加鎖,期間對該資料進行讀寫的其他執行緒都會進行等待,
樂觀鎖(Optimistic Lock):
每次獲取資料的時候,都不會擔心資料被修改,所以每次獲取資料的時候都不會進行加鎖,但是在更新資料的時候需要判斷該資料是否被別人修改過,如果資料被其他執行緒修改,則不進行資料更新,如果資料沒有被其他執行緒修改,則進行資料更新,由于資料沒有進行加鎖,期間該資料可以被其他執行緒進行讀寫操作,
適用場景:
悲觀鎖:比較適合寫入操作比較頻繁的場景,如果出現大量的讀取操作,每次讀取的時候都會進行加鎖,這樣會增加大量的鎖的開銷,降低了系統的吞吐量,
樂觀鎖:比較適合讀取操作比較頻繁的場景,如果出現大量的寫入操作,資料發生沖突的可能性就會增大,為了保證資料的一致性,應用層需要不斷的重新獲取資料,這樣會增加大量的查詢操作,降低了系統的吞吐量,
總結:兩種所各有優缺點,讀取頻繁使用樂觀鎖,寫入頻繁使用悲觀鎖,
后端實作跨域
- spring就用filter里面往header里面放跨域引數
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
- Springboot 很簡單 @CrossOrigin
- 或者用nginx實作做代理
Spring Boot、Spring MVC、Spring之間的區別?(Spring Boot本質是什么?)
Spring Boot Starter 是什么?
如何自定義Spring Boot Starter?(如何擴展Spring Boot)
Spring Boot 的自動裝配原理是什么?(原始碼分析哦)
在全域配置的屬性如:server.port等,
通過@ConfigurationProperties注解,
系結到對應的XxxxProperties配置物體類上封裝為一個bean,
然后再通過@EnableConfigurationProperties注解匯入到Spring容器中,
Spring Boot啟動的時候會通過@EnableAutoConfiguration注解找到
META-INF/spring.factories組態檔中的所有自動配置類,
并對其進行加載,而這些自動配置類 都是以AutoConfiguration結尾來命名的,
它實際上就是一個JavaConfig形式的Spring容器配置類,
它能通過以Properties結尾命名的類中取得在全域組態檔中配置的屬性如:
server.port,
參考博文:https://blog.csdn.net/Dongguabai/article/details/80865599
Spring Boot 的啟動流程是什么?
有沒有看過 Spring Boot 原始碼?你覺得最神奇的地方是什么?
對服務注冊中心的理解
我的理解很簡單就是服務注冊進來就把他記錄下來,客戶端需要用的時候就直接來查詢
對網關的理解
TCP/IP 顧名思義就是一個網路到一個網路的關口
jvm 原理
- JVM是java的核心和基礎,在java編譯器和os平臺之間的虛擬處理器,它是一種利用軟體方法實作的抽象的計算機基于下層的作業系統和硬體平臺,可以在上面執行java的位元組碼程式,
- java編譯器只要面向JVM,生成JVM能理解的代碼或位元組碼檔案,Java源檔案經編譯成位元組碼程式,通過JVM將每一條指令翻譯成不同平臺機器碼,通過特定平臺運行,
你是怎么設計微服務
1·單一職責(Single Responsibility),一個服務應當承擔盡可能單一的職責,服務應基于有界的背景關系(bounded context,通常是邊界清晰的業務領域)構建,服務理想應當只有一個變更的理由(類似Robert C. Martin講的:A class should have only one reason to change),當一個服務承擔過多職責,就會產生各種耦合性問題,需要進一步拆分使其盡可能職責單一化,
2·關注分離(Separation of Concerns),跨橫切面邏輯,例如日志分析、監控、限流、安全等等,盡可能與具體的業務邏輯相互分離,讓開發人員能專注于業務邏輯的開發,減輕他們的思考負擔,這個也是有界背景關系(bounded context)的一個體現,
3·模塊化(Modularity)和分而治之(Divide & Conquer),這個是解決復雜性問題的一般性方法,將大問題(如單塊架構)大而化小(模塊化和微服務化),然后分而治之,
前期階段,大致要做好如下事情:
和多方充分溝通,確保能符合客戶和組織的需求,并且得到認同
和團隊溝通,讓隊友(開發/測驗/運維)理解,并且積極投入
和業務部門溝通,指定版本計劃和上線時間
設計階段,參考 Sam Newman 的著作《微服務設計》,單微服務必須要滿足以下的條件,才符合微服務的基本要求:
標準的 REST 風格介面(基于 HTTP 和 JSON 格式)
獨立部署,避免共享資料庫(避免因為資料庫而影響整個分布式系統)
業務上的高內聚,減少依賴(從設計上要避免服務過大或者太小)
技術階段,龐大的分布式系統,需要強大基礎設施來支撐,微服務涉及哪些基礎設施?
CI/CD和自動化(分布式系統幾乎不可能通過人工手動發布)
虛擬化技術(要保證微服務運行環境隔離,目前行業主流的是使用 Docker 容器)
日志聚合,全鏈路監控(高度可觀察和分析診斷問題)
參考博文:https://www.cnblogs.com/xiao2shiqi/p/11298663.html
redis用過鎖嗎
redis快取穿透
key對應的資料在資料源并不存在,每次針對此key的請求從快取獲取不到,請求都會到資料源,從而可能壓垮資料源,比如用一個不存在的用戶id獲取用戶資訊,不論快取還是資料庫都沒有,若黑客利用此漏洞進行攻擊可能壓垮資料庫,
參考博文: https://www.cnblogs.com/xichji/p/11286443.html
redis雪崩
很多key在同一時間同時過期,解決方案就是把key分組,分別設定過期時間,避免同時過期的情況
redis記憶體優化
redis淘汰策略
(1)volatile-lru:從已設定過期時間的資料集中挑選最近最少使用的資料淘汰,
(2)volatile-ttl:從已設定過期時間的資料集中挑選將要過期的資料淘汰,
(3)volatile-random:從已設定過期時間的資料集中任意選擇資料淘汰,
(4)volatile-lfu:從已設定過期時間的資料集挑選使用頻率最低的資料淘汰,
(5)allkeys-lru:從資料集中挑選最近最少使用的資料淘汰
(6)allkeys-lfu:從資料集中挑選使用頻率最低的資料淘汰,
(7)allkeys-random:從資料集(server.db[i].dict)中任意選擇資料淘汰
(8) no-enviction(驅逐):禁止驅逐資料,這也是默認策略,意思是當記憶體不足以容納新入資料時,新寫入操作就會報錯,請求可以繼續進行,線上任務也不能持續進行,采用no-enviction策略可以保證資料不被丟失,
這八種大體上可以分為4中,lru、lfu、random、ttl,
Redis最為常用的資料型別主要有以下
String
Hash
List
Set
Sorted set 有序集合
redis 的應用場景
快取,秒殺(expire過期時間),計數器(incrby命令可以實作原子性的遞增),排行榜(SortedSet 排序),分布式鎖(setnx命令進行,有過期時間,可防止死鎖),延時操作,分頁、模糊搜索(set集合中提供了一個zrangebylex方法),點贊、好友等相互關系的存盤(set),佇列
訊息佇列(rabbitMQ)
參考博文: https://www.jianshu.com/p/40dbc78711c8
spring bean 不是執行緒安全的
普通的java類, 帶有屬性, 并且屬性是可以被修改的, 那么這個類的實體就是有狀態物件. 也就是如果你拿到的這個實體, 可能就被別人修改過, 那么你當前的操作就會受到別人之前操作的影響.
冪等性問題
微服務的架構設計
mybatis原理
通過 Resource加載 mapper.xml,生成一個 inputstream的輸入流,創建 sqlsessionfactorybuilder物件,通過該物件的 builder( inputstream)方法,回傳一個 sqlsessionfactory物件,由 sqlsessionfactory物件生成 sqlsession,通過 statement id找到對應的 statement,通過傳入的引數進行一系列的復雜判斷生成要執行的 sql,通過 jdbc執行 sql,然后把結果封裝成 map、 list等回傳
mybatis $ # 的區別
# 可以防止SQL注入 他會做字串處理 他是預編譯的,會用 ? 作為占位符
$ 的話就是你傳什么他就是什么,他不會做字串處理
TCP協議詳解
1.第一次握手:建立連接,客戶端發送連接請求報文段,將SYN位置為1,Sequence Number為x;然后,客戶端進入SYN_SEND狀態,等待服務器的確認;
2.第二次握手:服務器收到SYN報文段,服務器收到客戶端的SYN報文段,需要對這個SYN報文段進行確認,設定Acknowledgment Number為x+1(Sequence Number+1);同時,自己自己還要發送SYN請求資訊,將SYN位置為1,Sequence Number為y;服務器端將上述所有資訊放到一個報文段(即SYN+ACK報文段)中,一并發送給客戶端,此時服務器進入SYN_RECV狀態;
3.第三次握手:客戶端收到服務器的SYN+ACK報文段,然后將Acknowledgment Number設定為y+1,向服務器發送ACK報文段,這個報文段發送完畢以后,客戶端和服務器端都進入ESTABLISHED狀態,完成TCP三次握手,
完成了三次握手,客戶端和服務器端就可以開始傳送資料,以上就是TCP三次握手的總體介紹,
參考博文:
https://blog.csdn.net/weixin_40462235/article/details/79840355?utm_medium=distribute.pc_relevant.none-task-blog-baidulandingword-1&spm=1001.2101.3001.4242
java sync 鎖的是什么
物件
hashmap的原理
(一個是鏈表的長度達到8個,一個是陣列的長度達到64個)
陣列加連表的結構 運用了紅黑樹原理
紅黑樹是什么
自平衡的二叉查找樹,他這個自平衡的特性就是對HashMap中鏈表可能會很長做出的優化,
性質1. 節點是紅色或黑色,
性質2. 根節點是黑色,
性質3 每個葉節點(NIL節點,空節點)是黑色的,
性質4 每個紅色節點的兩個子節點都是黑色,(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)
性質5. 從任一節點到其每個葉子的所有路徑都包含相同數目的黑色節點,
springboot的初始化原理
參考博文:https://blog.csdn.net/u014745069/article/details/83820511
jvm的磁區(五大磁區)
程式計數器,虛擬機堆疊,本地方法堆疊,堆,方法區
參考博文:https://blog.csdn.net/qq_32755757/article/details/85259133
GC垃圾回識訓制
把所有物件組成一個集合,或可以理解為樹狀結構,從樹根開始找,只要可以找到的都是活動物件,如果找不到,這個物件就被回收了
作業原理
GC的作業流程主要分為如下幾個步驟:
1、標記(Mark)---GC的根節點也即GC Root
2、計劃(Plan)
3、清理(Sweep)
4、參考更新(Relocate)
5、壓縮(Compact)
怎么執行GC垃圾回收
代碼主動顯式呼叫System.GC.Collect()
springboot是怎么實作springmvc的東西的
mysql怎么運用分庫分表
兩種解決方案:垂直拆分、水平拆分
- 垂直拆分:根據業務進行拆分,比如可以將一張表中的多個欄位拆成兩張表,一張是不經常更改的,一張是經常改的,
- 水平拆分:即根據表來進行分割:比如user表可以拆分為user0,、user1、user2、user3、user4等
參考博文:https://www.cnblogs.com/mengtaoadmin/p/11184047.html
用過哪些設計模式
工廠模式,單例模式(雙檢鎖主要是加鎖操作,先判斷有沒有物件,沒有再創建),觀察者模式,生產者消費者模式,動態代理模式
參考博文:https://www.cnblogs.com/leeego-123/p/10882079.html
對Euraka服務注冊中心的理解
Eureka 原理與步驟
比擬場景:餐廳吃飯
1、先向收銀員(注冊中心)要個號牌(IP地址),
2、飯菜到場就根據你號牌(IP地址)將飯菜端到你面前,
3、在整個就餐程序中,你隨時可以與收銀員進行互相溝通(監聽客戶端心跳),
4、最后你吃完跑路了號牌回收(剔除服務器),
原理: 與比擬場景序號對應理解,
1、服務提供方啟動后將注冊到 注冊中心,提供IP, 名字,什么服務等資訊,
2、服務呼叫方作為客戶端注冊到注冊中心后,拉取注冊中心的服務串列,在通過負載均衡呼叫對應的服務提供方,
3、注冊中心可以建立集群,生成多臺eureka,注冊中心為了監測各個服務的心跳,將在每30S 向所注冊的服務發起請求判斷
4、服務是否掛掉,如果掛掉90S后將會將服務從注冊中心剔除,
一個服務可以監測多臺服務實體,從而可實作均衡負載,
參考博文:https://www.cnblogs.com/lanSeGeDiao/p/10801804.html
運用Euraka遇到的問題
zuul有哪些過濾器
a、pre: 這種過濾器在請求被路由之前呼叫,可利用這種過濾器實作身份驗證、在集群中選擇請求的微服務,記錄除錯資訊等,
b、routing: 這種過濾器將請求路由到微服務,這種過濾器用于構建發送給微服務的請求,并使用apache httpclient或netflix ribbon請求微服務,
c、post: 這種過濾器在路由到微服務以后執行,這種過濾器可用來為回應添加標準的http header、收集統計資訊和指標、將回應從微服務發送給客戶端等,
e、error: 在其他階段發送錯誤時執行該過濾器,
參考博文: https://www.cnblogs.com/linjiqin/p/10202085.html
分頁插件的好處是什么
封裝型別和基本型別的區別
包裝型別可以為 null,而基本型別不可以
包裝型別可用于泛型,而基本型別不可以
基本型別比包裝型別更高效
兩個包裝型別的值可以相同,但卻不相等
自動裝箱和自動拆箱
怎么解決并發的
訊息佇列,多執行緒,負載均衡,代碼的話用一些 并發包,比如說map用ConcurrentHashmap
shrio的使用
Subject: 用戶主體(把操作交給SecurityManager)
SecurityManager:安全管理器(關聯Realm)
Realm:Shiro連接資料的橋梁
1·創建ShiroFilterFactoryBean
設定安全管理器 securityManager
添加Shiro內置過濾器(訪問權限 anon: 無需認證(登錄)可以訪問 uthc: 必須認證才可以訪問 user: 如果使用rememberMe的功能可以直接訪問 perms: 該資源必須得到資源權限才可以訪問
role: 該資源必須得到角色權限才可以訪問)
2·創建DefaultWebSecurityManager
關聯realm
自定義 realm (public class UserRealm extends AuthorizingRealm 寫執行認證邏輯,執行授權邏輯)
springmvc的原始碼
用戶請求DispatcherServlet,
DispatcherServlet呼叫HandlerMapping,
HandlerMapping根據請求路徑找到對應的handler,
DispatcherServlet呼叫HandlerAdapter
HandlerAdapter去呼叫handler,并且在呼叫handler前后做一些適配,最侄訓傳ModelAndView物件,
DispatcherServlet呼叫ViewResovler,拼接出完整的jsp地址,
DispatcherServlet傳遞模型資料給view,并且渲染列印資料給用戶,
DispatcherServlet:
spring mvc的入口,整個框架運行就是在這個servlet中完成,
HandlerMapping:
處理器映射器,用于映射每個處理方法對應的請求路徑,是一個map結構<url,method>,
handler:
處理器,實際上就是控制器中的每個處理方法,
HandlerAdapter:
處理器配接器,專門用來呼叫handler,因為在spring mvc中每個處理方法引數以及回傳型別都不一樣,因此需要用配接器來適配,
ViewResovler:
視圖決議器,用于指定視圖技術,以及視圖技術相關的配置,
View:
視圖,springmvc 中支持多種視圖,除了jsp外 還有xml,json,pdf等,
in id方法有用到索引嗎
會用到索引
list的子類
ArrayList:底層資料結構為陣列,查詢快,增刪慢,執行緒不安全,效率高;
Vector:底層資料結構為陣列,查詢快,增刪慢,執行緒安全,效率慢,一般不用;
LinkedList:底層資料結構為鏈表,查詢慢,增刪快,執行緒不安全,效率高
ArrayList
ArrayList集合繼承了List的所有成員方法,沒有新增,用法和List同
Vector
Vector比繼承體系歷史更久遠,有一些實作同樣獲取、遍歷功能更復雜的方法,老版本用,新版本基本不用,
LinkedList
LinkedList中多了新增,洗掉,獲取First&Last元素的方法
并發包
hashMap 在執行緒中的并發解決辦法
比如ConcurrentHashmap(鎖分段技術)
容器里有多把鎖,每一把鎖用于鎖容器其中一部分資料,那么當多執行緒訪問容器里不同資料段的資料時,執行緒間就不會存在鎖競爭,從而可以有效的提高并發訪問效率,這就是ConcurrentHashMap所使用的鎖分段技術,首先將資料分成一段一段的存盤,然后給每一段資料配一把鎖,當一個執行緒占用鎖訪問其中一個段資料的時候,其他段的資料也能被其他執行緒訪問,
,Hashtable等執行緒安全等集合類,
synchronized來保證執行緒安全
對dubbo的理解
1、容器 (spring容器)
2、服務生產者
3、注冊中心 (zookeeper 、redis (發布訂閱 -頻道))
4、服務消費者
5、監控中心(可以查看哪個方法的使用次數)
容器啟動,服務生產者會把自己的服務的介面地址報告給注冊中心,服務消費者訂閱它需要的服務,他去查詢注冊中心,大哥有地址嗎?有就回傳服務地址,消費者拿到地址就可以去呼叫服務,監控中心:監控生產者和消費者的健康狀況,
Dubbo是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向介面的遠程方法呼叫,智能容錯和負載均衡,以及服務自動注冊和發現,
注冊中心掛了會產生什么影響?
對服務的呼叫沒有任何影響,因為本地快取了服務端的地址,
為什么使用Dubbo?
1、Dubbo提供了豐富的協議選擇:Dubbo協議(服務呼叫),注冊服務:zookeeper協議,tcp協議,http協議等,協議越底層,傳輸效率越高,
2、io的選擇:異步的nio,
什么叫事務?簡稱ACID
A 事務的原子性(Atomicity):指一個事務要么全部執行,要么不執行.也就是說一個事務不可能只執行了一半就停止了.比如你從取款機取錢,這個事務可以分成兩個步驟:1劃卡,2出錢.不可能劃了卡,而錢卻沒出來.這兩步必須同時完成.要么就不完成.
C 事務的一致性(Consistency):指事務的運行并不改變資料庫中資料的一致性.例如,完整性約束了a+b=10,一個事務改變了a,那么b也應該隨之改變.
I 獨立性(Isolation):事務的獨立性也有稱作隔離性,是指兩個以上的事務不會出現交錯執行的狀態.因為這樣可能會導致資料不一致.
D 持久性(Durability):事務的持久性是指事務執行成功以后,該事務所對資料庫所作的更改便是持久的保存在資料庫之中,不會無緣無故的回滾.
執行緒中變數的可見性
Java中實作多執行緒共享變數的可見性方法有synchronize 和 volatile :
synchronize:可以用在方法或者代碼塊上,能保證可見性,也能保證原子性.
volatitle:用在變數上,只保證可見性,不保證原子性,不加鎖,比synchronize輕量級,不會造成執行緒阻塞.volatitle讀相當于加鎖,volatitle寫相當于解鎖.
參考資料型別包括:
類、介面型別、陣列型別、列舉型別、注解型別,字串型,
java排序演算法
冒泡,相鄰元素兩兩比較,大的往后放,第一次完畢,最大值出現在了最大索引處,同理,其他的元素就可以排好,
簡單選擇排序:,把0索引的元素,和索引1以后的元素都進行比較,第一次完畢,最小值出現在了0索引,同理,其他的元素就可以排好,
插入排序:它的作業原理是通過構建有序序列,對于未排序資料,在已排序序列中從后向前掃描,找到相應位置并插入,插入排序在實作上,在從后向前掃描程序中,需要反復把已排序元素逐步向后挪位,為最新元素提供插入空間,
快速排序:快速排序的原理就是每次設定一個基準點,這個基準點可以是要排序的一趴數之間的任何數,然后將比基準點小的數放在基準點左邊,比基準點大的數放在基準點右邊
二分排序:針對陣列有序的情況(千萬不要先排序,在查找)
10G的檔案匯入帶資料庫中怎么實作(怎么快速把10G的檔案決議出來)
一、切割檔案
CutText類中的方法splitFile(String filePath, String cutPath, int fileCount);
二、txt檔案轉換為csv檔案
TxtToCSV類中的方法allFileIO(String filePath, String cutPath, int fileCount)
三、txt檔案匯入mysql
TxtLoadToMySQL類中的方法
toMySQL(String filePath, String cutPath, int fileCount)
參考博文:https://blog.csdn.net/L141210113/article/details/83865611
微信朋友圈的點贊功能怎么實作,好友可以看到,共同好友可以看到
js == === 的區別
== 型別不一樣 轉換在比較
=== 型別不一樣直接false 型別一樣才比較
springboot 的 starter的作業原理 自動裝配
@Configuration&與@Bean------>>>基于java代碼的bean配置
@Conditional-------->>>>>>設定自動配置條件依賴
@EnableConfigurationProperties與@ConfigurationProperties->讀取組態檔轉換為bean,
@EnableAutoConfiguration、@AutoConfigurationPackage 與@Import->實作bean發現與加載,
Servlet的生命周期
加載階段、實體化階段、初始化階段init、服務階段service、銷毀階段destroy
如何取得每個部門薪資前三名的人員名稱?
select e.ename, e.deptno,e.sal
from emp e
left join dept d on e.dept_id = d.id
where
(select count(*) from emp em where em.sal>=e.sal and em.deptno=e.deptno) <= 3
order by e.deptno,e.sal desc;
查詢兩張表中沒有交集的資料
left join where id is null 的資料
swagger 注解引數
@ApiParam(name = "id", value = "用戶id", required = true)
- @Api()用于類;
表示標識這個類是swagger的資源
- @ApiOperation()用于方法;
表示一個http請求的操作
- @ApiParam()用于方法,引數,欄位說明;
表示對引數的添加元資料(說明或是否必填等)
- @ApiModel()用于類
表示對類進行說明,用于引數用物體類接收
- @ApiModelProperty()用于方法,欄位
表示對model屬性的說明或者資料操作更改
- @ApiIgnore()用于類,方法,方法引數
表示這個方法或者類被忽略
- @ApiImplicitParam() 用于方法
表示單獨的請求引數
- @ApiImplicitParams() 用于方法,包含多個 @ApiImplicitParam
參考博文:https://blog.csdn.net/wyb880501/article/details/79576784
synchronized 的方式
個人理解:
synchronized(this)
因為this是當前物件本身,所以鎖定只對你自己new了并呼叫那個物件有用,所以另外一個人如果要new并呼叫,則和這個不是同一個鎖,因為this變了,
synchronized(類的名.class)
每個類在jvm里面只有一個唯一的位元組碼,所以.class是唯一的,無論多少物件,共用此同一把鎖,
介面和抽象的區別
相同點:
(1)都不能被實體化
(2)介面的實作類或抽象類的子類都只有實作了介面或抽象類中的方法后才能實體化,
不同點:
(1)介面只有定義,不能有方法的實作,java 1.8中可以定義default方法體,而抽象類可以有定義與實作,方法可在抽象類中實作,
(2)實作介面的關鍵字為implements,繼承抽象類的關鍵字為extends,一個類可以實作多個介面,但一個類只能繼承一個抽象類,所以,使用介面可以間接地實作多重繼承,
(3)介面強調特定功能的實作,而抽象類強調所屬關系,
(4)介面成員變數默認為public static final,必須賦初值,不能被修改;其所有的成員方法都是public、abstract的,抽象類中成員變數默認default,可在子類中被重新定義,也可被重新賦值;抽象方法被abstract修飾,不能被private、static、synchronized和native等修飾,必須以分號結尾,不帶花括號,
(5)介面被用于常用的功能,便于日后維護和添加洗掉,而抽象類更傾向于充當公共類的角色,不適用于日后重新對立面的代碼修改,功能需要累積時用抽象類,不需要累積時用介面,
怎么把抽象類變為介面
索引聯合
mysql的事務隔離級別
1、未提交讀(Read Uncommitted):允許臟讀,也就是可能讀取到其他會話中未提交事務修改的資料
2、提交讀(Read Committed):只能讀取到已經提交的資料,Oracle等多數資料庫默認都是該級別 (不重復讀)
3、可重復讀(Repeated Read):可重復讀,在同一個事務內的查詢都是事務開始時刻一致的,InnoDB默認級別,在SQL標準中,該隔離級別消除了不可重復讀,但是還存在幻象讀,但是innoDB解決了幻讀
4、串行讀(Serializable):完全串行化的讀,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞
參考博文: https://www.cnblogs.com/rxbook/p/8975924.html
索引的資料結構
參考博文:
https://www.cnblogs.com/xiaoshahai/p/12028737.html
https://blog.csdn.net/u013314679/article/details/105665026/
redis是怎么實作單執行緒的
spring bean 為什么沒有狀態
有狀態會話bean :每個用戶有自己特有的一個實體,在用戶的生存期內,bean保持了用戶的資訊,即“有狀態”;一旦用戶滅亡(呼叫結束或實體結束),bean的生命期也告結束,即每個用戶最初都會得到一個初始的bean,
無狀態會話bean :bean一旦實體化就被加進會話池中,各個用戶都可以共用,即使用戶已經消亡,bean 的生命期也不一定結束,它可能依然存在于會話池中,供其他用戶呼叫,由于沒有特定的用戶,那么也就不能保持某一用戶的狀態,所以叫無狀態bean,但無狀態會話bean 并非沒有狀態,如果它有自己的屬性(變數),那么這些變數就會受到所有呼叫它的用戶的影響,這是在實際應用中必須注意的,
Map<String, Object> map = new HashMap<String, Object>()用到了什么設計模式
工廠模式有幾種寫法
抽象工廠,簡單(靜態)工廠,多方法工廠(常用)
public class MulWayNoodlesFactory {
/**
* 模仿Executors 類
* 生產泡面
*
* @return
*/
public static INoodles createPm() {
return new PaoNoodles();
}
/**
* 模仿Executors 類
* 生產蘭州拉面
*
* @return
*/
public static INoodles createLz() {
return new LzNoodles();
}
/**
* 模仿Executors 類
* 生產干扣面
*
* @return
*/
public static INoodles createGk() {
return new GankouNoodles();
}
}
INoodles lz2 = MulWayNoodlesFactory.createLz();
lz2.desc();
redis什么時候會變卡
單例模式有幾種寫法(五種)
懶漢式(少用),餓漢式(常用),雙檢鎖(包含執行緒安全和執行緒不安全兩種方式),靜態內部類(在要明確實作 lazy loading 效果時),列舉(運用到反序列化創建物件的推薦)
參考檔案: https://blog.csdn.net/absolute_chen/article/details/93380566
紅黑樹是怎么保證自平衡的
任意一結點到每個葉子結點的路徑都包含數量相同的黑
自平衡所需要的操作,無非是變色,左旋,右旋,變色不用多說,黑變紅紅變黑,
我們添加一個節點后,如果其父節點還沒滿三個(左右節點都為紅表示滿 了),并且空位在新增節點這邊,那么變色即可完成修改,
如果新加節點的父節是紅色,說明沒空位了,那么就得拆分,將紅節點變黑,這時會發現又新增了一層,于就通過父節點的左旋或右旋,將父節點上升一層,于是又變回只新增一層,又可以重新按思路走下去,
如果新增節點沒有空位讓其補進去,會如此一直旋轉變色下去,最后到達根節點處,或是左旋或是右旋,根節點會變為原來子節點的子節點,子節點上升為根節點,到此,層數增長,由此也可以知道,層數增長總是發生在根處,
參考博文: https://blog.csdn.net/zjbyough/article/details/105336372
資料結構有哪些
js的選擇器
IOC的實作原理
Autowired 和Resources的區別
@Autowired注解是按型別裝配依賴物件,默認情況下它要求依賴物件必須存在,如果允許null值,可以設定它required屬性為false,@Resource注解和@Autowired一樣,也可以標注在欄位或屬性的setter方法上,但它默認按名稱裝配,名稱可以通過@Resource的name屬性指定,如果沒有指定name屬性,當注解標注在欄位上,即默認取欄位的名稱作為bean名稱尋找依賴物件,當注解標注在屬性的setter方法上,即默認取屬性名作為bean名稱尋找依賴物件, @Resources按名字,是JDK的,@Autowired按型別,是Spring的,
sprngboot檔案上傳用什么引數
依賴注入有幾種方式
介面,構造, setter
負載均衡用了哪些演算法
輪詢,加強輪詢,隨機,加強隨機,最小化原則
get方法引數為中文會變成什么
%52%
mysql怎么存盤表情符號
使用 utf8mb4_general_ci(推薦) utf8mb4_unicode_ci(更準確) 字符集
行程和執行緒
區別:行程是分配資源的最小單位,執行緒是調度資源的最小單位
一個行程中有一個或多個執行緒
一個執行緒只能屬于一個行程
行程之間的資源是獨立的,執行緒之間的資源是共享的,
執行緒的生命周期
執行緒的五大狀態(新建——準備——運行——阻塞——死亡)
mysql的優化方向
MYSQL優化主要分為以下四大方面:
設計:存盤引擎,myisam|innodb; 欄位型別,盡可能小(占用存盤空間少)、盡可能定長(占用存盤空間固定)、盡可能使用整數, 范式與逆范式
功能:索引,快取,磁區分表,
架構:主從復制,讀寫分離,負載均衡,
合理SQL:測驗,經驗,
參考博文:https://www.cnblogs.com/sharpest/p/10390035.html
過濾器Filter和攔截器Interceptor的區別
①攔截器是基于java的反射機制的,而過濾器是基于函式回呼,
②攔截器不依賴與servlet容器,過濾器依賴與servlet容器,
③攔截器只能對action請求起作用,而過濾器則可以對幾乎所有的請求起作用,
④攔截器可以訪問action背景關系、值堆疊里的物件,而過濾器不能訪問,
⑤在action的生命周期中,攔截器可以多次被呼叫,而過濾器只能在容器初始化時被呼叫一次,
⑥攔截器可以獲取IOC容器中的各個bean,而過濾器就不行,這點很重要,在攔截器里注入一個service,可以呼叫業務邏輯,
參考博文:https://www.cnblogs.com/panxuejun/p/7715917.html
String 為什么不能被繼承
因為 是fanal
怎么實作自動登錄的
token機制,token過期之后,用refess_token 去重繪,獲取新的token,保證登錄狀態
Springcloud和dubbo的區別
服務的發現、注冊、路由、熔斷、降級、分布式配置
dubbo是呼叫方式 rpc 通訊協議 cloud rest api
dubbo由于是二進制的傳輸,占用帶寬會更少 cloud 帶寬會比較多,同時使用http協議一般會使用JSON報文,消耗會更大
sync和lock的區別
- Synchronized和Lock的區別:Synchronized編碼更簡單,鎖機制由JVM維護,在競爭不激烈的情況下性能更好,Lock功能更強大更靈活,競爭激烈時性能較好,
- 性能不一樣:資源競爭激勵的情況下,lock性能會比synchronize好,競爭不激勵的情況下,synchronize比lock性能好,synchronize會根據鎖的競爭情況,從偏向鎖–>輕量級鎖–>重量級鎖升級,而且編程更簡單,
- 鎖機制不一樣:synchronize是在JVM層面實作的,系統會監控鎖的釋放與否,lock是JDK代碼實作的,需要手動釋放,在finally塊中釋放,可以采用非阻塞的方式獲取鎖,
- Synchronized的編程更簡潔,lock的功能更多更靈活,缺點是一定要在finally里面 unlock()資源才行,
- 用法不一樣:synchronize可以用在代碼塊上,方法上,lock只能寫在代碼里,不能直接修改方法,
B+tree 的的特點
和B樹的主要區別如下:
- 有 k 個子節點的非葉子節點擁有 k 個關鍵字,B樹是k-1個,這使得非葉子節點能保存的關鍵字大大增加,因此樹高也大大降低,
- 關鍵字不保存資料,只是用來索引,這樣非葉子節點的所占的記憶體空間就變小了,讀到記憶體中的索引資訊就會更多一些,相當于減少了磁盤IO次數
資料都是存在葉子節點,這樣保證了相近的資料都能存在同一塊資料塊里,另外也使得B+樹的查詢次數更穩定,每次查詢次數都是相同的,需要查詢到葉子節點 - 葉子節點的指標指向下一個資料對應的葉子節點,因此B+樹具備了天然排序功能,在排序和范圍查找的時候更方便,可以通過葉子節點的指標找到下一個葉子節點的位置
- B+樹可以方便地做全表搜索,只需要從第一個葉子節點順序往后面掃描即可,而B樹則需要做樹的遍歷,
redis持久化機制
RDB 快照的方式寫入到二進制檔案中,默認的檔案名為dump.rdb, 有兩種觸發方式 , save bgsave 全量備份
AOF 檔案重寫原理 增量備份
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/240520.html
標籤:其他
上一篇:nginx基本使用
