面試:第三章:中級綜合

SSM框架面試問題

講下springmvc框架的工做流程

一、用戶向服務器發送請求,請求被SpringMVC的前端控制器DispatcherServlet截獲。html

二、DispatcherServlet對請求的URL(統一資源定位符)進行解析,獲得URI(請求資源標識符),而後根據該URI,調用HandlerMapping得到該Handler配置的全部相關的對象,包括Handler對象以及Handler對象對應的攔截器,這些對象都會被封裝到一個HandlerExecutionChain對象當中返回。前端

三、DispatcherServlet根據得到的Handler,選擇一個合適的HandlerAdapter。HandlerAdapter的設計符合面向對象中的單一職責原則,代碼結構清晰,便於維護,最爲重要的是,代碼的可複製性高。HandlerAdapter會被用於處理多種Handler,調用Handler實際處理請求的方法。java

四、提取請求中的模型數據,開始執行Handler(Controller)。在填充Handler的入參過程當中,根據配置,spring將幫助作一些額外的工做mysql

消息轉換:將請求的消息,如json、xml等數據轉換成一個對象,將對象轉換爲指定的響應信息。nginx

數據轉換:對請求消息進行數據轉換,如String轉換成Integer、Double等。 程序員

數據格式化:對請求的消息進行數據格式化,如將字符串轉換爲格式化數字或格式化日期等。angularjs

數據驗證:驗證數據的有效性如長度、格式等,驗證結果存儲到BindingResult或Error中。web

五、Handler執行完成後,向DispatcherServlet返回一個ModelAndView對象,ModelAndView對象中應該包含視圖名或視圖模型。面試

六、根據返回的ModelAndView對象,選擇一個合適的ViewResolver(視圖解析器)返回給DispatcherServlet。ajax

七、ViewResolver結合Model和View來渲染視圖。

八、將視圖渲染結果返回給客戶端。

以上8個步驟,DispatcherServlet、HandlerMapping、HandlerAdapter和ViewResolver等對象協同工做,完成SpringMVC請求—>響應的整個工做流程,這些對象完成的工做對於開發者來講都是不可見的,開發者並不須要關心這些對象是如何工做的,開發者,只須要在Handler(Controller)當中完成對請求的業務處理。

 

圖片怎麼上傳

前端實現異步上傳,後端使用springmvc的MultipartFile類型來接收,放到分佈式圖片服務器中,服務器返回圖片路徑把路徑返回頁面回顯圖片,開發或者測試環境能夠使用FastDFS

 

微服務和SOA有什麼區別?

若是一句話來談SOA和微服務的區別,即微服務再也不強調傳統SOA架構裏面比較重的ESB企業服務總線,同時SOA的思想進入到單個業務系統內部實現真正的組件化。說的更直白一點就是微服務被拆分的粒度更小

 

spring框架AOP執行原理簡單說下?還有就是AOP在事務管理方面是怎麼實現的?

Spring AOP使用的動態代理,所謂的動態代理就是說AOP框架不會去修改字節碼,而是在內存中臨時爲方法生成一個AOP對象,這個AOP對象包含了目標對象的所有方法,而且在特定的切點作了加強處理,並回調原對象的方法。

Spring AOP中的動態代理主要有兩種方式,JDK動態代理和CGLIB動態代理。JDK動態代理經過反射來接收被代理的類,而且要求被代理的類必須實現一個接口。JDK動態代理的核心是InvocationHandler接口和Proxy類。若是目標類沒有實現接口,那麼Spring AOP會選擇使用CGLIB來動態代理目標類。CGLIB(Code Generation Library),是一個代碼生成的類庫,能夠在運行時動態的生成某個類的子類,注意,CGLIB是經過繼承的方式作的動態代理,所以若是某個類被標記爲final,那麼它是沒法使用CGLIB作動態代理的。

AOP在事務管理方面,Spring使用AOP來完成聲明式的事務管理有annotation和xml兩種形式。開發中,方便代碼編寫,不少時候都是在spring配置文件中配置事務管理器並開啓事務控制註解。在業務類或業務類方法中添加@Transactional實現事務控制。

 

Spring 分佈式事務如何處理的?

第一種方案:可靠消息最終一致性,須要業務系統結合MQ消息中間件實現,在實現過程當中須要保證消息的成功發送及成功消費。即須要經過業務系統控制MQ的消息狀態

第二種方案:TCC補償性,分爲三個階段TRYING-CONFIRMING-CANCELING。每一個階段作不一樣的處理。

TRYING階段主要是對業務系統進行檢測及資源預留

CONFIRMING階段是作業務提交,經過TRYING階段執行成功後,再執行該階段。默認若是TRYING階段執行成功,CONFIRMING就必定能成功。

CANCELING階段是回對業務作回滾,在TRYING階段中,若是存在分支事務TRYING失敗,則須要調用CANCELING將已預留的資源進行釋放。

 

Springboot用過沒,跟我說說,他的特色?

Springboot是從無數企業實戰開發中總結出來的一個更加精煉的框架,使得開發更加簡單,能使用寥寥數行代碼,完成一系列任務。

1)  Springboot解決那些問題

a)    編碼更簡單

 i.          Spring框架因爲超重量級的XML,annotation配置,使得系統變得很笨重,難以維護

ii.          Springboot採用約點大於配置的方法,直接引入依賴,便可實現代碼的開發

b)    配置更簡單

Xml文件使用javaConfig代替,XML中bean的建立,使用@bean代替後能夠直接注入。

配置文件變少不少,就是application.yml

c)    部署更簡單

d)    監控更簡單

Spring-boot-start-actuator:

能夠查看屬性配置

線程工做狀態

環境變量

JVM性能監控

支付接口是怎麼作的?

微信支付

調用微信的支付接口,參考微信提供的api

使用了微信的統一下單接口和查詢支付狀態接口

每一個接口須要的參數放入到map中使用微信提供的sdk轉成XML字符串,httpClient遠程提交參數和接收結果。

支付寶支付

詳情https://www.alipay.com/

SpringBoot相關面試題

什麼是 Spring Boot?

Spring Boot 是 Spring 開源組織下的子項目,是 Spring 組件一站式解決方案,主要是簡化了使用 Spring 的難度,簡省了繁重的配置,提供了各類啓動器,開發者能快速上手。

爲何要用 Spring Boot?

Spring Boot 優勢很是多,如:

獨立運行

簡化配置

自動配置

無代碼生成和XML配置

應用監控

上手容易

Spring Boot 的核心配置文件有哪幾個?它們的區別是什麼?

Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件。

application 配置文件這個容易理解,主要用於 Spring Boot 項目的自動化配置。

bootstrap 配置文件有如下幾個應用場景。

  • 使用 Spring Cloud Config 配置中心時,這時須要在 bootstrap 配置文件中添加鏈接到配置中心的配置屬性來加載外部配置中心的配置信息;
  • 一些固定的不能被覆蓋的屬性;
  • 一些加密/解密的場景

 

Spring Boot 的配置文件有哪幾種格式?它們有什麼區別?

.properties 和 .yml,它們的區別主要是書寫格式不一樣。

 

Spring Boot 的核心註解是哪一個?它主要由哪幾個註解組成的?

啓動類上面的註解是@SpringBootApplication,它也是 Spring Boot 的核心註解,主要組合包含了如下 3 個註解:

@SpringBootConfiguration:組合了 @Configuration 註解,實現配置文件的功能。

@EnableAutoConfiguration:打開自動配置的功能,也能夠關閉某個自動配置的選項,如關閉數據源自動配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。

@ComponentScan:Spring組件掃描。

 

開啓 Spring Boot 特性有哪幾種方式?

1)繼承spring-boot-starter-parent項目

2)導入spring-boot-dependencies項目依賴

 

Spring Boot 須要獨立的容器運行嗎?

能夠不須要,內置了 Tomcat/ Jetty 等容器.

 

運行 Spring Boot 有哪幾種方式?

1)打包用命令或者放到容器中運行

2)用 Maven/ Gradle 插件運行

3)直接執行 main 方法運行

 

Spring Boot 自動配置原理是什麼?

註解 @EnableAutoConfiguration, @Configuration, @ConditionalOnClass 就是自動配置的核心,首先它得是一個配置文件,其次根據類路徑下是否有這個類去自動配置。

 

你如何理解 Spring Boot 中的 Starters?

Starters能夠理解爲啓動器,它包含了一系列能夠集成到應用裏面的依賴包,你能夠一站式集成 Spring 及其餘技術,而不須要處處找示例代碼和依賴包。如你想使用 Spring JPA 訪問數據庫,只要加入 spring-boot-starter-data-jpa 啓動器依賴就能使用了。

Starters包含了許多項目中須要用到的依賴,它們能快速持續的運行,都是一系列獲得支持的管理傳遞性依賴.

 

如何在 Spring Boot 啓動的時候運行一些特定的代碼?

能夠實現接口 ApplicationRunner 或者 CommandLineRunner,這兩個接口實現方式同樣,它們都只提供了一個 run 方法.

 

Spring Boot 有哪幾種讀取配置的方式?

Spring Boot 能夠經過 @PropertySource,@Value,@Environment, @ConfigurationProperties 來綁定變量

 

電商項目業務面試問題

哪些狀況用到activeMq?

商品上架後更新ES索引庫、更新靜態頁、發送短信

 

秒殺的時候,只有最後一件物品,該怎麼去搶或者分配?

秒殺商品的庫存都會放到redis中,在客戶下單時就減庫存,減完庫存會判斷庫存是否爲大於 0,若是小於0,表示庫存不足,剛纔減去的數量再恢復,整個過程使用redis的watch鎖。

 

你項目對於訂單是怎麼處理的,假如一個客戶在下訂單的時候沒有購買怎麼辦,對於顧客在購買商品的時候大家怎麼處理大家的庫存?

