Java是一種可以撰寫跨平臺應(yīng)用軟件的面向?qū)ο蟮某绦蛟O(shè)計語言。Java 技術(shù)具有卓越的通用性、高效性、平臺移植性和安全性,廣泛應(yīng)用于PC、數(shù)據(jù)中心、游戲控制臺、科學(xué)超級計算機、移動電話和互聯(lián)網(wǎng),同時擁有全球最大的開發(fā)者專業(yè)社群。
給你學(xué)習(xí)路線:html-css-js-jq-javase-數(shù)據(jù)庫-jsp-servlet-Struts2-hibernate-mybatis-spring4-springmvc-ssh-ssm

小編推薦一個學(xué)Java的學(xué)習(xí)裙【 六五零,五五四,六零七 】,無論你是大牛還是小白,是想轉(zhuǎn)行還是想入行都可以來了解一起進步一起學(xué)習(xí)!裙內(nèi)有開發(fā)工具,很多干貨和技術(shù)資料分享!
-- ************************************* 兩年程序員知識 begin****************************************
spring特性:
1,方便解耦,簡化開發(fā) 通過Spring提供的IoC容器,我們可以將對象之間的依賴關(guān)系交由Spring進行控制,避免硬編碼所造成的過度程序耦合。有了Spring,用戶不必再為單實例模式類、
屬性文件解析等這些很底層的需求編寫代碼,可以更專注于上層的應(yīng)用。
2,AOP編程的支持 通過Spring提供的AOP功能,方便進行面向切面的編程,許多不容易用傳統(tǒng)OOP實現(xiàn)的功能可以通過AOP輕松應(yīng)付。
3,聲明式事務(wù)的支持 在Spring中,我們可以從單調(diào)煩悶的事務(wù)管理代碼中解脫出來,通過聲明式方式靈活地進行事務(wù)的管理,提高開發(fā)效率和質(zhì)量。
4,方便程序的測試 可以用非容器依賴的編程方式進行幾乎所有的測試工作,在Spring里,測試不再是昂貴的操作,而是隨手可做的事情。
5,方便集成各種優(yōu)秀框架 Spring不排斥各種優(yōu)秀的開源框架,相反,Spring可以降低各種框架的使用難度,Spring提供了對各種優(yōu)秀框架(如Struts,Hibernate、Hession、Quartz)等的直接支持。
6,降低Java EE API的使用難度 Spring對很多難用的Java EE API(如JDBC,JavaMail,遠程調(diào)用等)提供了一個薄薄的封裝層,通過Spring的簡易封裝,這些Java EE API的使用難度大為降低。
7,Java 源碼是經(jīng)典學(xué)習(xí)范例 Spring的源碼設(shè)計精妙、結(jié)構(gòu)清晰、匠心獨用,處處體現(xiàn)著大師對Java設(shè)計模式靈活運用以及對Java技術(shù)的高深造詣。Spring框架源碼無疑是Java技術(shù)的最佳實踐范例。
如果想在短時間內(nèi)迅速提高自己的Java技術(shù)水平和應(yīng)用開發(fā)水平,學(xué)習(xí)和研究Spring源碼將會使你收到意想不到的效果。
對Spring aop的理解
AOP,也就是面向切面編程,我是這么理解的:學(xué)java的應(yīng)該都知道面向?qū)ο缶幊蹋╫op),而OOP是從靜態(tài)解讀考慮程序結(jié)構(gòu),但AOP是從動態(tài)角度考慮程序運行過程。
也可以說AOP是OOP的補充和完善。OOP引入了封裝、繼承和多態(tài)性等概念來建立一種對象層次結(jié)構(gòu), 用以模擬公共的一個集合。當(dāng)我們需要為分散的對象引入公共行為的時候,
則OOP顯得無能為力了。也就是說,OOP允許你定義從上到下的關(guān)系,但并不適合從左到右的關(guān)系,例如日志功能。日志代碼往往水平的散步在所有對象層次中,
而與它所散步到的對象的核心功能毫無關(guān)系。對于其他類型的代碼,如安全性、異常處理和透明的持續(xù)性也是如此。這種散布在各處的無關(guān)的代碼被稱為橫切代碼,
在oop設(shè)計中,他導(dǎo)致了大量代碼的重復(fù),而不利于各個模塊的重用。
而AOP技術(shù)則恰恰相反,它利用一種稱為“橫切”的技術(shù),剖解開封裝的對象內(nèi)部,并將哪些影響了多個類的公共行為封裝到一個可重用模塊,簡單的來說就是將那些與業(yè)務(wù)無關(guān),
卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任封裝起來。便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度等。
aop 底層有兩種代理(jdk代理,CGLIB代理):
java動態(tài)代理是利用反射機制生成一個實現(xiàn)代理接口的匿名類,在調(diào)用具體方法前調(diào)用InvokeHandler來處理。
cglib代理,是針對類來實現(xiàn)代理的,他的原理是對指定的目標類生成一個子類,并覆蓋其中方法實現(xiàn)增強,但因為采用的是繼承,所以不能對final修飾的類進行代理。(例如service的事務(wù)處理)
對Spring IOC的理解
IoC(控制反轉(zhuǎn)),將類的創(chuàng)建和依賴關(guān)系寫在配置文件里,由配置文件注入,實現(xiàn)了松耦合
IOC 底層實現(xiàn)原理:JAVA反射
springmvc的運行流程,實現(xiàn)原理?
執(zhí)行流程:
1). 若一個請求匹配 DispatcherServlet 的請求映射路徑(在 web.xml 中指定), WEB 容器將該請求轉(zhuǎn)交給 DispatcherServlet 處理
2). DispatcherServlet 接收到請求后, 將根據(jù)請求信息(包括 URL、HTTP 方法、請求 頭、請求參數(shù)、Cookie 等)及 HandlerMapping 的配置找到處理請求的處理器(Handler). 可將 HandlerMapping 看成路由控制器,將 Handler 看成目標主機。
3). 當(dāng) DispatcherServlet 根據(jù) HandlerMapping 得到對應(yīng)當(dāng)前請求的 Handler 后, 通過 HandlerAdapter 對 Handler 進行封裝,再以統(tǒng)一的適配器接口調(diào)用 Handler。
4). 處理器完成業(yè)務(wù)邏輯的處理后將返回一個 ModelAndView 給 DispatcherServlet, ModelAndView 包含了視圖邏輯名和模型數(shù)據(jù)信息
5). DispatcherServlet 借助 ViewResoler 完成邏輯視圖名到真實視圖對象的解析
6). 得 到 真 實 視 圖 對 象 View 后 , DispatcherServlet 使用這個 View 對 ModelAndView 中的模型數(shù)據(jù)進行視圖渲染
實現(xiàn)原理:
基于servlet實現(xiàn),同樣流行的mvc框架還有struts2,兩者區(qū)別是:
1,SpringMVC的入口是servlet,而Struts2是filter(filter執(zhí)行順序 > serlvet)
2,spring會稍微比struts快。 spring mvc是基于方法的設(shè)計 ,而sturts是基于類 ,每次發(fā)一次請求都會實例一個action,每個action都會被注入屬性,而spring基于方法,
粒度更細,但要小心把握像在servlet控制數(shù)據(jù)一樣。spring3mvc是方法級別的攔截,攔截到方法后根據(jù)參數(shù)上的注解,把request數(shù)據(jù)注入進去,在spring3mvc中,一個方法對應(yīng)一個request上下文,
所以說從架構(gòu)本身上SpringMVC就容易實現(xiàn)restful,且SpringMVC執(zhí)行和開發(fā)效率都應(yīng)該是高于Struts2的。
來說說你認為寫過的最復(fù)雜的業(yè)務(wù)邏輯吧;
這個嘛,我認為目前認為,我沒有寫過任何復(fù)雜的業(yè)務(wù)邏輯,任何復(fù)雜的業(yè)務(wù)邏輯,細化拆分都是有簡單的業(yè)務(wù)組成,如果你很想聽的話,
那我就以登錄為例給你說說吧
1,首先,判斷用戶是否存在,若不存在,返回前端賬戶不存在信息(json形式),否則執(zhí)行下一步;
2,判斷輸入密碼是否錯誤,如果錯誤,返回前端密碼錯誤,用戶密碼錯誤次數(shù)加一,若大于指定次數(shù),鎖定該用戶,否則執(zhí)行下一步;
3,判斷用戶是否首次登錄,若是,跳轉(zhuǎn)指定頁面,強制修改密碼,修改完畢之后,重新登錄即可,否則進入下一步;
4,判斷用戶上次登錄時間,如果超過指定時間,跳轉(zhuǎn)強制修改頁面,否則進入下一步;
5,判斷用戶上次修改密碼時間,如果超過指定時間,跳轉(zhuǎn)強制修改頁面,否則進入下一步;
6,初始化一些信息(授權(quán),基礎(chǔ)信息保存【字典信息】等),放入session,修改上次用戶登錄時間,
7,返回成功登錄頁面
-- *************************************兩年以上程序員 end****************************************
-- **************************************************************************************************
-- *************************************三年以上程序員 begin****************************************
-- **************************************************************************************************
深入分析ClassLoader
先說說為什么要知道java的類加載機制。個人認為主要有以下幾個原因:
按需加載。JVM啟動時不能確定我要加載哪些東西,或者有些類非常大,我只希望用到它時再加載,并非一次性加載所有的class,所以這時候了解了加載機制就可以按需加載了。
類隔離。比如web容器中部署多個應(yīng)用,應(yīng)用之間互相可能會有沖突,所以希望盡量隔離,這里可能就要分析各個應(yīng)用加載的資源和加載順序之間的沖突,針對這些沖突再自己定些規(guī)則,
讓它們能夠愉快地玩耍。
資源回收。如果你不了解java是如何加載資源的,又怎么理解java是如何回收資源的?
一般說到j(luò)ava的類加載機制,都要說到“雙親委派模型”(其實個人很不理解為什么叫“雙親”,其實英文叫“parent”)。使用這種機制,可以避免重復(fù)加載,當(dāng)父親已經(jīng)加載了該類的時候,
就沒有必要子ClassLoader再加載一次。JVM根據(jù) 類名+包名+ClassLoader實例ID 來判定兩個類是否相同,是否已經(jīng)加載過(所以這里可以略微擴展下,可以通過創(chuàng)建不同的classloader實例
來實現(xiàn)類的熱部署)。
a) BootStrapClassLoader。它是最頂層的類加載器,是由C++編寫而成, 已經(jīng)內(nèi)嵌到JVM中了。在JVM啟動時會初始化該ClassLoader,它主要用來讀取Java的核心類庫JRE/lib/rt.jar中所有的class文件,這個jar文件中包含了java規(guī)范定義的所有接口及實現(xiàn)。
b) ExtensionClassLoader。它是用來讀取Java的一些擴展類庫,如讀取JRE/lib/ext/*.jar中的包等(這里要注意,有些版本的是沒有ext這個目錄的)。
c) AppClassLoader。它是用來讀取CLASSPATH下指定的所有jar包或目錄的類文件,一般情況下這個就是程序中默認的類加載器。
d) CustomClassLoader。它是用戶自定義編寫的,它用來讀取指定類文件 ?;谧远x的ClassLoader可用于加載非Classpath中(如從網(wǎng)絡(luò)上下載的jar或二進制)的jar及目錄、還可以在加載前
對class文件優(yōu)一些動作,如解密、編碼等。
很多資料和文章里說,ExtClassLoader的父類加載器是BootStrapClassLoader,其實這里省掉了一句話,容易造成很多新手(比如我)的迷惑。嚴格來說,ExtClassLoader的父類加載器是null,
只不過在默認的ClassLoader 的 loadClass 方法中,當(dāng)parent為null時,是交給BootStrapClassLoader來處理的,而且ExtClassLoader 沒有重寫默認的loadClass方法,所以,
ExtClassLoader也會調(diào)用BootStrapLoader類加載器來加載,這就導(dǎo)致“BootStrapClassLoader具備了ExtClassLoader父類加載器的功能”
查看classloader的源碼可以發(fā)現(xiàn)三個重要的方法:
a) loadClass。classloader加載類的入口,此方法負責(zé)加載指定名字的類,ClassLoader的實現(xiàn)方法為先從已經(jīng)加載的類中尋找,如沒有則繼續(xù)從父ClassLoader中尋找,
如仍然沒找到,則從BootstrapClassLoader中尋找,最后再調(diào)用findClass方法來尋找,如要改變類的加載順序,則可覆蓋此方法,如加載順序相同,則可通過覆蓋findClass來做特殊的處理,
例如解密、固定路徑尋找等,當(dāng)通過整個尋找類的過程仍然未獲取到Class對象時,則拋出ClassNotFoundException。如類需要 ,則調(diào)用resolveClass進行鏈接。
b) findClass。此方法直接拋出ClassNotFoundException,因此需要通過覆蓋loadClass或此方法來以自定義的方式加載相應(yīng)的類。
C) defineClass。此方法負責(zé)將二進制的字節(jié)碼轉(zhuǎn)換為Class對象,這個方法對于自定義加載類而言非常重要,如二進制的字節(jié)碼的格式不符合JVM Class文件的格式,拋出ClassFormatError;如需要生成的類名和二進制字節(jié)碼中的不同,則拋出NoClassDefFoundError;如需要加載的class是受保護的、采用不同簽名的或類名是以java.開頭的,則拋出SecurityException;如需加載的class在此ClassLoader中已加載,則拋出LinkageError。
類的加載的過程
一個java文件從被加載到被卸載這個生命過程
加載->鏈接(驗證+準備+解析)->初始化(使用前的準備)->使用->卸載
類的加載全過程
加載->驗證->準備->解析->初始化
1,首先是加載:
這一塊虛擬機要完成3件事:
1.通過一個類的全限定名來獲取定義此類的二進制字節(jié)流。
2.將這個字節(jié)流所代表的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運行時數(shù)據(jù)結(jié)構(gòu)。
3.在java堆中生成一個代表這個類的java.lang.Class對象,作為方法區(qū)這些數(shù)據(jù)的訪問入口。
關(guān)于第一點,很靈活,很多技術(shù)都是在這里切入,因為它并沒有限定二進制流從哪里來:
從class文件來->一般的文件加載
從zip包中來->加載jar中的類
從網(wǎng)絡(luò)中來->Applet
2,加載完成后就要開始對那些字節(jié)流進行檢驗
檢驗的目的:確保class文件的字節(jié)流信息符合jvm的口味,不會讓jvm感到不舒服。
檢驗主要經(jīng)歷幾個步驟:文件格式驗證->元數(shù)據(jù)驗證->字節(jié)碼驗證->符號引用驗證
文件格式驗證:驗證字節(jié)流是否符合Class文件格式的規(guī)范并驗證其版本是否能被當(dāng)前的jvm版本所處理。
ok沒問題后,字節(jié)流就可以進入內(nèi)存的方法區(qū)進行保存了。后面的3個校驗都是在方法區(qū)進行的。
元數(shù)據(jù)驗證:對字節(jié)碼描述的信息進行語義化分析,保證其描述的內(nèi)容符合java語言的語法規(guī)范。
字節(jié)碼檢驗:校驗java編譯成的字節(jié)碼文件是否破損或格式錯誤
符號引用驗證:來驗證一些引用的真實性與可行性,比如代碼里面引了其他類,這里就要去檢測一下那些來究竟是否存在;
或者說代碼中訪問了其他類的一些屬性,這里就對那些屬性的可訪問性進行檢驗。(這一步將為后面的解析工作打下基礎(chǔ))
3,接著就上面步驟完成后,就會進入準備階段了:
這階段會為類變量(指那些靜態(tài)變量)分配內(nèi)存并設(shè)置初始值的階段,這些內(nèi)存在方法區(qū)中進行分配。這里不包含用final修飾的static,因為final在編譯的時候就會分配了
4,完成上步后,就要進行解析了。解析好像是對類的字段,方法等東西進行轉(zhuǎn)換,具體涉及到Class文件的格式內(nèi)容,并沒深入去了解。
5,在前面的類加載過程中,除了在加載階段用戶可以通過自定義類加載器參與之外,其他的動作完全有jvm主導(dǎo),到了初始化這塊,才開始真正執(zhí)行java里面的代碼。
這一步將會執(zhí)行一些預(yù)操作,注意區(qū)分在準備階段,已經(jīng)為類變量執(zhí)行過一次系統(tǒng)賦值了。
其實說白了,這一步就是執(zhí)行程序的構(gòu)造器
GC:
垃圾檢測方式:
引用計數(shù)法:給一個對象添加引用計數(shù)器,每當(dāng)有個地方引用它,計數(shù)器就加1;引用失效就減1。
好了,問題來了,如果我有兩個對象A和B,互相引用,除此之外,沒有其他任何對象引用它們,實際上這兩個對象已經(jīng)無法訪問,即是我們說的垃圾對象。但是互相引用,
計數(shù)不為0,導(dǎo)致無法回收,所以還有另一種方法:
可達性分析算法:以根集對象為起始點進行搜索,如果有對象不可達的話,即是垃圾對象。這里的根集一般包括java棧中引用的對象、方法區(qū)常良池中引用的對象本地方法中引用的對象等。
總之,JVM在做垃圾回收的時候,會檢查堆中的所有對象是否會被這些根集對象引用,不能夠被引用的對象就會被垃圾收集器回收。
回收算法:
1.標記-清除(Mark-sweep)
說明:算法和名字一樣,分為兩個階段:標記和清除。標記所有需要回收的對象,然后統(tǒng)一回收。這是最基礎(chǔ)的算法,后續(xù)的收集算法都是基于這個算法擴展的。
不足:效率低;標記清除之后會產(chǎn)生大量碎片
2.復(fù)制(Copying)
說明:此算法把內(nèi)存空間劃為兩個相等的區(qū)域,每次只使用其中一個區(qū)域。垃圾回收時,遍歷當(dāng)前使用區(qū)域,把正在使用中的對象復(fù)制到另外一個區(qū)域中。此算法每次只處理正在使用中的對象,因此復(fù)制成本比較小,同時復(fù)制過去以后還能進行相應(yīng)的內(nèi)存整理,不會出現(xiàn)“碎片”問題。
缺點:就是需要兩倍內(nèi)存空間
3.標記-整理(Mark-Compact)
說明:此算法結(jié)合了“標記-清除”和“復(fù)制”兩個算法的優(yōu)點。也是分兩階段,第一階段從根節(jié)點開始標記所有被引用對象,第二階段遍歷整個堆,把清除未標記對象并且把存活對象“壓縮”到堆的其中一塊,按順序排放。此算法避免了“標記-清除”的碎片問題,同時也避免了“復(fù)制”算法的空間問題
缺點:
4.分代收集算法
說明:
這是當(dāng)前商業(yè)虛擬機常用的垃圾收集算法。分代的垃圾回收策略,是基于這樣一個事實:不同的對象的生命周期是不一樣的。因此,不同生命周期的對象可以采取不同的收集方式,以便提高回收效率。
為什么要運用分代垃圾回收策略?
在java程序運行的過程中,會產(chǎn)生大量的對象,因每個對象所能承擔(dān)的職責(zé)不同所具有的功能不同所以也有著不一樣的生命周期,有的對象生命周期較長,比如Http請求中的Session對象,
線程,Socket連接等;有的對象生命周期較短,比如String對象,由于其不變類的特性,有的在使用一次后即可回收。試想,在不進行對象存活時間區(qū)分的情況下,每次垃圾回收都是對整
個堆空間進行回收,那么消耗的時間相對會很長,而且對于存活時間較長的對象進行的掃描工作等都是徒勞。因此就需要引入分治的思想,所謂分治的思想就是因地制宜,將對象進行代的
劃分,把不同生命周期的對象放在不同的代上使用不同的垃圾回收方式。

小編推薦一個學(xué)Java的學(xué)習(xí)裙【 六五零,五五四,六零七 】,無論你是大牛還是小白,是想轉(zhuǎn)行還是想入行都可以來了解一起進步一起學(xué)習(xí)!裙內(nèi)有開發(fā)工具,很多干貨和技術(shù)資料分享!
如何劃分?
將對象按其生命周期的不同劃分成:年輕代(Young Generation)、年老代(Old Generation)、持久代(Permanent Generation)。其中持久代主要存放的是類信息,所以與java對象的回收關(guān)
系不大,與回收息息相關(guān)的是年輕代和年老代。這里有個比喻很形象
“假設(shè)你是一個普通的 Java 對象,你出生在 Eden 區(qū),在 Eden 區(qū)有許多和你差不多的小兄弟、小姐妹,可以把 Eden 區(qū)當(dāng)成幼兒園,在這個幼兒園里大家玩了很長時間。
Eden 區(qū)不能無休止地放你們在里面,所以當(dāng)年紀稍大,你就要被送到學(xué)校去上學(xué),這里假設(shè)從小學(xué)到高中都稱為 Survivor 區(qū)。開始的時候你在 Survivor 區(qū)里面劃分出來
的的“From”區(qū),讀到高年級了,就進了 Survivor 區(qū)的“To”區(qū),中間由于學(xué)習(xí)成績不穩(wěn)定,還經(jīng)常來回折騰。直到你 18 歲的時候,高中畢業(yè)了,該去社會上闖闖了。于是你
就去了年老代,年老代里面人也很多。在年老代里,你生活了 20 年 (每次 GC 加一歲),最后壽終正寢,被 GC 回收。有一點沒有提,你在年老代遇到了一個同學(xué),他的名
字叫愛德華 (慕光之城里的帥哥吸血鬼),他以及他的家族永遠不會死,那么他們就生活在永生代?!?/p>
年輕代:是所有新對象產(chǎn)生的地方。年輕代被分為3個部分——Enden區(qū)和兩個Survivor區(qū)(From和to)當(dāng)Eden區(qū)被對象填滿時,就會執(zhí)行Minor GC。并把所有存活下來的對象轉(zhuǎn)移到其中
一個survivor區(qū)(假設(shè)為from區(qū))。Minor GC同樣會檢查存活下來的對象,并把它們轉(zhuǎn)移到另一個survivor區(qū)(假設(shè)為to區(qū))。這樣在一段時間內(nèi),總會有一個空的survivor區(qū)。
經(jīng)過多次GC周期后,仍然存活下來的對象會被轉(zhuǎn)移到年老代內(nèi)存空間。通常這是在年輕代有資格提升到年老代前通過設(shè)定年齡閾值來完成的。需要注意,Survivor的兩個區(qū)是
對稱的,沒先后關(guān)系,from和to是相對的。涉及了復(fù)制算法
年老代:在年輕代中經(jīng)歷了N次回收后仍然沒有被清除的對象,就會被放到年老代中,可以說他們都是久經(jīng)沙場而不亡的一代,都是生命周期較長的對象。對于年老代和永久代,就不能再采用
像年輕代中那樣搬移騰挪的回收算法,因為那些對于這些回收戰(zhàn)場上的老兵來說是小兒科。通常會在老年代內(nèi)存被占滿時將會觸發(fā)Full GC,回收整個堆內(nèi)存。涉及了“標記-整理(Mark-Sweep)”的算法。
持久代:用于存放靜態(tài)文件,比如java類、方法等。持久代對垃圾回收沒有顯著的影響。
-- *************************************三年以上程序員 end****************************************
-- **************************************************************************************************
-- *************************************五年以上程序員 begin****************************************
-- **************************************************************************************************
簡要說明oracle數(shù)據(jù)庫是如何執(zhí)行SQL語句的。
一、 基本階段
當(dāng)用戶執(zhí)行SQL語句(這里主要值數(shù)據(jù)操縱語言DML)時,通過連接,先將該語句發(fā)送到oracle服務(wù)器,再由服務(wù)器進程處理該語句。
服務(wù)器進程處理SQL語句的基本階段是:解析、執(zhí)行、返回結(jié)果。
1、解析(perse)
解析指檢查SQL語句的語法和語義,生成SQL語句的執(zhí)行計劃,并將SQL語句和執(zhí)行計劃存放到SGA區(qū)的共享SQL區(qū)中。
在解析期間服務(wù)器進程會執(zhí)行如下操作:
1)搜索SGA區(qū)的共享SQL區(qū),檢查其中是否存在相同的SQL語句及其執(zhí)行計劃。如果有,則直接執(zhí)行該SQL語句。這樣能夠提高oracle的性能
如果沒有該SQL語句,就檢查該SQL的語法。如果語法不正確,就將語法錯誤消息返回給客戶機
2)如果語法正確,就通過查詢數(shù)據(jù)字典,檢查該SQL語句的語義,以確定表名、列名是否正確。如果表名和列名不正確,就將語義錯誤消息返回給客戶機
3)如果語義正確,就給相應(yīng)的對象加解析鎖,以防止在解析期間其他用戶改變這些對象的結(jié)構(gòu)(或刪除這些對象)
4)檢查用戶是否具有訪問相應(yīng)對象的相應(yīng)權(quán)限。如果沒有相應(yīng)權(quán)限,就將權(quán)限不夠錯誤消息返回給客戶機,如果具有相應(yīng)的權(quán)限,
就由SQL語句的優(yōu)化器來確定該SQL語句的最佳執(zhí)行計劃,為該SQL語句在SGA區(qū)的共享SQL區(qū)中分配空間,將該SQL語句及其執(zhí)行計劃裝入其中,以便執(zhí)行
2、 執(zhí)行(execute)
執(zhí)行指服務(wù)器進程按照SQL語句的執(zhí)行計劃執(zhí)行SQL語句。在此期間,服務(wù)器進程執(zhí)行如下操作:
1,確定被操縱對象的數(shù)據(jù)所在的數(shù)據(jù)塊是否已經(jīng)被讀取到SGA區(qū)的數(shù)據(jù)高速緩存區(qū)中了。如果數(shù)據(jù)塊在數(shù)據(jù)高速緩存中,則直接在其中操作
2,如果數(shù)據(jù)塊不在數(shù)據(jù)高速緩存中,則從數(shù)據(jù)文件所對應(yīng)的物理存儲設(shè)備中讀取該數(shù)據(jù)塊,并在數(shù)據(jù)高速緩存中尋找空閑數(shù)據(jù)塊,將讀入的數(shù)據(jù)放入
3,對于update和delete語句,將需要修改或刪除的行鎖住,以便在事務(wù)結(jié)束之前相同的行不會被其他進程修改。對于select和insert語句,因為不會修改數(shù)據(jù),所以不需要鎖住行。
3、 返回結(jié)果
對于select語句,在執(zhí)行階段,要將查詢到的結(jié)果(或被標示的行)返回給用戶進程。加入查詢結(jié)果需要排序,還要利用共享池的排序區(qū),甚至臨時表空間的臨時段來排序。查詢結(jié)果總是以列表格式顯示。根據(jù)查詢結(jié)果的大小不同,可以一次全部返回,也可以分多次逐步返回。對于其他DML語句,將執(zhí)行是否成功等狀態(tài)細心返回給用戶進程。
-- *************************************五年以上程序員 end****************************************
-- **************************************************************************************************
-- *************************************必問問題 begin****************************************
-- **************************************************************************************************
說說你最近有什么計劃吧;
這個嘛,是一個不錯的問題啊,我呢,是搞技術(shù)的,也只想在技術(shù)方向走向輝煌;為此呢,我專門做了一些準備:
1,一直呢,聽說spring是java程序員學(xué)習(xí)的典范,最想研究一下spring,Spring是于2003 年興起的一個輕量級的Java 開發(fā)框架,它能夠活到現(xiàn)在而沒有被時間所打死,這足以證明它有足夠的魅力誘惑那一群饑渴難耐的程序員,終于呢,我這個一向清高的小哥也淪陷了;其源碼設(shè)計的精妙,結(jié)構(gòu)清晰,及java設(shè)計模式的靈活運用,以及對java技術(shù)的高深造詣,都是我學(xué)習(xí)的典范,其IOC主從關(guān)系的轉(zhuǎn)變,讓我想到好萊塢的一句話,“別找我們,我們會找你的,你等著哈”,如果不是spring,也許我還在陷入永無止境的new Objec()的苦海深淵中
2,我還買了一些其他的書籍,mysql的從入門到精通,不要問我作者是誰,我看書從來不問出處,也懶的看,平??吹胶軣o聊的電視節(jié)目的時候,我遙控器都懶得拿,sql基本程序員必備技能,但是如何快速寫出高效的sql是一個值得學(xué)習(xí)的問題
3,學(xué)完這些,大概也過了小半年了吧,接下來干什么呢,唉喲,這就是個問題了,sql學(xué)習(xí)了,spring研究的差不多了,自己該寫點東西,練練手了吧,光看不練,來裝逼的嗎?
4,練習(xí)之后,該干嘛了啊,嗯,分布式,緩存,事多著呢,沒幾年,估計也別想再技術(shù)上面有什么發(fā)展,提什么走向輝煌,恩哼
說說你遇到的問題:
1, 問題描述:
短信驗證碼被別人惡意刷,當(dāng)時我們這個東西,加的是有驗證碼的,且后端對手機號格式,發(fā)送頻率都有校驗(每分鐘最多六次),
但是還是出現(xiàn)了被惡意刷的問題,幾個小時,兩千塊的短信費就沒了,查看后臺才知道,手機號沒有重復(fù)的
解決方案:
原來也考慮過 判斷 手機 mac ip,在實施過程中,才知道手機上網(wǎng)是隨機分配網(wǎng)絡(luò)地址的,是沒有固定的IP的,
于是采用了另一種方案,數(shù)據(jù)加密,數(shù)據(jù)組包組完以后 對數(shù)據(jù)加密 然后再組包,相當(dāng)于 多了一層,然后就沒有問題了
你還有想問的嗎?
1,公司現(xiàn)在做什么業(yè)務(wù)?進展到哪里了?
2,福利待遇?
3,公司人員怎么分配的,幾個前端,幾個后臺?
-- *************************************必問問題 end****************************************
-- **************************************************************************************************
-- *************************************常問問題 begin****************************************
-- **************************************************************************************************
索引建設(shè)原則:
1、索引應(yīng)該經(jīng)常建在Where 子句經(jīng)常用到的列上。如果某個大表經(jīng)常使用某個字段進行查詢,并且檢索行數(shù)小于總表行數(shù)的5%。則應(yīng)該考慮。
2、對于兩表連接的字段,應(yīng)該建立索引。如果經(jīng)常在某表的一個字段進行Order By 則也經(jīng)過進行索引。
3、不應(yīng)該在小表上建設(shè)索引。
Sql 優(yōu)化:
當(dāng)Oracle數(shù)據(jù)庫拿到SQL語句時,其會根據(jù)查詢優(yōu)化器分析該語句,并根據(jù)分析結(jié)果生成查詢執(zhí)行計劃。
也就是說,數(shù)據(jù)庫是執(zhí)行的查詢計劃,而不是Sql語句。
查詢優(yōu)化器有rule-based-optimizer(基于規(guī)則的查詢優(yōu)化器) 和Cost-Based-optimizer(基于成本的查詢優(yōu)化器)。
其中基于規(guī)則的查詢優(yōu)化器在10g版本中消失。
對于規(guī)則查詢,其最后查詢的是全表掃描。而CBO則會根據(jù)統(tǒng)計信息進行最后的選擇。
1、先執(zhí)行From ->Where ->Group By->Order By
2、執(zhí)行From 字句是從右往左進行執(zhí)行。因此必須選擇記錄條數(shù)最少的表放在右邊。這是為什么呢?
3、對于Where字句其執(zhí)行順序是從后向前執(zhí)行、因此可以過濾最大數(shù)量記錄的條件必須寫在Where子句的末尾,而對于多表之間的連接,則寫在之前。
因為這樣進行連接時,可以去掉大多不重復(fù)的項。
4. SELECT子句中避免使用(*)ORACLE在解析的過程中, 會將’*’ 依次轉(zhuǎn)換成所有的列名, 這個工作是通過查詢數(shù)據(jù)字典完成的, 這意味著將耗費更多的時間
5、索引失效的情況:
① Not Null/Null 如果某列建立索引,當(dāng)進行Select * from emp where depto is not null/is null。 則會是索引失效。
② 索引列上不要使用函數(shù),SELECT Col FROM tbl WHERE substr(name ,1 ,3 ) = 'ABC'
或者SELECT Col FROM tbl WHERE name LIKE '%ABC%' 而SELECT Col FROM tbl WHERE name LIKE 'ABC%' 會使用索引。
③ 索引列上不能進行計算SELECT Col FROM tbl WHERE col / 10 > 10 則會使索引失效,應(yīng)該改成
SELECT Col FROM tbl WHERE col > 10 * 10
④ 索引列上不要使用NOT ( != 、 <> )如:SELECT Col FROM tbl WHERE col ! = 10
應(yīng)該 改成:SELECT Col FROM tbl WHERE col > 10 OR col < 10 。
6、用UNION替換OR(適用于索引列)
union:是將兩個查詢的結(jié)果集進行追加在一起,它不會引起列的變化。 由于是追加操作,需要兩個結(jié)果集的列數(shù)應(yīng)該是相關(guān)的,
并且相應(yīng)列的數(shù)據(jù)類型也應(yīng)該相當(dāng)?shù)?。union 返回兩個結(jié)果集,同時將兩個結(jié)果集重復(fù)的項進行消除。 如果不進行消除,用UNOIN ALL.
通常情況下, 用UNION替換WHERE子句中的OR將會起到較好的效果. 對索引列使用OR將造成全表掃描. 注意, 以上規(guī)則只針對多個索引列有效.
如果有column沒有被索引, 查詢效率可能會因為你沒有選擇OR而降低. 在下面的例子中, LOC_ID 和REGION上都建有索引.
高效:
SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE LOC_ID = 10
UNION
SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE REGION = “MELBOURNE”
低效:
SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE LOC_ID = 10 OR REGION = “MELBOURNE”
如果你堅持要用OR, 那就需要返回記錄最少的索引列寫在最前面.
7. 用EXISTS替代IN、用NOT EXISTS替代NOT IN
在許多基于基礎(chǔ)表的查詢中, 為了滿足一個條件, 往往需要對另一個表進行聯(lián)接. 在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的效率.
在子查詢中, NOT IN子句將執(zhí)行一個內(nèi)部的排序和合并. 無論在哪種情況下, NOT IN都是最低效的(因為它對子查詢中的表執(zhí)行了一個全表遍歷).
為了避免使用NOT IN, 我們可以把它改寫成外連接(Outer Joins)或NOT EXISTS.
例子:
高效: SELECT * FROM EMP (基礎(chǔ)表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB’)
低效: SELECT * FROM EMP (基礎(chǔ)表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB’)
購物車業(yè)務(wù)分析:
1)添加商品到購物車
a)從cookie中獲取購物車列表
b)判斷:此商品是否在購物車(cookie)存在。
i.如果存在,此商品數(shù)據(jù)庫相加
ii.如果不存在,直接添加
c)把購物車寫回cookie
2)查詢購物車
a)展示購物車列表
3)修改購物車
a)修改購物車商品數(shù)量
b)修改商品價格
4)刪除購物車
任一項目登錄
a)接受頁面用戶名,密碼
b)根據(jù)用戶名查詢數(shù)據(jù)庫
c)校驗此用戶在系統(tǒng)中是否存在,密碼需要進行md5加密校驗
d)校驗成功,登錄成功。需要把用戶身份信息放入redis系統(tǒng)。生成token(我們這個token是用的UUID),token相當(dāng)于SESSION里面jsessionid,token就是redis的key。
e)返回token
f)把token寫入cookie(頂級域名中),實現(xiàn)多系統(tǒng)之間共享。實現(xiàn)了單點登錄。
緊接著其他項目登錄
根據(jù)token查詢redis服務(wù)器用戶身份信息
a)如果cookie沒有token,重新登錄
b)如果cookie中有token,redis服務(wù)器過期,重新登錄
c)登錄,重置redis中用戶身份認證過期時間。
跨域問題:
i.跨服務(wù)(不需要發(fā)請求)
ii.跨域名(需要發(fā)送請求)[表現(xiàn)層與表現(xiàn)層交互]
1.不能接受數(shù)據(jù)(普通Json數(shù)據(jù))
2.接受js代碼(callback(json))
iii.Jsonp(ajax的dataType為jsonp)
網(wǎng)頁靜態(tài)化
為什么網(wǎng)頁靜態(tài)化:使用Freemarker技術(shù),生成靜態(tài)化頁面,用戶不需要訪問后臺服務(wù)器,只需要訪問html頁面即可。訪問只是單純html頁面,只是和存放靜態(tài)化頁面的服務(wù)器有交互,和后臺淘淘商城沒有交互。大大減輕服務(wù)器壓力
秒殺活動技術(shù)挑戰(zhàn):
1,對現(xiàn)有網(wǎng)站業(yè)務(wù)造成沖擊
秒殺只是一個附加活動,具有時間短,并發(fā)大的特點,如果和正常網(wǎng)站放到一塊,可能導(dǎo)致整站癱瘓。
2,高并發(fā)下應(yīng)用和數(shù)據(jù)庫負載
因為用戶會不斷刷新頁面,類似12306搶票,這些請求如果安裝一般網(wǎng)站設(shè)計,對應(yīng)用服務(wù)器和數(shù)據(jù)庫造成極大的負載壓力。
3,網(wǎng)絡(luò)帶寬壓力
假如返回一個頁面是200K,包括HTML和圖片JS等,那么一萬個人訪問就是200K*10000,2G的帶寬流量。這種壓力,做過運維的應(yīng)該清楚。
4,直接下單
秒殺規(guī)則就是開始后才能下單,之前只能瀏覽。下單頁面也是一個URL,如果有人破解,不用秒殺就可以下單了。當(dāng)然,直接下單后后端也必須判斷(這話是我加的)。
秒殺系統(tǒng)應(yīng)對策略
1,秒殺系統(tǒng)獨立部署
蜂擁而至的用戶訪問,如果秒殺系統(tǒng)沒有獨立部署,會拖垮整個網(wǎng)站。一般我們的Java系統(tǒng)都是分布式部署,這里的獨立部署不是簡單的把特定請求指向特定服務(wù)器,我們甚至可以用二級域名來處理。
2,頁面靜態(tài)化
一般我們做java的,頁面就是JSP,但是每個JSP都是動態(tài)生成HTML的,如果按照這個思維做秒殺網(wǎng)站,光JSP就能干掉自己的網(wǎng)站。不過現(xiàn)在互聯(lián)網(wǎng)網(wǎng)站前端都是PHP的,JSP也只有內(nèi)部系統(tǒng)用了。但是瀏覽器需要的就是一個HTML,我們在服務(wù)器放一個靜態(tài)頁面,不用任何程序處理。
3,租借秒殺活動網(wǎng)絡(luò)帶寬
服務(wù)器帶寬對外網(wǎng)的話,其實是很貴的。所有之前有很多虛擬空間來做網(wǎng)站,大家公用帶寬,節(jié)省資本。在比如我的論壇,雖然是獨立服務(wù)器,但帶寬其實很坑的。這里就要和運營商合作,甚至我們可以把靜態(tài)頁面放到CDN。
4,動態(tài)的下單URL
為了防止用戶直接下單,下單URL應(yīng)該是動態(tài)生成的,而且只有在活動開始的時候外層才能知道。
秒殺系統(tǒng)架構(gòu)涉及
1,如何控制商品頁面購買按鈕點亮
購買按鈕在活動開始的時候才能點擊,在此之前是灰色。如果頁面是動態(tài)的,那么可以在活動開始的時候改變這個頁面,但是上面也說了,頁面都存到CDN了,請求不會到應(yīng)用服務(wù)器。
方法是用JS控制,在靜態(tài)頁面引入一個JS,JS文件中有是否開始的標記,和下單的URL。這個JS文件不被瀏覽和CDN和反向代理緩存。該文件還要非常小,避免對集群服務(wù)器造成帶寬壓力。
2,如果允許第一個提交的訂單能下單
如果能秒殺成功的只有一個人,那么提交訂單的時候,就得檢查是否有訂單提交。所以要控制下單頁面入口,只有少數(shù)用戶能進入下單頁面,其他直接進入活動結(jié)束頁面,和秒殺頁面一樣就是一個簡單HTML。
以上,是別人書上說的,大體意思是這樣的,我稍加修改讓意思更明了。
那么其實他說的是整體思想,如果涉及到實現(xiàn)的時候,主要還是要看活動開始后,下單時這個搶的動作。
資源數(shù)量是特定的,大家都來搶了,怎么保證只有前幾個能搶到呢?這里就涉及到了線程的問題,我面試的時候竟然說了用消息隊列,往隊列里面放特定數(shù)量消息,客戶端消費完了就是搶光了。其實這是有問題的,這和消息隊列的特性有關(guān),另外這個時候效率也會有問題。
后來我又想了一下,簡述一下我的思路。
有兩個標量,1:是否開始。2:當(dāng)前資源數(shù)量。3:是否結(jié)束。
剛才說的是JS級別控制了開始,那么其實在網(wǎng)站的后臺,請求來了以后也要判斷是否開始,防破解。另外要判斷是否結(jié)束,從這里把運氣不好的用戶擋住。
如果活動是開始有效的,請求一個特定的接口,接口是線程安全的。
接口首先判斷是否有資源,沒有返回空,并設(shè)置活動結(jié)束。如果有則獲取并把資源數(shù)量減一,返回該資源。
那么此時一個問題,該接口是線程安全的,大量用戶訪問的時候會不會堵塞?
因為這個接口的處理是足夠快的,另外部分用戶在是否結(jié)束判斷時擋住了,我認為不會堵塞住。
框架就是別人說的那么回事,搶的這個操作,我想的是這樣的。當(dāng)然不一定是最好的方案,都說了是探討。
FastDFS是一個開源的分布式文件系統(tǒng),她對文件進行管理,功能包括:文件存儲、文件同步、文件訪問(文件上傳、文件下載)等,解決了大容量存儲和負載均衡的問題。特別適合以文件
為載體的在線服務(wù),如相冊網(wǎng)站、視頻網(wǎng)站等等。
FastDFS服務(wù)端有兩個角色:跟蹤器(tracker)和存儲節(jié)點(storage)。跟蹤器主要做調(diào)度工作,在訪問上起負載均衡的作用。
FastDFS架構(gòu)包括 Tracker server和Storage server。客戶端請求Tracker server進行文件上傳、下載,通過Tracker server調(diào)度最終由Storage server完成文件上傳和下載。
Tracker server作用是負載均衡和調(diào)度,通過Tracker server在文件上傳時可以根據(jù)一些策略找到Storage server提供文件上傳服務(wù)??梢詫racker稱為追蹤服務(wù)器或調(diào)度服務(wù)器。
Storage server作用是文件存儲,客戶端上傳的文件最終存儲在Storage服務(wù)器上,Storage server沒有實現(xiàn)自己的文件系統(tǒng)而是利用操作系統(tǒng) 的文件系統(tǒng)來管理文件??梢詫torage稱為存儲服務(wù)器。
如下圖:
Tracker 集群
FastDFS集群中的Tracker server可以有多臺,Tracker server之間是相互平等關(guān)系同時提供服務(wù),Tracker server不存在單點故障??蛻舳苏埱骉racker server采用輪詢方式,如果請求的tracker無法
提供服務(wù)則換另一個tracker。
Storage集群
Storage集群采用了分組存儲方式。storage集群由一個或多個組構(gòu)成,集群存儲總?cè)萘繛榧褐兴薪M的存儲容量之和。一個組由一臺或多臺存儲服務(wù)器組成,組內(nèi)的Storage server之間是平等關(guān)系,
不同組的Storage server之間不會相互通信,同組內(nèi)的Storage server之間會相互連接進行文件同步,從而保證同組內(nèi)每個storage上的文件完全一致的。一個組的存儲容量為該組內(nèi)存儲服務(wù)器容量最
小的那個,由此可見組內(nèi)存儲服務(wù)器的軟硬件配置最好是一致的。
采用分組存儲方式的好處是靈活、可控性較強。比如上傳文件時,可以由客戶端直接指定上傳到的組也可以由tracker進行調(diào)度選擇。一個分組的存儲服務(wù)器訪問壓力較大時,可以在該組增加存儲服
務(wù)器來擴充服務(wù)能力(縱向擴容)。當(dāng)系統(tǒng)容量不足時,可以增加組來擴充存儲容量(橫向擴容)。
**********************************************************************************************************************************
*****前端*****前端*******前端*****前端*****前端*****前端*****前端*****前端*****前端*****前端****前端****前端****前端****前端******
**********************************************************************************************************************************
前端都用過什么框架?
jquery,easyUI,boostrap(面試官問:"就這些嗎?","是的,因為我主要做一些傳統(tǒng)項目,都是一些老的項目,技術(shù)什么的都比較老,像easyui當(dāng)時就是很新穎的框架了")

小編推薦一個學(xué)Java的學(xué)習(xí)裙【 六五零,五五四,六零七 】,無論你是大牛還是小白,是想轉(zhuǎn)行還是想入行都可以來了解一起進步一起學(xué)習(xí)!裙內(nèi)有開發(fā)工具,很多干貨和技術(shù)資料分享!
jquery都有哪些方法?
val(),html(),css(),addClass(),hide(),show(),append()[追加方法],live()[追加方法],toggle()【切換方法】,find(),each(),parent()[父親輩分的],parents()[父親的父親,爺爺輩分的]
next(),prev()[上一個同級元素],siblings()【方法返回被選元素的所有同胞元素】,first()[獲取元素列表的第一個元素],last()[獲取元素列表的最后一個元素],eq()【返回被選元素中帶有指定索引號的元素】
attr()【獲取屬性】,text()
css有哪些選擇器?
類選擇器,ID選擇器,標簽選擇器
-------------------last updated time is 2017-03-12 by yangwenxue,soon,and continue to update-------------------