訂單表中設置了一個過時時間,天天會有定時任務來掃描訂單表數據,若是到達預訂的過時時間沒有付款就會取消此訂單交易。

關於庫存的設計是這樣的:

普通商品在發貨時纔去更新庫存,若是庫存不足商家會立刻補貨

秒殺的商品會在客戶下單時就減庫存,若是在規定時間(半個小時)沒有付款,會取消此訂單把庫存還原

 

redis存儲格式的選擇

redis支持的數據結構總共有5種:hash、value、list、set、zset,其中項目中用到最可能是hash

 

商品中的數據是哪裏來的

商品表的數據是在商家管理後臺中由商家錄入的。數據分別錄入到商品表、商品描述表和商品項表

 

當初設計項目時預計的訪問量計劃是多少

訪問量計劃是3000至5000

 

簡單介紹一下你的這個項目以及項目中涉及到的技術框架以及使用場景以及你主要負責項目中的哪一塊?

項目介紹時,先總體介紹是什麼項目,項目主要是作啥的,爲何會作這個項目(市場需求)?例如:XXX電商項目,是一個B2B2C綜合電商平臺。由三個系統組成,包含:運營商管理後臺、商家管理後臺、網站前臺。運營商平臺主要負責基礎數據維護、商家審覈、商品審覈等。商家管理後臺主要負責商家入駐、商品錄入/修改、商品上下架等。網站前臺主要負責商品銷售。包含:網站首頁、商品搜索、商品詳情展現、購物車、訂單、支付、用戶中心等模塊。

再介紹本身在項目中作的功能模塊。例如:運營商管理後臺的品牌、規格數據錄入,已經商品管理後臺商品錄入功能。同時,實現了網站前臺系統中的商品搜索、購物車等功能模塊。

而後介紹裏面使用的技術:例如:dubbo分佈式框架、ssm、es、redis、activeMQ、支付寶支付等等。最好是結合技術講解項目功能點如何實現。

 

秒殺系統中如何防止超售?如何避免腳本進行惡意刷單?

防止超售解決方案:將存庫從MySQL前移到Redis中,全部的寫操做放到內存中,因爲Redis中不存在鎖故不會出現互相等待,而且因爲Redis的寫性能和讀性能都遠高於MySQL,這就解決了高併發下的性能問題。而後經過隊列等異步手段,將變化的數據異步寫入到DB中。當達到庫存閥值的時候就不在消費隊列,並關閉購買功能。

避免腳本惡意刷單:採用IP級別的限流,即針對某一個IP,限制單位時間內發起請求數量。

 

單點登陸大家是本身編寫的仍是使用通用的CAS?

項目使用通用的CAS框架。

 

若是一個用戶的token被其餘用戶劫持了,怎樣解決這個安全問題。

a、在存儲的時候把token進行對稱加密存儲,用時解開。

b、將請求URL、時間戳、token三者進行合併加鹽簽名,服務端校驗有效性。

c、HTTPS對URL進行加密

 

項目部署上線後,運營商管理,商品審覈等後臺流量問題?

先詢問流量是指哪方面?流量分爲三種,一種是商家流量,另外一種是用戶流量,第三種運營商流量。

解決方案:

      這三種流量對系統運行形成很大壓力,隨着項目上線時間增加,壓力會愈來愈大,所以咱們要減輕系統訪問壓力 ,就須要作一系列優化措施。

       具體優化以下:

數據層面的優化:

從數據庫層面作優化,好比:索引,緩存,集羣,讀寫分離,主從複製,分表,分庫。

從數據庫設計層面的優化:好比減小表關聯,加入冗餘字段

從緩存方面優化:好比redis實現數據緩存,減輕數據庫壓力

從搜索上進行優化:好比查找索引庫

 

項目層面的優化:

採用面向服務的分佈式架構:分擔服務器壓力 ,提升項目併發量。 好比dubbox+zookeeper分佈式架構

採用分佈式文件系統實現海量文件存儲:如採用fastdfs實現海量圖片存儲,提升文件的訪問速度。

採用mq使用服務進一步解藕:同步索引庫,同步靜態資源,短信發送

            

 服務器層面的優化:

 集羣思想的使用:tomcat,zookeeper,redis,mysql等

Tomcat異步通訊的使用,tomcat鏈接池配置

 

秒殺和團購業務實現思路

回答:

將商品數量查詢出存入到redis中,全部用戶下單後,減掉redis中的數量

若是併發量很大時,還要考慮高併發問題,因此能夠加入mq消息中間件處理搶單問題,再結合redis實現庫存減小操做。高併發方面還能夠考慮CDN,Nginx負載均衡等

 

大家項目中使用的安全框架是什麼

使用springSecurity 或者shiro,校驗用戶登陸和用戶權限!

 

項目中使用到的應用服務器是什麼

Tomcat+nginx

 

講一下每臺服務器的集羣數量

      項目中一共15臺項目服務,那麼爲了每一臺高可用一主一備,但首頁項目高併發設爲四臺服務器,則一共32臺項目服務器,再加redis集羣用了3臺,爲了每一臺高可用一主一備一共6臺,fastdfs一個trackerServer一個storageServer搭建集羣一共6臺,solr集羣7臺服務器,nginx爲了高可用一主一備一共2臺,mysql數據庫集羣3臺!activemq消息中間件高可用2臺;

共計:58臺服務器!

 

你在項目開發中碰到過哪些重大且棘手的問題

場景一:需求不明確困境

在項目開發中,項目採用迭代開發,開發需求不是很明確,對於項目開發初期來講很是困難,進度很是慢,有時開發的出的產品結果每每不能令老闆滿意,或者是甲方滿意,項目還須要不停的迭代,修改。

好比說:

在開發商城項目的時候,客戶定位是一個綜合性的商務平臺,能夠實如今線第三方商家對接,實現商品的銷售

可是並無明確的需求,所以開發全憑藉電商的項目經驗來實現裏面的相關的業務,後期慢慢迭代。 

 

場景二: ES高亮不能顯示的問題

前臺使用angularJS加載搜索結果,可是發現高亮不能展現。

問題緣由:

angularJS底層使用ajax,異步加載高亮信息返回給頁面後,頁面沒有刷新,就直接顯示返回的數據。此時會把全部的數據做爲普通的文本數據進行加載。所以就沒有高亮的效果。

解決方案:

使用angularJS過濾器過濾文本數據,此時angularJS過濾器把html文本數據解析爲瀏覽器能識別的html標籤。高亮就能展現了。

 

場景三:Nginx靜態頁面服務跳轉到購物車跨域問題

在Nginx中部署了靜態頁面,添加購物車時必須從靜態頁面跳轉到購物車系統,實現購物車添加操做。

因爲在靜態頁面中使用angularJS實現的跳轉,發現跳轉到購物車系統徹底沒有問題,可是並不能跳轉回到購物車系統頁面。

問題分析:

從靜態詳情繫統跳轉到購物車系統,會存在跨域問題,所以不能進行回調函數的數據傳遞。因此在回調函數中的頁面跳轉就不能實現。

解決方案:

使用angularJS跨域調用及springmvc跨域配置,解決問題。

 

 場景四:activeMQ存在運行時間長了之後,收不到消息的現象

時間長了就會出現,卡死,新的數據不能從隊列接聽到。只能重啓程序。

解決方案:

1)不要頻繁的創建和關閉鏈接

 JMS使用長鏈接方式,一個程序,只要和JMS服務器保持一個鏈接就能夠了,不要頻繁的創建和關閉鏈接。頻繁的創建和關閉鏈接,對程序的性能影響仍是很大的。這一點和jdbc仍是不太同樣的。

2)Connection的start()和stop()方法代價很高

 JMS的Connection的start()和stop()方法代價很高,不能常常調用。咱們試用的時候,寫了個jms的connection pool,每次將connection取出pool時調用start()方法,歸還時調用stop()方法,然然後來用jprofiler發現,通常的cpu時間都耗在了這兩個方法上。

3)start()後才能收消息

 Connection的start()方法調用後,才能收到jms消息。若是不調用這個方法,能發出消息,可是一直收不到消息。不知道其它的jms服務器也是這樣。

4)顯式關閉Session

若是忘記了最後關閉Connection或Session對象,都會致使內存泄漏。這個在我測試的時候也發現了。原本覺得關閉了Connection,由這個Connection生成的Session也會被自動關閉,結果並不是如此,Session並無關閉,致使內存泄漏。因此必定要顯式的關閉Connection和Session。

5)對Session作對象池

對Session作對象池,而不是Connection。Session也是昂貴的對象,每次使用都新建和關閉,代價也很是高。並且後來咱們發現,原來Connection是線程安全的,而Session不是,因此後來改爲了對Session作對象池,而只保留一個Connection。

6) 集羣

ActiveMQ有強大而靈活的集羣功能,可是使用起來仍是會有不少陷阱

 

場景五:activeMQ存在發出消息太大,形成消息接受不成功

多個線程從activeMQ中取消息,隨着業務的擴大,該機器佔用的網絡帶寬愈來愈高。

仔細分析發現,mq入隊時並無異常高的網絡流量,僅僅在出隊時會產生很高的網絡流量。

 

最終發現是springjmsTemplateactivemqprefetch機制配合致使的問題。

研究源碼發現jmsTemplate實現機制是:每次調用receive()時都會建立一個新的consumer對象,用完即銷燬。

正常狀況下僅僅會浪費重複建立consumer的資源代價,並不至於產生正常狀況十倍百倍的網絡流量。

可是activeMQ有一個提升性能的機制prefetch,此時就會有嚴重的問題。

prefetch機制:
每次consumer鏈接至MQ時,MQ預先存放許多message到消費者(前提是MQ中存在大量消息),預先存 放message的數量取決於prefetchSize(默認爲1000)。此機制的目的很顯然,是想讓客戶端代碼用一個consumer反覆進行 receive操做,這樣可以大量提升出隊性能。

此機制與jmsTemplate配合時就會產生嚴重的問題,每次jmsTemplate.receive(),都會產生1000個消息的網絡流量, 可是由於jmsTemplae並不會重用consumer,致使後面999個消息都被廢棄。反覆jmsTemplate.receive()時,表面上看 不出任何問題,其實網絡帶寬會形成大量的浪費。


解決方案:

一、若堅持使用jmsTemplate,須要設置prefetch值爲1,至關於禁用了activeMQ的prefetch機制,此時感受最健壯, 就算多線程,反覆調用jmsTemplate.receive()也不會有任何問題。可是會有資源浪費,由於要反覆建立consumer並頻繁與服務器進 行數據通訊,但在性能要求不高的應用中也不算什麼問題。

二、不使用jmsTemplate,手工建立一個consumer,並單線程反覆使用它來receive(),此時能夠充分利用prefetch機制。配合多線程的方式每一個線程擁有本身的一個consumer,此時可以充分發揮MQ在大吞吐量時的速度優點。

切記避免多線程使用一個consumer形成的消息混亂。大吞吐量的應用推薦使用方案2,可以充分利用prefetch機制提升系MQ的吞吐性能。

 

商品的價格變化後,如何同步redis中數以百萬計的購物車數據。

購物車只存儲商品id,到購物車結算頁面將會重新查詢購物車數據,所以就不會涉及購物車商品價格同步的問題。

 

系統中的錢是如何保證安全的。

在當前互聯網系統中錢的安全是頭等大事,如何保證錢的安全能夠從如下2個方面來思考:

1)錢計算方面

在系統中必須是浮點數計算類型存儲錢的額度,不然計算機在計算時可能會損失精度。

2)事務處理方面

在當前環境下,高併發訪問,多線程,多核心處理下,很容易出現數據一致性問題,此時必須使用事務進行控制,訪問交易出現安全性的問題,那麼在分佈式系統中,存在分佈式事務問題,能夠有不少解決方案:

使用 jpa能夠解決

使用 tcc 框架能夠解決等等。

 

作交易或是金融系統安全性須要從哪些方面考慮?沒有用什麼第三方能夠框架

ip黑白名單,訪問日誌明細記錄,防止重複提交,訪問頻率控制,分佈式鎖,數據先後端校驗,自動對帳任務處理,互聯網金融項目通常狀況下,不建議自動重試,最好結合對帳系統,人工進行處理,寫好人工處理的接口就好。其餘就是控制好數據的一致性了,這個最重要,其次還要保證接口的冪等性,不要重複處理訂單。這些是最基本的安全控制了。像這類網站用戶的輸入數據通常都不會太多,通常敏感詞過濾,廣告之類的能夠忽略,若是有的話還要控制這些。安全框架選shiro 了,在系統中分配好角色就行了,控制好用戶的資源訪問。其餘的用springmvc 就夠了

 

訂單中的事物是如何保證一致性的。

使用分佈式事務來進行控制,保證數據最終結果的一致性。

 

當商品庫存數量不足時,如何保證不會超賣。

當庫存數量不足時,必須保證庫存不能被減爲負數,若是不加以控制,庫存被減爲小於等於0的數,那麼這就叫作超賣。

那麼如何防止超賣的現象發生呢?

場景一: 若是系統併發要求不是很高

那麼此時庫存就能夠存儲在數據庫中,數據庫中加鎖控制庫存的超賣現象。

 

場景二:系統的併發量很大

若是系統併發量很大,那麼就不能再使用數據庫來進行減庫存操做了,由於數據庫加鎖操做自己是以損失數據庫的性能來進行控制數據庫數據的一致性的。

可是當併發量很大的時候,將會致使數據庫排隊,發生阻塞。所以必須使用一個高效的nosql數據庫服務器來進行減庫存。

此時能夠使用redis服務器來存儲庫存,redis是一個內存版的數據庫,查詢效率至關的高,能夠使用watch來監控減庫存的操做,一旦發現庫存被減爲0,立馬中止售賣操做。

 

大家系統的商品模塊和訂單模塊的數據庫是怎麼設計的

商品模塊設計:

商品模塊一共8張表,整個核心就是模板表。採用模板表爲核心的設計方法,來構造商品數據。

訂單設計:

訂單涉及的表有:

1)      收貨人地址

2)      訂單信息

3)      訂單明細

 

系統中商家活動策劃以及上報相關業務流程。

商城系統中有如下活動:

1)      秒殺活動

          a)    後臺設置秒殺商品

          b)    設置秒殺開啓時間,定時任務,開啓秒殺

          c)    秒殺減庫存(秒殺時間結束,庫存賣完,活動結束)

2)      促銷活動

3)      團購活動

4)      今日推薦

以上活動銷售記錄,統計,使用圖形化報表進行統計,能夠查看銷售狀況。

 

涉及到積分積累和兌換商品等業務是怎麼設計的

積分累計有2大塊:

積分累計:

根據用戶購買的商品的價格不一樣,沒有購買必定價格的商品,獲取必定的積分。

積分商城:

積分商城是用戶能夠使用積分商品換取商品的區域。

 

介紹下電商項目,你以爲那些是亮點?

這個項目是爲xxx開發的b2b2c類型綜合購物平臺,主要以銷售xxx,電子產品爲主要的電子商城網站。

項目的亮點是:

1)項目採用面向服務分佈式架構(使用dubbo,zookeeper)

            a)    解耦

            b)    提升項目併發能力

            c)    分擔服務器壓力

2)項目中使用activeMQ對項目進一步解耦

            a)    提升項目併發能力

            b)    提升任務處理速度

3)       使用微信支付,支付寶支付(本身總結)

4)       使用阿里大魚發生短信

5)       使用第三方分佈式文件系統存儲海量文件

6)       Nginx部署靜態頁面實現動靜分離

 

購物車功能作了嗎,實現原理說一下?

  1. 加入購物車 
    加入購物車插入到庫中一條購物記錄,同時插入到緩存中,緩存的key是記錄的id 
    未登陸狀態 
    用戶未登陸時點擊加入購物車,將productId ,skuId,buyNum 轉換成json存到cookie中(同一件商品不一樣的skuId視爲兩個商品,相同的skuId和productId視爲相同商品數量累加),用戶登陸成功的時候接收用戶的消息將cookie中的商品信息保存到數據庫中,而後清空cookie數據(京東)否則會出現登陸成功後刪除購物車商品而後退出,購物車中顯示問題 
    登陸狀態 
    點擊加入購物車將long userId,long productId,long skuId,int count 存到庫中,相同的productId和skuId 數量累加,不一樣的skuId新增一條 
    addToCart(long userId,long skuId,int count); //加入sku到購物車商品
  2. 修改商品數量 
    未登陸狀態 
    用戶未登陸時,點擊加減數量,根據productId和skuId從cooike中將商品數量進行加減,注意校驗cooike中的數量不能小於0,不能大於庫存數量 
    登陸狀態 
    用戶登陸狀態時,點擊加減數量productId和skuId,userId將用戶購物車中某個sku的數量增長或減去differ值,注意校驗庫存數量 
    updateAmount(long userId,skuId,int differ,List selectedSkuIds); //將用戶購物車中某個sku的數量增長或減去differ值。此方法更新商品後,會根據selectedSkuIds從新計算一遍購物車價格,返回知足條件的優惠券
  3. 刪除購物車記錄 
    未登陸狀態 
    用戶未登陸時,根據productId和skuId刪除cookie中的記錄 
    deleteCart(long userId,long skuId, List selectedSkuIds); //將某個sku從用戶購物車移除。此接品,在清除後臺會重複計算selectedSkuIds價格,並會返回選中的sku列表與未選中的sku列表集合。及相應優惠券。 
    登陸狀態 
    登陸狀態下,直接根據productId和skuId以及userId刪除庫中數據 
    4購物車列表展現 
    未登陸狀態 
    從cookie中取出productId以及skuId列表展現商品信息 
    登陸狀態 
    登陸狀態下根據用戶id查詢庫中的記錄數 
    getCart(long userId,list selectedSkuIds); //查詢用戶購物車。此接口會從新計算selectedSkuIds,並返回選中與未選中sku列表集合,返回相應的知足條件的優惠券信息。

5.訂單提交成功後更新購物車數量以及修改購物車狀態 
訂單提交成功後接收訂單成功消息,更新購物車狀態和數量刪除緩存記錄

6.商品下架後,更新庫存狀態,顯示失效 
商品下架後接收消息修改購物車裏的商品狀態爲失效

 

們的項目上線了嗎?這麼大的項目怎麼沒上線?

項目上線問題回答:

1)       項目沒有上線

若是你沒有作過電商的項目,能夠說項目沒有上線以前,你離職了,這個一個創業型的公司,或者此項目是給甲方作的項目,你沒有參與上線。以此來回避這個問題.

2)       項目上線

項目已經上線了

上線環境:

a)    Centos7

b)    Mysql

c)    Jdk8

d)    Tomcat8

    關於上線,那麼面試官必定會問您,上線遇到什麼問題沒有?

所以必須把項目中遇到的問題準備2個,如下能夠做爲參考

問題一:(用戶非正常流程致使的錯誤)

用戶註冊一半就退出來,致使再次註冊不成功或者用證件號登錄觸發空指針異常。

解決辦法:一旦輸入證件號時,檢查數據庫的表是否有相應的證件號記錄,有則把相關記錄所有刪掉,從而讓他成功註冊。空指針異常的解決辦法,作非空驗證的判斷。

問題二:(併發插入,流水號不一致)

   出現大量的主鍵惟一約束錯誤,後來想到是產生的預報名號不一樣步,致使有可能大併發量時產生多個相同的流水號,插入就會出現主鍵惟一約束錯誤。

   解決辦法:在數據庫裏寫一個insert的觸發器。自動替換掉要插入的主鍵爲 max(key)+1.

問題三:(併發刪除,索引失效)

   出現某些表的索引失效,後來發現是插入相同主鍵屢次以後致使表失效。

  解決辦法:設定oracle任務,讓數據庫每隔12個小時自動重建全部索引。

問題四:(js代碼的不細緻)

   發現報考志願顯示的專業比原來的少一個。

  解決辦法:發現時jsp頁面的js少循環一個=號致使的。。。。

問題五:(頁面和後臺代碼太不通用)

    用戶需求一旦更改或者程序邏輯有錯誤後,致使要修改不少頁面和後臺代碼,十分不通用,要從業務邏輯上設計的通用點。改一個,就能等同於改所有。用一些設計模式去解決。
 

 

訂單怎麼實現的,大家這個功能怎麼這麼簡單?

訂單實現:

從購物車系統跳轉到訂單頁面,選擇默認收貨地址

選擇支付方式

購物清單展現

提交訂單

訂單業務處理:

一個商家一個訂單,不一樣的倉庫發送的貨品也是屬於不一樣的訂單。所以會產出不一樣的訂單號。

訂單處理:根據支付的狀態進行不一樣的處理

1) 在線支付

a)    支付未成功—重新發起支付

b)    支付超時---訂單關閉

2) 貨到付款 

 

大家這個項目有秒殺嗎,怎麼實現的?

所謂「秒殺」,就是網絡賣家發佈一些超低價格的商品,

全部買家在同一時間網上搶購的一種銷售方式。通俗一點講就是網絡商家爲促銷等目的組織的網上限時搶購活動。因爲商品價格低廉,每每一上架就被搶購一空,有時只用一秒鐘。

秒殺商品一般有兩種限制:庫存限制、時間限制。

需求:

(1)商家提交秒殺商品申請,錄入秒殺商品數據,主要包括:商品標題、原價、秒殺價、商品圖片、介紹等信息

(2)運營商審覈秒殺申請

(3)秒殺頻道首頁列出秒殺商品(進行中的)點擊秒殺商品圖片跳轉到秒殺商品詳細頁。

(4)商品詳細頁顯示秒殺商品信息,點擊當即搶購實現秒殺下單,下單時扣減庫存。當庫存爲0或不在活動期範圍內時沒法秒殺。

(5)秒殺下單成功,直接跳轉到支付頁面(微信掃碼),支付成功,跳轉到成功頁,填寫收貨地址、電話、收件人等信息,完成訂單。

(6)當用戶秒殺下單5分鐘內未支付,取消預訂單,調用微信支付的關閉訂單接口,恢復庫存。

數據庫表分析

Tb_seckill_goods 秒殺商品表

Tb_seckill_order 秒殺訂單表

秒殺實現思路

秒殺技術實現核心思想是運用緩存減小數據庫瞬間的訪問壓力!讀取商品詳細信息時運用緩存,當用戶點擊搶購時減小redis中的庫存數量,當庫存數爲0時或活動期結束時,同步到數據庫。 產生的秒殺預訂單也不會馬上寫到數據庫中,而是先寫到緩存,當用戶付款成功後再寫入數據庫。

 

大家這個項目用的什麼數據庫,數據庫有多少張表?

項目使用mysql數據庫,總共有103張表,其中商品表共計有8張。

 

項目部署作過嗎,能不能部署?

作過,能夠部署。

項目服務器:集羣部署

數據庫服務器:集羣部署

Nginx集羣:負載均衡

 

單點登陸怎麼作的,用別人知道原理嗎?

在分佈式項目中實現session共享,完成分佈式系統單點登陸

3)       Cookie中共享ticket

4)       Redis存儲session

分佈式系統共享用戶身份信息session,必須先獲取ticket票據,而後再根據票據信息獲取redis中用戶身份信息。

實現以上2點便可實現session共享。

目前項目中使用的springsecurity + cas 來實現的單點登陸,cas自動產生ticket票據信息,每次獲取用戶信息,cas將會攜帶ticket信息獲取用戶身份信息。

 

支付作了嗎,支付寶仍是微信,實現說下?

微信支付:

1)       調用微信支付下單接口

2)       返回支付地址,生成二維碼

3)       掃描二維碼便可完成支付

問題: 微信支付二維碼是咱們本身生成的,所以必須時刻監控微信支付二維碼的狀態,確保支付成功。

支付寶支付能夠參考www.alipay.com

 

緩存及優化方面的面試問題

怎麼提升redis緩存利用率

一、從業務場景分析,預計會高頻率用到的數據預先存放到redis中,

二、能夠定時掃描命中率低的數據,能夠直接從redis中清除。

 

怎麼實現數據量大、 併發量高的搜索

建立solr索引庫,數據量特別大時採用solr分佈式集羣

 

MySQL索引使用限制

    不要在列上進行運算。
    select * from users where YEAR(adddate)<2007; 將在每一個行上進行運算,這將致使索引失效而進行全表掃描,所以咱們能夠改爲select * from users where adddate<‘2007-01-01’;
    like語句操做
    若是使用like。like 「%aaa%」 不會使用索引而like 「aaa%」能夠使用索引。
    select * from users where name like '%aaa%'不會使用索引
    select * from users where name like 'aaa%'能夠使用索引
    使用短索引
    例如,若是有一個CHAR(255)的列,若是在前10個或20個字符內,多數值是唯一的,那麼就不要對整個列進行索引。短索引不只能夠提升查詢速度並且能夠節省磁盤空間和I/O操做。
    索引不會包含NULL列
    複合索引中若是有一列含有NULL值那麼這個組合索引都將失效,通常須要給默認值0或者 ' '字符串
    最左匹配
    不按索引最左列開始查詢(多列索引) 例如index(‘c1’, ‘c2’, ‘c3’) ,where ‘c2’ = ‘aaa’ 不使用索引,where ‘c2’ = ‘aaa’ and ‘c3’ = ‘sss’ 不能使用索引。where ‘c1’ = ‘aaa’ and ‘c2’ = ‘bbb’ 能夠使用索引
    多列範圍查詢
    查詢中某個列有範圍查詢,則其右邊的全部列都沒法使用查詢(多列查詢)。where c1= ‘xxx’ and c2 like = ‘aa%’ and c3=’sss’ 該查詢只會使用索引中的前兩列,c3將不能使用到索引,由於like是範圍查詢。
    檢索排序
    一個查詢語句中,既有檢索又有排序而且是不一樣的字段,且這兩個列上都有單列索引(獨立索引),那麼只有其中一個列用到索引,由於查詢優化器在作檢索和排序中不能同時使用兩個不一樣的索引
    索引散列度
    經過索引掃描的記錄超過了表總行數的30%(估計值),則查詢優化器認爲全表掃描的效率更高,因此會變成全表掃描查詢
    隱式轉換
    隱式轉換致使的索引失效。好比,表的字段tu_mdn定義爲varchar(20),但在查詢時把該字段做爲number類型當作where條件,這樣會致使索引失效. 錯誤的例子:select * from test where tu_mdn=13333333333; 正確的例子:select * from test where tu_mdn='13333333333’;
 

怎麼分詞

使用第三方的分詞器IKAnalyzer,會按照中國人用此習慣自動分詞。

 

seo怎麼優化

使用restful,或靜態頁這樣能更好的被搜索引擎收錄。

 

怎麼加快訪問速度

硬件上加大網絡帶寬、和服務器內存

代碼的處理:靜態頁面、緩存、優化sql、建立索引等方案

 

講到redis緩存的時候說不清楚

  1. redis中項目中的應用。1.主要應用在門戶網站首頁廣告信息的緩存。由於門戶網站訪問量較大,將廣告緩存到redis中,能夠下降數據庫訪問壓力,提升查詢性能。2.應用在用戶註冊驗證碼緩存。利用redis設置過時時間,當超過指定時間後,redis清理驗證碼,使過時的驗證碼無效。3.用在購物車模塊,用戶登錄系統後,添加的購物車數據須要保存到redis緩存中。
  2. 技術角度分析:

內存若是滿了,採用LRU算法進行淘汰。

Redis如何實現負載的?採用Hash槽來運算存儲值,使用CRC16算法取模運算,來保證負載問題。

Redis緩存穿透問題?將數據查詢出來若是沒有強制設置空值,而且設置過時時間,減小頻繁查詢數據庫。

 

能講下redis的具體使用場景嗎?使用redis存儲長期不改變的數據徹底能夠使用也看靜態化,那麼大家當時是爲何會使用redis?

redis在項目中應用:1.主要應用在門戶網站首頁廣告信息的緩存。由於門戶網站訪問量較大,將廣告緩存到redis中,能夠下降數據庫訪問壓力,提升查詢性能。2.應用在用戶註冊驗證碼緩存。利用redis設置過時時間,當超過指定時間後,redis清理驗證碼,使過時的驗證碼無效。3.用在購物車模塊,用戶登錄系統後,添加的購物車數據須要保存到redis緩存中。

使用redis主要是減小系統數據庫訪問壓力。從緩存中查詢數據,也提升了查詢性能,挺高用戶體驗度。

 

redis中對一個key進行自增或者自減操做,它是原子性的嗎?

是原子性的。對於Redis而言,命令的原子性指的是:一個操做的不能夠再分,操做要麼執行,要麼不執行。Redis的操做之因此是原子性的,是由於Redis是單線程的。對Redis來講,執行get、set以及eval等API,都是一個一個的任務,這些任務都會由Redis的線程去負責執行,任務要麼執行成功,要麼執行失敗,這就是Redis的命令是原子性的緣由。Redis自己提供的全部API都是原子操做,Redis中的事務實際上是要保證批量操做的原子性。

 

大家項目中使用到的數據庫是什麼?你有涉及到關於數據庫到建庫建表操做嗎?數據庫建立表的時候會有哪些考慮呢?

項目中使用的是MySQL數據庫,

數據庫建立表時要考慮

a、大數據字段最好剝離出單獨的表,以便影響性能

b、使用varchar,代替char,這是由於varchar會動態分配長度,char指定爲20,即時你存儲字符「1」,它依然是20的長度

c、給表創建主鍵,看到好多表沒主鍵,這在查詢和索引定義上將有必定的影響

d、避免表字段運行爲null,若是不知道添加什麼值,建議設置默認值,特別int類型,好比默認值爲0,在索引查詢上,效率立顯。

e、創建索引,彙集索引則意味着數據的物理存儲順序,最好在惟一的,非空的字段上創建,其它索引也不是越多越好,索引在查詢上優點顯著,在頻繁更新數據的字段上創建彙集索引,後果很嚴重,插入更新至關忙。

f、組合索引和單索引的創建,要考慮查詢實際和具體模式

 

mysql中哪些狀況下能夠使用索引,哪些狀況不能使用索引?mysql索引失效的情形有哪些?

使用索引:

a、 爲了快速查找匹配WHERE條件中涉及到列。

b、 若是表有一個multiple-column索引,任何一個索引的最左前綴能夠經過使用優化器來查找行

c、 當運行joins時,爲了從其餘表檢索行。MySql能夠更有效的使用索引在多列上若是他們聲明的類型和大小是同樣的話。在這個環境下,VARCHAR和CHAR是同樣的若是他們聲明的大小是同樣的

d、 爲了找到 MIN() or MAX()的值對於一個指定索引的列key_col.

總之,就是常常用到的列就最好建立索引。

 

不能使用引用:

    a) 數據惟一性差(一個字段的取值只有幾種時)的字段不要使用索引

好比性別,只有兩種可能數據。意味着索引的二叉樹級別少,可能是平級。這樣的二叉樹查找無異於全表掃描

b) 頻繁更新的字段不要使用索引

好比logincount登陸次數,頻繁變化致使索引也頻繁變化,增大數據庫工做量,下降效率

c) 字段不在where語句出現時不要添加索引,若是where後含IS NULL /IS NOT NULL/ like ‘%輸入符%’等條件,不建議使用索引只有在where語句出現,mysql纔會去使用索引

d) where 子句裏對索引列使用不等於(<>),使用索引效果通常

 

索引失效:

a.若是條件中有or,即便其中有條件帶索引也不會使用(這也是爲何儘可能少用or的緣由)

  注意:要想使用or,又想讓索引生效,只能將or條件中的每一個列都加上索引

  b.對於多列索引,不是使用的第一部分,則不會使用索引

     c.like查詢是以%開頭

d.若是列類型是字符串,那必定要在條件中將數據使用引號引用起來,不然不使用索引

     e.若是mysql估計使用全表掃描要比使用索引快,則不使用索引

 

8,java中的多線程在大家的這個項目當中有哪些體現?

        a,後臺任務:如定時向大量(100W以上)的用戶發送郵件;按期更新配置文件、任務調度(如quartz),一些監控用於按期信息採集

b,  自動做業處理:好比按期備份日誌、按期備份數據庫

c, 異步處理:如發微博、記錄日誌

 

Redis分佈式鎖理解

實現思想

獲取鎖的時候,使用setnx加鎖,並使用expire命令爲鎖添加一個超時時間,超過該時間則自動釋放鎖,鎖的value值爲一個隨機生成的UUID,經過此在釋放鎖的時候進行判斷。

獲取鎖的時候還設置一個獲取的超時時間,若超過這個時間則放棄獲取鎖。

釋放鎖的時候,經過UUID判斷是否是該鎖,如果該鎖,則執行delete進行鎖釋放。

 

Redis怎麼設置過時的?項目過程當中,使用了哪種持久化方式

設置過時:

this.redisTemplate.expire("max",tempTime,TimeUnit.SECONDS);

持久化方式:Redis默認的RDB方式

 

項目添加Redis緩存後,持久化具體怎麼實現的。

RDB:保存存儲文件到磁盤;同步時間爲15分鐘,5分鐘,1分鐘一次,可能存在數據丟失問題。

AOF:保存命令文件到磁盤;安全性高,修改後當即同步或每秒同步一次。

上述兩種方式在咱們的項目中都有使用到,在廣告輪播的功能中使用了redis緩存,先從redis中獲取數據,無數據後從數據庫中查詢後保存到redis中

採用默認的RDB方式,在廣告輪播的功能中使用了redis緩存,先從redis中獲取數據,無數據就從數據庫中查詢後再保存到redis中

 

項目中有用到過redis,訪問redis是經過什麼訪問的?redis可以存儲的數據類型有哪幾種?

Redis經過SpringDataRedis訪問的.

  Redis支持五種數據類型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)

 

怎樣進行程序性能調優

       系統性能就是兩個事:   

Throughput ,吞吐量。也就是每秒鐘能夠處理的請求數,任務數。

Latency, 系統延遲。也就是系統在處理一個請求或一個任務時的延遲。

那麼Latency越好,能支持的Throughput就會越高。由於Latency短說明處理速度快,因而就能夠處理更多的請求。

提升吞吐量:

   分佈式集羣,模塊解藕,設計模式

系統延遲:

       異步通訊

 

數據庫設計的面試問題

你有了解mysql的隔離級別嗎?mysql默認的隔離級別是什麼?

數據庫事務的隔離級別有四種,隔離級別高的數據庫的可靠性高,但併發量低,而隔離級別低的數據庫可靠性低,但併發量高,系統開銷小。

  1. READ UNCIMMITTED(未提交讀)
  2. READ COMMITTED(提交讀)
  3. REPEATABLE READ(可重複讀)
  4. SERIALIZABLE(可串行化)

mysql默認的事務處理級別是'REPEATABLE-READ',也就是可重複讀。

 

sql語句中關於查詢語句的優化大家是怎麼作的?

一、應儘可能避免在 where 子句中使用!=或<>操做符,不然將引擎放棄使用索引而進行全表掃描。

二、對查詢進行優化,應儘可能避免全表掃描,首先應考慮在 where 及 order by 涉及的列上創建索引。

三、應儘可能避免在 where 子句中對字段進行 null 值判斷,不然將致使引擎放棄使用索引而進行全表掃描

四、儘可能避免在 where 子句中使用 or 來鏈接條件,不然將致使引擎放棄使用索引而進行全表掃描

五、in 和 not in 也要慎用,不然會致使全表掃描

六、應儘可能避免在 where 子句中對字段進行表達式操做,這將致使引擎放棄使用索引而進行全表掃描。

七、應儘可能避免在where子句中對字段進行函數操做,這將致使引擎放棄使用索引而進行全表掃描

八、不要在 where 子句中的「=」左邊進行函數、算術運算或其餘表達式運算,不然系統將可能沒法正確使用索引。

九、在使用索引字段做爲條件時,若是該索引是複合索引,那麼必須使用到該索引中的第一個字段做爲條件時才能保證系統使用該索引,不然該索引將不會被使 用,而且應儘量的讓字段順序與索引順序相一致。

十、索引並非越多越好,索引當然能夠提升相應的 select 的效率,但同時也下降了 insert 及 update 的效率,由於 insert 或 update 時有可能會重建索引,因此怎樣建索引須要慎重考慮,視具體狀況而定。

十一、儘量的使用 varchar/nvarchar 代替 char/nchar ,由於首先變長字段存儲空間小,能夠節省存儲空間,其次對於查詢來講,在一個相對較小的字段內搜索效率顯然要高些。

十二、任何地方都不要使用 select * from t ,用具體的字段列表代替「*」,不要返回用不到的任何字段。

 

mysql索引失效的場景有哪些?like作模糊查詢的時候會失效嗎?

1.WHERE字句的查詢條件裏有不等於號(WHERE column!=…),MYSQL將沒法使用索引

2.相似地,若是WHERE字句的查詢條件裏使用了函數(如:WHERE DAY(column)=…),MYSQL將沒法使用索引

3.在JOIN操做中(須要從多個數據表提取數據時),MYSQL只有在主鍵和外鍵的數據類型相同時才能使用索引,不然即便創建了索引也不會使用

4.若是WHERE子句的查詢條件裏使用了比較操做符LIKE和REGEXP,MYSQL只有在搜索模板的第一個字符不是通配符的狀況下才能使用索引。好比說,若是查詢條件是LIKE 'abc%',MYSQL將使用索引;若是條件是LIKE '%abc',MYSQL將不使用索引。

5.在ORDER BY操做中,MYSQL只有在排序條件不是一個查詢條件表達式的狀況下才使用索引。儘管如此,在涉及多個數據表的查詢裏,即便有索引可用,那些索引在加快ORDER BY操做方面也沒什麼做用。

6.若是某個數據列裏包含着許多重複的值,就算爲它創建了索引也不會有很好的效果。好比說,若是某個數據列裏包含了淨是些諸如「0/1」或「Y/N」等值,就沒有必要爲它建立一個索引。

7.索引有用的狀況下就太多了。基本只要創建了索引,除了上面提到的索引不會使用的狀況下以外,其餘狀況只要是使用在WHERE條件裏,ORDER BY 字段,聯表字段,通常都是有效的。 創建索引要的就是有效果。 否則還用它幹嘛? 若是不能肯定在某個字段上創建的索引是否有效果,只要實際進行測試下比較下執行時間就知道。

8.若是條件中有or(而且其中有or的條件是不帶索引的),即便其中有條件帶索引也不會使用(這也是爲何儘可能少用or的緣由)。注意:要想使用or,又想讓索引生效,只能將or條件中的每一個列都加上索引

9.若是列類型是字符串,那必定要在條件中將數據使用引號引用起來,不然不使用索引

10.若是mysql估計使用全表掃描要比使用索引快,則不使用索引

 

問題二:Like模糊查詢,創建索引會失效

項目中關於表結構拆分,大家是業務層面的拆分仍是表結構層面的拆分?

表結構層面的拆分。經過mycat數據庫中間件完成數據庫分表操做。

業務層面也有拆分,好比商品模塊拆分紅8張表來實現存儲

 

有了解過大數據層面的分庫分表嗎?以及mysql的執行計劃嗎?

分庫:經過Mycat結點來管理不一樣服務器上的數據庫,每一個表最多存500萬條記錄

分表:重直切割,水平切割

MySql提供了EXPLAIN語法用來進行查詢分析,在SQL語句前加一個"EXPLAIN"便可。mysql中的explain語法能夠幫助咱們改寫查詢,優化表的結構和索引的設置,從而最大地提升查詢效率。

 

有了解過數據庫中的表級鎖和行級鎖嗎?樂觀鎖和悲觀鎖你有哪些瞭解?

MySQL的鎖機制比較簡單,其最顯著的特色是不一樣的存儲引擎支持不一樣的鎖機制。好比,MyISAM和MEMORY存儲引擎採用的是表級鎖(table-level locking);InnoDB存儲引擎既支持行級鎖( row-level locking),也支持表級鎖,但默認狀況下是採用行級鎖。

MySQL主要的兩種鎖的特性可大體概括以下:
表級鎖: 開銷小,加鎖快;不會出現死鎖(由於MyISAM會一次性得到SQL所需的所有鎖);鎖定粒度大,發生鎖衝突的機率最高,併發度最低。
行級鎖: 開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的機率最低,併發度也最高。

 

樂觀鎖:經過version版本字段來實現

悲觀鎖:經過for update來實現

 

Mysql優化有沒有工具

三個MySQL性能測試工具:The MySQL Benchmark Suite、MySQL super-smack、MyBench。除了第一個爲MySQL性能測試工具,其餘兩個都爲壓力測試工具。

 

大家項目中使用到的數據庫是什麼?你有涉及到關於數據庫到建庫建表操做嗎?數據庫建立表的時候會有哪些考慮呢?

項目中使用的是MySQL數據庫,

數據庫建立表時要考慮

a、大數據字段最好剝離出單獨的表,以便影響性能

b、使用varchar,代替char,這是由於varchar會動態分配長度,char指定爲20,即時你存儲字符「1」,它依然是20的長度

c、給表創建主鍵,看到好多表沒主鍵,這在查詢和索引定義上將有必定的影響

d、避免表字段運行爲null,若是不知道添加什麼值,建議設置默認值,特別int類型,好比默認值爲0,在索引查詢上,效率立顯。

e、創建索引,彙集索引則意味着數據的物理存儲順序,最好在惟一的,非空的字段上創建,其它索引也不是越多越好,索引在查詢上優點顯著,在頻繁更新數據的字段上創建彙集索引,後果很嚴重,插入更新至關忙。

f、組合索引和單索引的創建,要考慮查詢實際和具體模式

 

怎樣進行數據庫優化

       a,選取最適用的字段

        在建立表的時候,爲了得到更好的性能,咱們能夠將表中字段的寬度設得儘量小。另一個提升效率的方法是在可能的狀況下,應該儘可能把字段設置爲NOTNULL,

       b,使用鏈接(JOIN)來代替子查詢(Sub-Queries)

       c,使用聯合(UNION)來代替手動建立的臨時表

       d,事物:

           a)要麼語句塊中每條語句都操做成功,要麼都失敗。換句話說,就是能夠保持數據庫中數據的一致性和完整性。事物以BEGIN關鍵字開始,COMMIT關鍵字結束。在這之間的一條SQL操做失敗,那麼,ROLLBACK命令就能夠把數據庫恢復到BEGIN開始以前的狀態。

           b) 是當多個用戶同時使用相同的數據源時,它能夠利用鎖定數據庫的方法來爲用戶提供一種安全的訪問方式,這樣能夠保證用戶的操做不被其它的用戶所幹擾。

       e,鎖定表

        f,使用外鍵

              鎖定表的方法能夠維護數據的完整性,可是它卻不能保證數據的關聯性。這個時候咱們就能夠使用外鍵。

        g,使用索引

        h,優化的查詢語句

 

怎樣進行數據庫性能調優

一應用程序優化

 (1)把數據庫看成奢侈的資源看待,在確保功能的同時,儘量少地動用數據庫資源。

 (2)不要直接執行完整的SQL 語法,儘可能經過存儲過程實現數據庫操做。

 (3)客戶與服務器鏈接時,創建鏈接池,讓鏈接儘可能得以重用,以免時間與資源的損耗。

 (4)非到不得已,不要使用遊標結構,確實使用時,注意各類遊標的特性。

二基本表設計優化

  (1)表設計遵循第三範式。在基於表驅動的信息管理系統中,基本表的設計規範是第三範式。

  (2)分割表。分割表可分爲水平分割表和垂直分割表兩種:水平分割是按照行將一個表分割爲多個表。

 (3)引入中間表。

 數據庫索引優化

索引是創建在表上的一種數據組織,它能提升訪問表中一條或多條記錄的特定查詢效率。 

彙集索引

  一種索引,該索引中鍵值的邏輯順序決定了表中相應行的物理順序。 

  彙集索引肯定表中數據的物理順序。

非彙集索引

  一種索引,該索引中索引的邏輯順序與磁盤上行的物理存儲順序不一樣.

 

分佈式開發面試問題

 

分佈式架構session共享問題,如何在集羣裏邊實現共享。

用了CAS,全部應用項目中若是須要登陸時在web.xml中配置過濾器作請求轉發到cas端工做原理是在cas登陸後會給瀏覽器發送一個票據(ticket),瀏覽器cookie中會緩存這個ticket,在登陸其餘項目時會拿着瀏覽器的ticket轉發到cas,到cas後根據票據判斷是否登陸

 

項目中如何配置集羣?

配置了redis集羣,使用redis3.0版本官方推薦的配置方式

solr集羣使用了solrCloud,使用zookeeper關聯solrCloud的配置文件

zookeeper也配置了集羣

應用層使用Nginx負載均衡

 

對分佈式,dubbo,zookeeper說的不太清楚

分佈式是從項目業務角度考慮劃分項目整個架構。能夠將項目基於功能模塊劃分再分別部署。Dubbo是實現分佈式項目部署框架。在zookeeper是dubbo分佈式框架的註冊中心,管理服務的註冊和調用。

 

從前端到後臺的實現的過程描述的也不清楚

項目前端採用angularjs框架在controller控制器中完成數據組裝和數據展現,在服務層(service)代碼完成中後臺請求操做。後端基於前端的接口調用,完成數據的增刪改查操做。先後端數據交互經過json格式字符串完成。

 

Dubbo爲何選擇Zookeeper,而不選擇Redis

引入了ZooKeeper做爲存儲媒介,也就把ZooKeeper的特性引進來。

首先是負載均衡,單註冊中心的承載能力是有限的,在流量達到必定程度的時候就須要分流,負載均衡就是爲了分流而存在的,一個ZooKeeper羣配合相應的Web應用就能夠很容易達到負載均衡;

資源同步,單單有負載均衡還不夠,節點之間的數據和資源須要同步,ZooKeeper集羣就自然具有有這樣的功能;

命名服務,將樹狀結構用於維護全局的服務地址列表,服務提供者在啓動 的時候,向ZK上的指定節點/dubbo/${serviceName}/providers目錄下寫入本身的URL地址,這個操做就完成了服務的發佈。 其餘特性還有Mast選舉,分佈式鎖等。

 

項目中Zookeeper服務器掛了,服務調用能夠進行嗎

能夠的,消費者在啓動時,消費者會從zk拉取註冊的生產者的地址接口等數據,緩存在本地。

每次調用時,按照本地存儲的地址進行調用

 

如何保證dubbo高可用?

1. zookeeper宕機與dubbo直連

在實際生產中,假如zookeeper註冊中心宕掉,一段時間內服務消費方仍是可以調用提供方的服務的,實際上它使用的本地緩存進行通信,這只是dubbo健壯性的一種。

dubbo的健壯性表現:

  • 監控中心宕掉不影響使用,只是丟失部分採樣數據
  • 數據庫宕掉後,註冊中心仍能經過緩存提供服務列表查詢,但不能註冊新服務
  • 註冊中心對等集羣,任意一臺宕掉後,將自動切換到另外一臺
  • 註冊中心所有宕掉後,服務提供者和服務消費者仍能經過本地緩存通信
  • 服務提供者無狀態,任意一臺宕掉後,不影響使用
  • 服務提供者所有宕掉後,服務消費者應用將沒法使用,並沒有限次重連等待服務提供者恢復

註冊中心的做用在於保存服務提供者的位置信息,咱們能夠徹底能夠繞過註冊中心——採用dubbo直連,即在服務消費方配置服務提供方的位置信息。

點對點直連方式,將以服務接口爲單位,忽略註冊中心的提供者列表,A 接口配置點對點,不影響 B 接口從註冊中心獲取列表。

xml配置方式

<dubbo:reference id="userService" interface="com.zang.gmall.service.UserService" url="dubbo://localhost:20880" />

註解上直接添加

@Reference(url = "127.0.0.1:20880")   
 UserService userService;

2. 集羣下dubbo負載均衡配置

在集羣負載均衡時,Dubbo提供了4種均衡策略,如:Random LoadBalance(隨機均衡算法)、RoundRobin LoadBalance(權重輪循均衡算法)、LeastAction LoadBalance(最少活躍調用數均衡算法)、ConsistentHash LoadBalance(一致性Hash均衡算法)。缺省時爲Random隨機調用。

@Reference(loadbalance = "roundrobin")
 UserService userService;

服務方方法級別配置(基於xml配置的權重輪詢均衡算法)

<dubbo:service interface="com.zang.gmall.service.UserService" 
<dubbo:method name="getUserAddressList" loadbalance="roundrobin"></dubbo:method>
</dubbo:service>

3. 權重設置

當不設置負載均衡策略,即採用默認的Random LoadBalance(隨機均衡算法)時,默認每一個服務的權重相同,咱們能夠經過設置權重來分配訪問的隨機性。

權重默認爲100,能夠在暴露服務的同時設置

 

4. 服務降級

當服務器壓力劇增的狀況下,根據實際業務狀況及流量,對一些服務和頁面有策略的不處理或換種簡單的方式處理,從而釋放服務器資源以保證核心交易正常運做或高效運做。

能夠經過服務降級功能臨時屏蔽某個出錯的非關鍵服務,並定義降級後的返回策略(不調用服務即返回爲空 or 調用失敗返回爲空

 向註冊中心寫入動態配置覆蓋規則:

RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null"));

其中:

  • mock=force:return+null 表示消費方對該服務的方法調用都直接返回 null 值,不發起遠程調用。用來屏蔽不重要服務不可用時對調用方的影響。
  • 還能夠改成 mock=fail:return+null 表示消費方對該服務的方法調用在失敗後,再返回 null 值,不拋異常。用來容忍不重要服務不穩定時對調用方的影響。

 經過操做管理控制檯也能夠方便的進行服務降級

5. 集羣容錯

在集羣調用失敗時,Dubbo 提供了多種容錯方案,缺省爲 failover 重試。

集羣容錯模式主要有如下幾種:

Failover Cluster

失敗自動切換,當出現失敗,重試其它服務器。一般用於讀操做,但重試會帶來更長延遲。可經過 retries="2" 來設置重試次數(不含第一次)。

消費方服務級註解添加(不能到方法級)

Failfast Cluster

快速失敗,只發起一次調用,失敗當即報錯。一般用於非冪等性的寫操做,好比新增記錄。

Failsafe Cluster

失敗安全,出現異常時,直接忽略。一般用於寫入審計日誌等操做。

Failback Cluster

失敗自動恢復,後臺記錄失敗請求,定時重發。一般用於消息通知操做。

Forking Cluster

並行調用多個服務器,只要一個成功即返回。一般用於實時性要求較高的讀操做,但須要浪費更多服務資源。可經過 forks="2" 來設置最大並行數。

Broadcast Cluster

廣播調用全部提供者,逐個調用,任意一臺報錯則報錯。一般用於通知全部提供者更新緩存或日誌等本地資源信息。

集羣模式配置方法

在服務提供方和消費方配置集羣模式

6. 整合hystrix

Hystrix 旨在經過控制那些訪問遠程系統、服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。Hystrix具有擁有回退機制和斷路器功能的線程和信號隔離,請求緩存和請求打包,以及監控和配置等功能。

spring boot官方提供了對hystrix的集成,直接在pom.xml里加入依賴:

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>1.4.4.RELEASE</version>
   </dependency>

而後在Application類上增長@EnableHystrix來啓用hystrix starter:

配置服務提供方:

在Dubbo的Provider上增長@HystrixCommand 配置,這樣子調用就會通過Hystrix代理。

配置服務消費方:

對於Consumer端,則能夠增長一層method調用,並在method上配置@HystrixCommand 。當調用出錯時,會走到 fallbackMethod = "reliable" 的調用裏。

@HystrixCommand註解設置的 reliable 調用方法的裏的參數要和 method 的參數保持一致。

 

ActiveMq消息被重複消費,丟失,或者不消費怎麼辦

重複消費:Queue支持存在多個消費者,可是對一個消息而言,只會有一個消費者能夠消費。

丟消息:用持久化消息,或者非持久化消息及時處理不要堆積,或者啓動事務,啓動事務後,commit()方法會負責任的等待服務器的返回,也就不會關閉鏈接致使消息丟失了。

不消費:去ActiveMQ.DLQ裏找找

 

怎樣解決activeMQ的消息持久化問題

A:持久化爲文件

     這個你裝ActiveMQ時默認就是這種,只要你設置消息爲持久化就能夠了。涉及到的配置和代碼有

<persistenceAdapter>

<kahaDB directory="${activemq.base}/data/kahadb"/>

</persistenceAdapter>

producer.Send(request, MsgDeliveryMode.Persistent, level, TimeSpan.MinValue);

      B:持久化爲MySql

      加載驅動jar,爲數據中建立三個數據庫表,存儲activemq的消息信息

 

若是activeMQ的消息沒有發送成功,怎樣確保再次發送成功。

        從新傳遞消息的狀況

ActiveMQ在接收消息的Client有如下幾種操做的時候,須要從新傳遞消息:

 1:Client用了transactions(事務),且在session中調用了rollback()

 2:Client用了transactions,且在調用commit()以前關閉

 3:Client在CLIENT_ACKNOWLEDGE的傳遞模式下,在session中調用了recover()

   確保客戶端有幾種狀態,檢測狀態,只要提交了那就說明客戶端成功!

 

Zookeeper怎樣進行服務治理

接受提供者的接口信息和提供者ip地址進行存儲,而後管理消費者和提供者之間調用關係!

 

若是activeMQ的服務掛了,怎麼辦

一、在一般的狀況下,非持久化消息是存儲在內存中的,持久化消息是存儲在文件中的,它們的最大限制在配置文件的<systemUsage>節點中配置。可是,在非持久化消息堆積到必定程度,內存告急的時候,ActiveMQ會將內存中的非持久化消息寫入臨時文件中,以騰出內存。雖然都保存到了文件裏,但它和持久化消息的區別是,重啓後持久化消息會從文件中恢復,非持久化的臨時文件會直接刪除。

二、考慮高可用,實現activemq集羣。

 

若是zookeeper服務掛了怎麼辦

  註冊中心對等集羣,任意一臺宕掉後,會自動切換到另外一臺

        註冊中心所有宕掉,服務提供者和消費者仍能夠經過本地緩存通信

服務提供者無狀態,任一臺宕機後,不影響使用

服務提供者所有宕機,服務消費者會沒法使用,並沒有限次重連等待服務者恢復

 

Dubbo有3次重試,假如新消息被重複消費怎麼處理

一、去掉超時重試機制

二、服務端增長冪等校驗,服務器加入校驗機制,若是這個消息已被 消費就再也不重複消費

 

MQ消費者接收不到消息怎麼辦。

Mq消費者接受不到消息存在2中狀況:

1. 處理失敗 指的是MessageListener的onMessage方法裏拋出RuntimeException。

2. Message頭裏有兩個相關字段:Redelivered默認爲false,redeliveryCounter默認爲0。

3. 消息先由broker發送給consumer,consumer調用listener,若是處理失敗,本地redeliveryCounter++,給broker一個特定應答,broker端的message裏redeliveryCounter++,延遲一點時間繼續調用,默認1s。超過6次,則給broker另外一個特定應答,broker就直接發送消息到DLQ。

4. 若是失敗2次,consumer重啓,則broker再推過來的消息裏,redeliveryCounter=2,本地只能再重試4次即會進入DLQ。

5. 重試的特定應答發送到broker,broker即會在內存將消息的redelivered設置爲true,redeliveryCounter++,可是這兩個字段都沒有持久化,即沒有修改存儲中的消息記錄。因此broker重啓時這兩個字段會被重置爲默認值。

 

系統的高併發問題是怎麼解決的。

併發問題高,這個問題的解決方案是一個系統性的,系統的每一層面都須要作優化:

1)      數據層

a)    集羣

b)    分表分庫

c)    開啓索引

d)    開啓緩存

e)    表設計優化

f)     Sql語句優化

g)    緩存服務器(提升查詢效率,減輕數據庫壓力)

h)    搜索服務器(提升查詢效率,減輕數據庫壓力)

2)      項目層

a)    採用面向服務分佈式架構(分擔服務器壓力,提升併發能力)

b)    採用併發訪問較高的詳情繫統採用靜態頁面

c)    使用頁面緩存

d)    用ActiveMQ使得業務進一步進行解耦,提升業務處理能力

e)    使用分佈式文件系統存儲海量文件

3)      應用層

a)    Nginx服務器來作負載均衡

b)    Lvs作二層負載

 

併發數多少,項目中怎麼解決併發問題?

       面試中項目的併發數不宜說的過大,安裝目前穀粒商城項目拆分規模,這個項目的併發是在10000+,可是學生面試不能說的這麼高。

 

能夠有如下2方面的回答:

1)    項目併發並不清楚(只是底層程序員)

2)    參與核心業務設計,知道併發是多少(測試峯值,上線併發)

3000---5000吧

面對項目高併發,項目必須作各類優化措施了:

4)      數據層

a)    集羣

b)    分表分庫

c)    開啓索引

d)    開啓緩存

e)    表設計優化

f)     Sql語句優化

g)    緩存服務器(提升查詢效率,減輕數據庫壓力)

h)    搜索服務器(提升查詢效率,減輕數據庫壓力)

5)      項目層

a)    採用面向服務分佈式架構(分擔服務器壓力,提升併發能力)

b)    採用併發訪問較高的詳情繫統採用靜態頁面

c)    使用頁面緩存

d)    用ActiveMQ使得業務進一步進行解耦,提升業務處理能力

e)    使用分佈式文件系統存儲海量文件

6)      應用層

a)    Nginx服務器來作負載均衡

b)    Lvs作二層負載

 

消息發送失敗怎麼處理,發送數據,數據庫已經保存了數據,可是redis中沒有同步,怎麼辦。或者說如何作到消息同步。

消息發送失敗,能夠進行消息的從新發送,能夠配置消息的重發次數。

若是消息重發完畢後,消息尚未接受成功,重啓服務。

 

Dubbo的通訊原理?

Dubbo底層使用hessain2進行二進制序列化進行遠程調用

Dubbo底層使用netty框架進行異步通訊。NIO

 

 

其餘技術面試問題

單點登陸的訪問或者跨域問題

首先要理解什麼是單點登陸。單點登陸是相互信任的系統模塊登陸一個模塊後,其餘模塊不須要重複登陸即認證經過。項目採用的是CAS單點登陸框架完成的。首先CAS有兩大部分。客戶端和服務端。服務端就是一個web工程部署在tomcat中。在服務端完成用戶認證操做。每次訪問系統模塊時,須要去CAS完成獲取ticket。當驗證經過後,訪問繼續操做。對於CAS服務端來講,咱們訪問的應用模塊就是CAS客戶端。

 

跨域問題,首先明白什麼是跨域。何時涉及跨域問題。當涉及前端異步請求的時候才涉及跨域。那什麼是跨域呢?當異步請求時,訪問的請求地址的協議、ip地址、端口號任意一個與當前站點不一樣時,就會涉及跨域訪問。解決方案:一、jQuery提供了jsonp實現二、W3C標準提供了CORS(跨域資源共享)解決方案。

 

shiro安全認證時如何作的

要明白shiro執行流程以及shiro的核心組件

認證過程:

在application Code應用程序中調用subject的login方法。將頁面收集的用戶名和密碼傳給安全管理器securityManager,將用戶名傳給realm對象。Realm對象能夠理解爲是安全數據橋,realm中認證方法基於用戶名從數據庫中查詢用戶信息。若是用戶存在,將數據庫查詢密碼返回給安全管理器securityManager,而後安全管理器判斷密碼是否正確。

 

ES的用途

ES在系統中主要完成商品搜索功能,提升搜索性能。

 

分佈式鎖的問題

針對分佈式鎖的實現,目前比較經常使用的有如下幾種方案:

1.基於數據庫實現分佈式鎖

2.基於緩存(redis,memcached,tair)實現分佈式鎖

3.基於zookeeper實現分佈式鎖

 

ES索引中使用了IK分詞器,大家項目中使用到了分詞器的哪一種工做模式?

IK分詞器,基本可分爲兩種模式,一種爲smart模式,一種爲非smart模式。

例如:張三說的確實在理
smart模式的下分詞結果爲:
張三 | 說的 | 確實 | 在理
而非smart模式下的分詞結果爲:
張三 | 三 | 說的 | 的確 | 的 | 確實 | 實在 | 在理
可見非smart模式所作的就是將可以分出來的詞所有輸出;smart模式下,IK分詞器則會根據內在方法輸出一個認爲最合理的分詞結果,這就涉及到了歧義判斷。

項目中採用的是smart模塊分詞的。

 

java中關於多線程的瞭解你有多少?線程池有涉及嗎?

同一類線程共享代碼和數據空間,每一個線程有獨立的運行棧和程序計數器(PC),線程切換開銷小。線程分爲五個階段:建立、就緒、運行、阻塞、終止。

Java線程有五種基本狀態

新建狀態(New):當線程對象對建立後,即進入了新建狀態,如:Thread t = new MyThread();
就緒狀態(Runnable):當調用線程對象的start()方法(t.start();),線程即進入就緒狀態。處於就緒狀態的線程,只是說明此線程已經作好了準備,隨時等待CPU調度執行,並非說執行了t.start()此線程當即就會執行;
運行狀態(Running):當CPU開始調度處於就緒狀態的線程時,此時線程才得以真正執行,即進入到運行狀態。注:就 緒狀態是進入到運行狀態的惟一入口,也就是說,線程要想進入運行狀態執行,首先必須處於就緒狀態中;
阻塞狀態(Blocked):處於運行狀態中的線程因爲某種緣由,暫時放棄對CPU的使用權,中止執行,此時進入阻塞狀態,直到其進入到就緒狀態,才 有機會再次被CPU調用以進入到運行狀態。根據阻塞產生的緣由不一樣,阻塞狀態又能夠分爲三種:
1.等待阻塞:運行狀態中的線程執行wait()方法,使本線程進入到等待阻塞狀態;
2.同步阻塞 -- 線程在獲取synchronized同步鎖失敗(由於鎖被其它線程所佔用),它會進入同步阻塞狀態;
3.其餘阻塞 -- 經過調用線程的sleep()或join()或發出了I/O請求時,線程會進入到阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程從新轉入就緒狀態。
死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命週期。

 

Java中線程的建立常見有如三種基本形式
1.繼承Thread類,重寫該類的run()方法。

2.實現Runnable接口,並重寫該接口的run()方法,

該run()方法一樣是線程執行體,建立Runnable實現類的實例,並以此實例做爲Thread類的target來建立Thread對象,該Thread對象纔是真正的線程對象。

3.使用Callable和Future接口建立線程。

具體是建立Callable接口的實現類,並實現clall()方法。並使用FutureTask類來包裝Callable實現類的對象,且以此FutureTask對象做爲Thread對象的target來建立線程。

線程池:線程池是一種多線程處理形式,處理過程當中將任務添加到隊列,而後在建立線程後自動啓動這些任務。線程池線程都是後臺線程。每一個線程都使用默認的堆棧大小,以默認的優先級運行,並處於多線程單元中。若是某個線程在託管代碼中空閒(如正在等待某個事件),則線程池將插入另外一個輔助線程來使全部處理器保持繁忙。若是全部線程池線程都始終保持繁忙,但隊列中包含掛起的工做,則線程池將在一段時間後建立另外一個輔助線程但線程的數目永遠不會超過最大值。超過最大值的線程能夠排隊,但他們要等到其餘線程完成後才啓動。

 

如何實現線程的同步?

爲什麼要使用同步? 

   java容許多線程併發控制,當多個線程同時操做一個可共享的資源變量時(如數據的增刪改查),將會致使數據不許確,相互之間產生衝突,所以加入同步鎖以免在該線程沒有完成操做以前,被其餘線程的調用,從而保證了該變量的惟一性和準確性。

線程同步(5種同步方式)

1.同步方法  2.同步代碼塊   3.使用特殊域變量(volatile)實現線程同步  4.使用重入鎖實現線程同步  5.使用局部變量實現線程同步 

 

遍歷hashmap有幾種方式?

Map的四種遍歷方式

(1) for each map.entrySet()

(2) 顯示調用map.entrySet()的集合迭代器

(3) for each map.keySet(),再調用get獲取

(4) for each map.entrySet(),用臨時變量保存map.entrySet()

 

簡單介紹一下Es全文檢索在整個系統中的應用,在更新索引庫的同時會產生索引碎片,這個碎片是如何處理的?

根據商品的名稱,分類,品牌等屬性來建立索引進行商品搜索。

更新索引庫時會先刪除索引,而後再重建。而對於刪除彙集索引,則會致使對應的非彙集索引重建兩次(刪除時重建,創建時再重建).直接刪除碎片。

 

java併發包下有哪些併發組件?

分爲兩層組成

    外層框架主要有Lock(ReentrantLock、ReadWriteLock等)、同步器(semaphores等)、阻塞隊列(BlockingQueue等)、Executor(線程池)、併發容器(ConcurrentHashMap等)、還有Fork/Join框架; 

內層有AQS(AbstractQueuedSynchronizer類,鎖功能都由他實現)、非阻塞數據結構、原子變量類(AtomicInteger等無鎖線程安全類)三種。

 

講一下jvm調優。

     a,堆大小設置

     b,回收器選擇

     c,輔助信息

        JVM提供了大量命令行參數,打印信息,供調試使用;

 

講一下jvm的組成。

      JVM 由類加載器子系統、運行時數據區、執行引擎以及本地方法接口組成

 

講一下ThreadLocal類。

ThreadLocal,不少地方叫作線程本地變量,也有些地方叫作線程本地存儲,其實意思差很少。可能不少朋友都知道ThreadLocal爲變量在每一個線程中都建立了一個副本,那麼每一個線程能夠訪問本身內部的副本變量;

ThreadLocal在每一個線程中對該變量會建立一個副本,即每一個線程內部都會有一個該變量,且在線程內部任何地方均可以使用,線程之間互不影響,這樣一來就不存在線程安全問題,也不會嚴重影響程序執行性能。

可是要注意,雖然ThreadLocal可以解決上面說的問題,可是因爲在每一個線程中都建立了副本,因此要考慮它對資源的消耗,好比內存的佔用會比不使用ThreadLocal要大;

 

怎麼確保session共享?

在分佈式項目中實現session共享必須作如下準備工做:

1)       Cookie中共享ticket

2)       Redis存儲session

分佈式系統共享用戶身份信息session,必須先獲取ticket票據,而後再根據票據信息獲取redis中用戶身份信息。

實現以上2點便可實現session共享。

 

目前項目中使用的springsecurity + cas 來實現的單點登陸,cas自動產生ticket票據信息,每次獲取用戶信息,cas將會攜帶ticket信息獲取用戶身份信息。

 

項目中哪塊涉及了線程問題,怎麼處理的?

項目的高併發訪問就是一個多線程問題。

項目中普通的業務開發基本沒有涉及多線程問題,不過你能夠談談你使用的框架中使用的多線程技術:

由於咱們項目使用的框架進行開發的,所以多線程處理多讓框架非咱們處理結束了。

1)       高併發就是多線程,這裏的多線程讓servlet服務器給處理了談談Tomcat多線程配置;

a)   配置線程池,擴大併發能力

b)  開啓NIO能力等等

2)       框架多線程:mybatis 框架底層使用的鏈接池

相關文章
相關標籤/搜索