說說你對緩存的理解?
1.使用緩存的目的:
提高應用程序的性能,減少到數據庫的訪問次數,
舉個簡單應用場景,比如微信群聊,當服務器收到一條消息的時候,需要把消息插入數據庫。
最原始的做法,就是每當有一條聊天記錄到達服務器的時候,就進行一次數據庫的插入操作。如果不考慮服務器帶寬,這種情況下數據庫的每秒io次數約等於每秒聊天記錄插入的次數。
換一種實現思路,用redis做緩存,消息到達服務器的時候,並不是立刻插入數據庫,而是存在redis里。當redis聊天記錄到達60條的時候,再執行1次數據庫插入操作。
這樣子,粗略估計,服務器性能就提高了60倍
2.緩存的介質(緩存的存儲位置)
內存:臨時性存儲空間 存取數據快 減少網絡通信量
硬盤:永久性存儲空間 存取速度慢
3.緩存的分類
客戶端緩存:瀏覽器 cookie
服務器緩存:oscache,redis,memcache,session
4.緩存什么樣的數據?
經常訪問,又不經常修改的數據
5.緩存的有效性
為了避免臟數據的產生,要刷新緩存,這時就用到了事務為了避免頁面顯示問題,需要更新緩存和數據庫保證一致性
6.臟數據
如果緩存中的數據和數據庫中的數據不一致,那么緩存中的數據就被稱之為臟數據
臟讀: 一個事務讀到另一個事務未提交的數據
7.刷新緩存的方式
手動刷新:寫程序的時候調用指定的代碼清除緩存數據
定時刷新:當到達緩存過期時間后,會自動刷新數據
8.緩存的層次(一般我們將緩存加載service中)
jsp-->action-->service-->dao
緩存越靠前對性能的提高越大
9.緩存的清除策略:(緩存空間不足需要進行清理的時候使用)
LRU:最近最少使用原則.(理解:存儲書)
FIFO:先進先出的緩存策略.(理解:排隊)
10.什么時候使用緩存的清除策略?
當緩存中的數據已滿,又有新的數據進來時,執行緩存的清除策略
2.你對Maven是怎么理解的?
Maven兩個重點:根據Maven的約定由於配置了四個文件的文件名必須是固定的,還有一個loge日志的名字也是固定的,這樣不需要去加載這些文件直接通過Maven的約定由於配置自動加載好
還有根據maven的依賴管理在pom.xml中配置jar與這個jar包相關的jar包自動配置好
我當時是怎么配置maven的通過在服務端中setting 中配置這個mirror鏡像配置訪問nexus的訪問路徑
這樣我們就可以通過pom.xml先到我們的本地去找,如果本地倉庫找不到在去maven私服去找如果私服找不到在去外網下載使用maven這樣可以提高我們的開發效率與節省了下載帶寬,以及jar包的重用性。
3.Spring MVC中的注解你都用過哪些,SpringMVC的運行原理是什么?
@Controller:使其普通的java類充當控制層的作用。
@RequestMapping:有兩個參數 url 代表要訪問的路徑 method請求方式
@Service::使其java類充當service層。
@Repository::使其java類充當持久層。Er4
@Resource:默認按照名字注入指定的bean。
@Autowired:默認按照類型進行注入可以結合@Qualifier("bean的的名字 名字")使使其按照名字進行注入。他是 其按照名字進行注入。他是Spring中的注解。
@RespsonceBody:將controller的方法返回的對象通過適當的轉換器轉換為指定個時候將其輸出(通常適用於返回json/xml)
@RequestParam
作用:1.在文件上傳時注解 @requestParam 后跟multilpartFile屬性
2.接收指定參數名的參數並對方法中的參數賦值並且可以設置默認值
我對Spring MVC的理解和運用。
我們通常使用Spring MVC來充當我們項目中的控制層,我們控制層的作用就是接受前台傳遞的參數,調用業務邏輯層進行業務處理以及將返回的結果集返回前台進行展示,首先我們要在web.xml中配置Spring MVC的前端總控制器DispatcherServlet並加載Spring MVC的配置文件,我們在Controller層上加上@Controller注解,使其充當控制層,並且要在Spring mvc的配置文件中通過component-scan對Controller層進行掃描從而使類中的@Controller注解生效,Spring mvc用方法來接收參數,所以我們說Spring mvc是基於方法的設計,我們也可以通過@PathVariable從路徑中獲取信息,我們通常通過@Resource這個注解來進行Bean注入,他是java中的注解,而不是Spring中的,默認是按照屬性名進行注入,我們也可以通過設置name屬性的值,讓其只能按照屬性名進行注入,我們也可以用@Autowired注解來進行Bean的注入,他默認是按照類型進行注入,如果要按屬性名進行注入我們需要結合@Qualifier注解使其按照名字進行注入,我們可以將返回值的類型改為ModelAndView並在配置文件中配置視圖解析器的前綴和后綴,以此來給我們前台頁面傳遞數據,也可以在方法中通過ModelMap進行返回數據。也可以通過@ResponseBody將返回的實體類或者實體類的集合轉換為指定的格式進行前台頁面交互。並且要在配置文件中進行相關的配置。@RequestMapping是將Url映射到具體的方法上。文件上傳時我們通過@RequestParam來接收前台上傳的文件。以上就是我對Spring MVC的理解和運用。
4.SSH整合的流程/SSI整合的流程/SSM整合的流程?
SSH整合的流程
在項目中首先是通過在web.xml中配置strtus2的前端控制器filterDispatcher加載struts.xml
配置文件並對指定的后綴名進行攔截,並且通過配置spring的監聽器contextLoadListener
加載spring的相關配置文件如
spring-service.xml,spring-dao.xml,spring-common.xml,
之后新建控制層的類繼承於BaseAction,而BaseAction繼承於ActionSupport,
在BaseAction中封裝了常用的方法如getRealPath(),outJson()等,
之后控制層注入service層,service層注入dao,dao層繼承於HibernateDaoSupport
並注入spring-common.xml中配置的sessionFactory,sessionFactory注入dataSource連接數據庫,
注入hibernate.cfg.xml從而加載hbm.xml文件,
除此之外還通過Spring中的Aop配置了事務並且通過切點表達式對Servcie層代碼進行控制。
======================================================================SSM整合的流程
在項目中通過在web.xml配置springMVC的核心控制器DispatcherServlet
並加載Spring-mvc-controller.xml,並且通過配置Spring的監聽器contextLoaderListener
加載spring-common.xml,之后新建控制層並在類上加入@Controller和@RequestMapping注解,
並通過@Resouce注入service層,在
service的實現類上加入@Service注解並通過@Autowired注入dao層,
dao層只有接口並沒有實現類,
是通過在mybatis中對應的含有sql語句的xml文件中來通過namespace指明要實現的dao層的接口,
並使sql語句的id和dao層接口中的方法名一致從而明確調用指定dao層接口時要執行的sql語句。
並且在spring-mvc-controller.xml中配置了component-scan對controller
進行掃描從而使控制層的注解生效還配置了內部視圖解析器從而在控制層進行頁面跳轉時加上指定的前綴和后綴,
在spring-common.xml中配置了dbcp數據庫連接池以及sqlSession來加載mapper下所有的xml
並對所有的mapper層進行掃描也就是對dao層的掃描,
還通過Aop中的切點表達式對service層進行事務控制,並且對service層進行掃描使其注解生效。
5.談談你對Spring的理解?
Spring 是完全面向接口的設計,降低程序耦合性,主要是事務控制並創建bean實例對象。在ssh整合時,充當黏合劑的作用。IOC(Inversion of Control) 控制反轉/依賴注入,又稱DI(Dependency Injection) (依賴注入)
IOC的作用:產生對象實例,所以它是基於工廠設計模式的
Spring IOC的注入
通過屬性進行注入,通過構造函數進行注入,
注入對象數組 注入List集合
注入Map集合 注入Properties類型
Spring IOC 自動綁定模式:
可以設置autowire按以下方式進行綁定
按byType只要類型一致會自動尋找,
按byName自動按屬性名稱進行自動查找匹配.
AOP 面向方面(切面)編程
AOP是OOP的延續,是Aspect Oriented Programming的縮寫,
意思是面向方面(切面)編程。
注:OOP(Object-Oriented Programming ) 面向對象編程
AOP 主要應用於日志記錄,性能統計,安全控制,事務處理(項目中使用的)等方面。
Spring中實現AOP技術:
在Spring中可以通過代理模式來實現AOP
代理模式分為
靜態代理:一個接口,分別有一個真實實現和一個代理實現。
動態代理:通過代理類的代理,接口和實現類之間可以不直接發生聯系,而 可以在運行期(Runtime)實現動態關聯。
動態代理有兩種實現方式,可以通過jdk的動態代理實現也可以通過cglib
來實現而AOP默認是通過jdk的動態代理來實現的。jdk的動態代理必須要有
接口的支持,而cglib不需要,它是基於類的。
Spring AOP事務的描述:
在spring-common.xml里通過<aop:config>里面先設定一個表達式,設定對service里那些方法 如:對add* ,delete*,update*等開頭的方法進行事務攔截。我們需要配置事務的傳播(propagation="REQUIRED")特性,通常把增,刪,改以外的操作需要配置成只讀事務(read-only="true").只讀事務可以提高性能。之后引入tx:advice,在tx:advice引用 transactionManager(事務管理),在事務管理里再引入sessionFactory,sessionFactory注入 dataSource,最后通過<aop:config>引入txAdvice。
Spring實現ioc控制反轉描述:
原來需要我們自己進行bean的創建以及注入,而現在交給
spring容器去完成bean的創建以及注入。
所謂的“控制反轉”就是 對象控制權的轉移,
從程序代碼本身轉移到了外部容器。
官方解釋:
控制反轉即IoC (Inversion of Control),
它把傳統上由程序代碼直接操控的對象的調用權交給容器,
通過容器來實現對象組件的裝配和管理。
所謂的“控制反轉”概念就是對組件對象控制權的轉移,
從程序代碼本身轉移到了外部容器。
6.HashMap和HashTable的區別?
1.Map是一個以鍵值對存儲的接口。Map下有兩個具體的實現,分別是HashMap和HashTable.
2.HashMap是線程非安全的,HashTable是線程安全的,所以HashMap的效率高於HashTable.
3.HashMap允許鍵或值為空,而HashTable不允許鍵或值為空.
7.HashMap的底層原理?(源代碼)
HashMap底層就是一個數組結構,數組中的每一項又是一個鏈表。
當新建一個HashMap的時候,就會初始化一個數組。
Entry就是數組中的元素,每個 Entry 其實就是一個key-value對,
它持有一個指向下一個元素的引用,這就構成了鏈表。
HashMap 在底層將 key-value 當成一個整體進行處理,這個整體就是一個 Entry 對象。
HashMap 底層采用一個 Entry[] 數組來保存所有的 key-value 對,
當需要存儲一個 Entry 對象時,會根據hash算法來決定其在數組中的存儲位置,
再根據equals方法決定其在該數組位置上的鏈表中的存儲位置;當需要取出一個Entry時,
也會根據hash算法找到其在數組中的存儲位置,
再根據equals方法從該位置上的鏈表中取出該Entry。
8.jre,jdk,jvm的區別?
Jdk【Java Development ToolKit】就是java開發工具箱, JDK是整個JAVA的核心里邊包含了jre,它除了包含jre之外還包含了一些javac的工具類,把java源文件編譯成class文件,java文件是用來運行這個程序的,除此之外,里邊還包含了java源生的API,java.lang.integer在rt的jar包里邊【可以在項目中看到】,通過rt這個jar包來調用我們的這些io流寫入寫出等
JDK有以下三種版本:
J2SE,standard edition,標准版,是我們通常用的一個版本
J2EE,enterpsise edtion,企業版,使用這種JDK開發J2EE應用程序
J2ME,micro edtion,主要用於移動設備、嵌入式設備上的java應用程序
Jre【Java Runtime Enviromental】是java運行時環境,那么所謂的java運行時環境,就是為了保證java程序能夠運行時,所必備的一基礎環境,也就是它只是保證java程序運行的,不能用來開發,而jdk才是用來開發的,所有的Java程序都要在JRE下才能運行。
包括JVM和JAVA核心類庫和支持文件。與JDK相比,它不包含開發工具——編譯器、調試器和其它工具。
Jre里邊包含jvm
Jvm:【Java Virtual Mechinal】因為jre是java運行時環境,java運行靠什么運行,而底層就是依賴於jvm,即java虛擬機,java虛擬機用來加載類文件,java中之所以有跨平台的作用,就是因為我們的jvm
關系:
J2se是基於jdk和jre,
JDK是整個JAVA的核心里邊包含了jre,
Jre里邊包含jvm
9.Set,List,Collection,Collections的區別?
1.List和Set都是接口,他們都繼承於接口Collection,List是一個有序的可重復的集合,而Set的無序的不可重復的集合。Collection是集合的頂層接口,Collections是一個封裝了眾多關於集合操作的靜態方法的工具類,因為構造方法是私有的,所以不能實例化。
2.List接口實現類有ArrayList,LinkedList,Vector。ArrayList和Vector是基於數組實現的,所以查詢的時候速度快,而在進行增加和刪除的時候速度較慢LinkedList是基於鏈式存儲結構,所以在進行查詢的時候速度較慢但在進行增加和刪除的時候速度較快。又因為Vector是線程安全的,所以他和ArrayList相比而言,查詢效率要低。
10.系統管理的描述?
我負責項目中的系統管理模塊,其中包含用戶管理,菜單管理以及給用戶賦角色,給角色賦權限;涉及到的表有用戶表,角色表,用戶角色關聯表,菜單表,角色菜單關聯表。在菜單管理模塊采用ztree進行菜單的增刪改查操作,為了將權限控制到按鈕級別我們在進行菜單管理時會設置該菜單是屬於按鈕級別還是普通菜單,通過在數據庫中增加一個type類型的字段來實現,如type為1則是普通菜單,type為2則是按鈕菜單。
這樣用戶在登錄的時候根據用戶名和密碼到用戶表驗證信息是否合法,如果合法則獲取用戶信息,之后根據用戶id再到用戶角色關聯表中得到相關聯的角色id集合,之后根據角色id集合再到角色權限關聯表中獲取該角色所擁有的權限id集合,然后再根據權限id集合到權限表(菜單表)中獲取具體的菜單,展現給當前登錄用戶,從而達到不同用戶看到不同的菜單權限。
為了防止用戶不登錄而直接訪問后台資源我通過在項目中加入LoginInterceptor攔截器對未經認證的用戶進行攔截,如果未經認證則跳轉到登錄頁面使用戶再次登錄,除此之外還加入了PermissionInterceptor攔截器來對用戶無權訪問的資源進行攔截,如果無訪問權限則跳轉到沒rr4有訪問權限的頁面。
再者考慮到性能將用戶登錄后所擁有的資源權限通過OScache結合單例設計模式將數據存儲到了緩存中,這樣可以避免每次操作都需要重新進行查詢的代價,減少和數據庫的交互次數,提高系統性能。考慮到單例的設計模式在多線程中會出現線程安全的問題,所以就給單例加了雙重判斷鎖,從而避免該問題的發生。
11.抽象類和接口的區別?
共同點:
- 都可以寫抽象方法
- 都不能被實例化對象
- 類繼承抽象類需要重寫抽象方法,類實現接口也必須重寫抽象方法
不同點
- 類和接口是兩個不同的概念,抽象類是由abstract修飾的類;接口不是類,用interface定義
- 接口中只能有抽象方法,抽象類中既可以有抽象方法,又可以有普通方法
- 類是單繼承多實現,實現一個抽象類,需要繼承.實現接口需要implements
- 接口定義的變量默認是public static final的,而抽象類沒有這個限制
12.Get和Post的區別?
1.get是從服務器上獲取數據,post是向服務器傳送數據,
2.get傳送的數據量較小,不能大於2KB。post傳送的數據量較大,一般被默認為不受限制。
3.get安全性非常低,post安全性較高。但是執行效率卻比Post方法好。
4.在進行文件上傳時只能使用post而不能是get。
5.不明確是post請求的都是get請求
13.Redirect和Forward的區別?
1、從數據共享上
Forword是一個請求的延續,可以共享request的數據
Redirect開啟一個新的請求,不可以共享request的數據
2、從地址欄
Forword轉發地址欄不發生變化
Redirect轉發地址欄發生變化
14.Http協議的理解?
HTTP是一個超文本傳輸協議,屬於OSI七層模型的應用層,由請求和響應構成,
是一個標准的客戶端服務器模型。HTTP是無狀態的也就是說同一個客戶端的這次請求和上次請求是沒有對應關系。
http的工作流程:
當發送一個http請求時,首先客戶機和服務器會建立連接,
之后發送請求到服務器,請求中包含了要訪問的url地址,請求的方式(get/post),
以及要傳遞的參數和頭信息,服務器接到請求后會進行響應,
包括狀態行,狀態碼,響應頭,以及要響應的主體內容。客戶端接收
到請求后將其展示到瀏覽器上然后斷開和服務器端的連接。
簡單說就是:建立連接--》發送請求--》響應--》斷開連接
15.長連接和短連接?
在HTTP/1.0中,默認使用的是短連接。也就是說,瀏覽器和服務器每進行一次HTTP操作,就建立一次連接,
但任務結束就中斷連接。
從 HTTP/1.1起,默認使用長連接,用以保持連接特性。使用長連接的HTTP協議,會在響應頭有加入這行代碼:
Connection:keep-alive
在使用長連接的情況下,當一個網頁打開完成后,客戶端和服務器之間用於傳輸HTTP數據的 TCP連接不會關閉,
如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接。
Keep-Alive不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如Apache)中設定這個時間。
實現長連接要客戶端和服務端都支持長連接。
HTTP協議的長連接和短連接,實質上是TCP協議的長連接和短連接。
16.你對jquery的理解?
jquery是一個輕量級的js框架,具有跨瀏覽器的特性,兼容性好,
並且封裝了很多工具,方便使用。
常用的有: 選擇器 ,dom操作 ,ajax(ajax不能跨域) ,特效,工具類
17.事務的概述?
在數據庫中,所謂事務是指一組邏輯操作單元即一組sql語句。當這個單元中的一部分操作失敗,整個事務回滾,只有全部正確才完成提交。
判斷事務是否配置成功的關鍵點在於出現異常時事務是否會回滾
事務的ACID屬性
1. 原子性(Atomicity)
原子性是指事務是一個不可分割的工作單位,事務中的操作要么都發生,
要么都不發生。
2. 一致性(Consistency)
事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態。(數據不被破壞)
3. 隔離性(Isolation)
事務的隔離性是指一個事務的執行不能被其他事務干擾.
4. 持久性(Durability)
持久性是指一個事務一旦被提交,
它對數據庫中數據的改變就是永久性的.即使系統重啟也不會丟失.
在JDBC中,
事務默認是自動提交的,
每次執行一個 SQL 語句時,如果執行成功,
就會向數據庫自動提交,而不能回滾
為了讓多個 SQL 語句作為一個事務執行:
(1)執行語句前調用 Connection 對象的 setAutoCommit(false);
以取消自動提交事務
(2)在所有的 SQL 語句都成功執行后,調用 commit(); 方法提交事務
(3)在出現異常時,調用 rollback(); 方法回滾事務。
18.索引的概述?
1、索引的概念
索引就是為了提高數據的檢索速度。
數據庫的索引類似於書籍的索引。
在書籍中,索引允許用戶不必翻閱完整個書就能迅速地找到所需要的信息。
在數據庫中,索引也允許數據庫程序迅速地找到表中的數據,
而不必掃描整個數據庫.
2、索引的優點
1.創建唯一性索引,保證數據庫表中每一行數據的唯一性
2.大大加快數據的檢索速度,這也是創建索引的最主要的原因
創建索引默認排序 如果索引和主鍵 順序相同 則不用排序
3.減少磁盤IO(向字典一樣可以直接定位)
3、索引的缺點
1.創建索引和維護索引要耗費時間,這種時間隨着數據量的增加而增加
2.索引需要占用額外的物理空間
3.當對表中的數據進行增加、刪除和修改的時候,
索引也要動態的維護,降低了數據的維護速度
4、索引的分類
1.普通索引和唯一性索引
普通索引:CREATE INDEX mycolumn_index ON mytable (myclumn)
唯一性索引:保證在索引列中的全部數據是唯一的
CREATE unique INDEX mycolumn_index ON mytable (myclumn)
2. 單個索引和復合索引
單個索引:對單個字段建立索引
復合索引:又叫組合索引,在索引建立語句中同時包含多個字段名,
最多16個字段
CREATE INDEX name_index ON userInfo(firstname,lastname)
3.順序索引,散列索引,位圖索引
19.三層分頁的SQL語句?(手寫)
首先不考慮查詢條件 先寫分頁語句 在寫條件
1.例如:河北省不滿18周歲的男的4,5,6條信息
select * from
(select t.* ,rownum rn from
(select id,name, age,sex from t_student where name="河北" and age<18 and sex="男") t
where rownum <= 6)
where rn >=4
2.女生年齡從高到低排序 每頁3條 查詢第3條
select * from
(select t.*,rownum rn from
(select id,name,age from t_student order by age desc) t
where rownum <= 9)
where rn>=7
20.數據庫三范式?
第一范式(1NF):強調的是列的原子性,即列不能夠再分成其他幾列。
第二范式(2NF): 首先是滿足第一范式,另外包含兩部分內容,一是表必須有一個主鍵;二是沒有包含在主鍵中的列必須完全依賴於主鍵,而不是部分依賴。
第三范式(3NF): 首先滿足第二范式,非主鍵列直接依賴於主鍵,消除傳遞依賴。
21.id,rowid,rownum的區別?
rowid物理位置的唯一標識。
而id是邏輯上的唯一標識,所以rowid查找速度要快於id,是目前最快的
定位一條記錄的方式
rowid和rownum都是"偽數列"
所謂“偽數列”也就是默認隱藏的一個數列。
rownum用於標記結果集中結果順序的一個字段,
它的特點是按順序標記,而且是連續的,
換句話說就是只有有rownum=1的記錄,才可能有rownum=2的記錄。
rownum關鍵字只能和<或者<=直接關聯
如果是>或者=則需要給他0起個別名
22.單例設計模式?(手寫)
單例就是該類只能返回一個實例(實例只會創建一次)
單例所具備的特點:
1.私有的構造函數
2.私有的靜態的全局變量
3.公共的靜態的方法
雙重鎖定式
public class Singleton {
private Singleton(){};
private static Singleton single;
public static Singleton getInstance(){
if(null ==single){
Synchronized(single){
if(null == single){
single = new Singleton();
}
}
}
return single;
}
}
23.主鍵和唯一索引的區別?
在創建主鍵的同時會生成對應的唯一索引,主鍵在保證數據唯一性的同時不允許為 空,而唯一可以有一個為空數據項,一個表中只能有一個主鍵,但是一個主鍵可以 有多個字段,一個表中可以有多個唯一索引。
24.數據庫連接池運行原理?
數據庫連接池的優點運行原理:
在我們不使用數據庫連接池的時候,每次訪問數據庫都需要創建連接,
使用完成之后需要釋放關閉連接,而這樣是很耗費資源的。當我們使用
數據庫連接池的時候,在tomcat啟動的時候就創建了指定數量的連接,
之后當我們程序使用的時候就直接從連接池里面取,而不需要創建,同理,
當我們使用完的時候也不需要關閉連接,而是將連接返回到連接池中,供
其他請求繼續使用。
DBCP:比較穩定。
C3P0: 性能比較高。
25.jdbc,ibatis,hibernate的區別?
Hibernate屬於全自動, Ibatis屬於半自動,Jdbc屬於手動,從開發效率上講hibernate較高,ibatis居中,jdbc較低,從執行效率上講hibernate較低,ibatis居中,jdbc較高,因為jdbc是手工寫sql語句,程序員對sql的控制能力更大,可以根據業務需要進行優化,而ibatis雖然也可以對sql進行優化,但是他里面將resultset封裝為實體的過程中采用了反射機制所以一定程度上影響了性能,而hibernate因為高度封裝所以開發效率相對較高,但正因為這個原因,所以程序員在對sql語句的控制和優化方面相對比較弱,而且在將resultset封裝成實體的過程中也采用了反射機制,所以在性能方面較低
26.SQL優化?
外鍵必須加索引。
避免在 where 子句中對有索引的字段進行運算,這會導致索引失效,從而進行全表掃描。
在 where 及 order by 涉及的列上建立索引,要盡量避免全表掃描。
在設計表時要避免表中字段出現null的情況,通常要為其設置默認值。
避免在查找時放棄使用索引而進行全表掃描。
SELECT語句中避免使用'*’,只查詢需要返回的字段 ,這樣可以減少oracle解析sql語句的時間。
用NOT EXISTS 替換 NOT IN 操作符,用 EXISTS 替換 IN
27.Java代碼優化?
解析大文件的xml
數據使用sax替代dom4j,使用分段批量提交來完成大數據量的插入。
對於大批量字符串的拼接使用stringbuffer或者stringbuilder代替string進行+拼接。
根據業務情況使用緩存減少對數據庫的訪問。
單線程應盡量使用 HashMap, ArrayList,因為HashTable,Vector使用了同步機制,降低了性能。
在finally塊中關閉流,斷開連接,釋放資源。
避免在循環條件中使用復雜表達式 。
28.Hibernate優化?
3.Hibernate優化:
在處理大數據量時,會有大量的數據緩沖保存在Session的一級緩存中,這緩存大太時會嚴重顯示性能,所以在使用Hibernate處理大數 據量的,可以使用session. clear()或者session. evict(Object) ,在處理過程中,清除全部的緩存或者清除某個對象。
通過使用Hibernate的一級緩存,二級緩存,查詢緩存等來提高性能 (必須)
Hibernate可以通過設置hibernate.jdbc.fetch_size,hibernate.jdbc.batch_size等屬性,對Hibernate進行優化。
Batch Size是設定對數據庫進行批量刪除,批量更新和批量插入的時候的批次大小,Batch Size越大和數據庫交互的次數就越少,速度就越快, 但也不要無限的大下去,通常選擇一個合適的值,如100條;其次我們在進行大批量數據的導入操作時,可以結合batchsize進行分段批量提交,從而達到最優效果。
29.數據庫優化?(被動說)
數據庫優化:作為開發人員最主要是從sql語句的優化方面考慮的,對於數據庫底層的優化,是由DBA完成的。
在我們公司里面做項目的時候,在開發過程中最主要是由程序員對java代碼以及sql語句這方面進行優化,至於數據庫 底層的優化,則由DBA在項目基本結尾進行壓力測試的時候參與進來,通過對數據庫的分析,確定影響性能的sql語句以及相關的表,通過和我們進行交流然后對其進行適當的改進。
30.MySQL優化?【慢日志,分表,sql執行計划】
慢日志就是在我們設置的時間內執行慢的語句可以在慢日志看到!
2.分表:
時間划分 地區划分
水平划分 垂直划分(把平常經常使用的提取出來加上索引)
3.在mysql中通過explain查看執行計划
31.Freemarker靜態化?
在做XX電商項目的時候,考慮到提高網站前台的性能,承受更大的並發,我們將網站首頁和很多文章頁面都進行了靜態化。當時采用的方式是通過freemarker模板引擎和spring定時器來結合完成的。前台美工通過網站管理后台用freemarker編寫首頁模板以及相關的樣式,之后將模板信息存入模板表,我負責編寫spring定時器在每晚的凌晨從數據庫中的模板表中取出各種類型的模板並和相關的數據結合起來生成靜態的html頁面。並且考慮到減少前台美工編寫freemarker標簽的難度,我將經常用到的一些功能像分頁,列表展示等通過#macro編寫為freemarker的宏命令,方便前台美工直接使用。對於及時性要求比較高的特別熱門的頻道,則在用戶點擊發布時直接調用編寫的接口通過freemarker和數據結合生成html靜態頁面。
32.Redis分布式緩存?
redis是一個基於key,value的支持多種數據類型(String,List,Set,zSet,Hash)的可進行持久化的內存數據庫。我們在項目中通常使用redis來充當緩存服務器來緩存分類列表,品牌列表,熱銷商品,推薦商品以及該商品的關聯商品等等。以前做項目的時候,我們是把商品的信息存放在redis里面,redis支持多種數據類型,有兩種方法存儲對象:1,可以把對象序列化進行存儲,然后反序列化取出。2.用hash結構存儲,最后發現,還是用hash存取比較快
當時我們就是在redis中設置maxmemory【最大內存】,把maxmemory-policy【數據清除策略】設置為allkeys-lru。為了保證redis不會因為占用內存過大而導致系統宕機,也會設置最大內存和數據清除策略。使用了jedis作為客戶端,並考慮到性能問題使用了jedis連接池。考慮到redis服務器的高可用性,我們做了redis的主從復制,剛開始配置redis的時候,我是關閉它的保護模式,雖然實現了功能,但是不安全,最后是在redis.conf配置文件中綁定具體的ip地址,這樣只有該ip地址才能訪問redis服務器,並且設置長度為20位左右的密碼,從而保證只有進行了密碼授權才能進行相關的操作,為了信息安全,我們配置了redis的主從復制,在從服務器的配置文件中通過配置slaveof綁定主服務器的ip地址和端口號,
當設置好slave服務器后,slave會建立和master的連接,然后發送sync命令。無論是第一次同步建立的連接還是連接斷開后的重新連接,master都會啟動一個后台進程,將數據庫
快照保存到文件中,同時master主進程會開始收集新的寫命令並緩存起來。后台進程完成寫文件后master就發送文件給slave,slave將文件保存到磁盤上,然后加載到內存恢復數據庫快照到slave上。接着master就會把緩存的命令轉發給slave。而且后續master收到的寫命令都會通過開始建立的連接發送給slave。從master到slave的同步數據的命令和從 client發送的命令使用相同的協議格式。當master和slave的連接斷開時slave可以自動重新建立連接。如果master同時收到多個slave發來的同步連接命令,只會使用啟動一個進程來寫數據庫鏡像,然后發送給所有slave。
哨兵要監視 Redis 服務器,就必須連接 Redis 服務器。啟動哨兵的時候需要指定一個配置文件,程序初始化的時候會讀取這個配置文件,獲取被監視 Redis 服務器的 IP 地址和端口等信息。
哨兵連接redis服務器發送兩個連接一個是普通連接,另一個是訂閱發布專用連接。哨兵在初始化訂閱發布連接的時候,做了兩個工作:一是,向 Redis 服務器發送 SUBSCRIBE SENTINEL_HELLO_CHANNEL命令;二是,注冊了回調函數 sentinelReceiveHelloMessages()。
哨兵會向 hello 頻道發送包括:哨兵自己的IP 地址和端口,runid,當前的配置版本;其所監視主機的 IP 地址,端口,當前的配置版本。【這里要說清楚,什么是 runid 和配置版本】雖然未知的信息很多,但我們可以得知,當一個哨兵新加入到一個 Redis 集群中時,就能通過 hello 頻道,發現其他更多的哨兵,而它自己也能夠被其他的哨兵發現,哨兵向與 Redis 服務器的命令連接通道上,發送了一個INFO 命令(字符串);並注冊了回調函數sentinelInfoReplyCallback()。Redis 服務器需要對 INFO 命令作出相應,能在 redis.c 主文件中找到 INFO 命令的處理函數:當 Redis 服務器收到INFO命令時候,會向該哨兵回傳數據,包括:
關於該 Redis 服務器的細節信息,rRedis 軟件版本,與其所連接的客戶端信息,內存占用情況,數據落地(持久化)情況,各種各樣的狀態,主從復制信息,所有從機的信息,CPU 使用情況,存儲的鍵值對數量等。
由此得到最值得關注的信息,所有從機的信息都在這個時候曝光給了哨兵,哨兵由此就可以監視此從機了。
Redis 服務器收集了這些信息回傳給了哨兵,剛才所說哨兵的回調函數 sentinelInfoReplyCallback()會被調用,它的主要工作就是着手監視未被監視的從機;完成一些故障修復(failover)的工作。連同上面的一節,就是Redis 的 auto discover 的全貌了。
在哨兵的定時程序中,哨兵會向所有的服務器,包括哨兵服務器,發送 PING 心跳,而哨兵收到來自 Redis 服務器的回應后,也會更新相應的時間點或者執行其他操作,哨兵不僅僅憑借自己的信息,還依據其他哨兵提供的信息判斷 Redis 服務器是否下線的方法稱為客觀方法,即通過所有其他哨兵報告的主機在線狀態來判定某主機是否下線。
一個 Redis 集群難免遇到主機宕機斷電的時候,哨兵如果檢測主機被大多數的哨兵判定為下線,就很可能會執行故障修復,重新選出一個主機。一般在 Redis 服務器集群中,只有主機同時肩負讀請求和寫請求的兩個功能,而從機只負責讀請求,從機的數據更新都是由之前所提到的主從復制上獲取的。因此,當出現意外情況的時候,很有必要新選出一個新的主機。
優選選擇優先級高的從機
優先選擇主從復制偏移量高的從機,即從機從主機復制的數據越多
優先選擇有 runid 的從機
如果上面條件都一樣,那么將 runid 按字典順序排序
並且通過加入哨兵來使redis主服務器宕機時,從服務器自動轉換為主服務器繼續提供服務。
33.jdbc操作數據庫的步驟?
①加載數據庫驅動程序(Class.forName("數據庫驅動類");)
②連接數據庫(Connection con = DriverManager.getConnection();)
③操作數據庫(PreparedStatement stat = con.prepareStatement(sql);stat.executeQuery();)
④關閉數據庫,釋放連接(con.close();)
34.悲觀鎖,樂觀鎖?
悲觀鎖/樂觀鎖:
悲觀鎖(Pessimistic Lock), 每次去查詢數據的時候都認為別人會修改,
所以每次在查詢數據的時候都會上鎖,這樣別人想拿這個數據就會阻塞直到它拿到鎖。
傳統的關系型數據庫里邊就用到了這種鎖機制,比如通過select ....for update進行數據鎖定。
樂觀鎖(Optimistic Lock), 每次去查詢數據的時候都認為別人不會修改,
所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,
可以使用版本號,時間戳等機制。樂觀鎖適用於多讀的應用類型,這樣可以提高吞吐量。
35.Spring中事務的隔離級別,傳播特性?
spring中事務的傳播特性好像有5個左右,
我做項目的時候使用最多的就是PROPAGATION_REQUIRED,
它所代表的意思支持當前事務,如果當前沒有事務,就新建一個事務。
spring中事務的隔離級別有5個,默認使用的是ISOLATION_DEFAULT,
它代表使用數據庫默認的事務隔離級別,也是我們項目中最常使用的。
除此之外還有
讀未提交:
它充許另外一個事務可以看到這個事務未提交的數據,
這種隔離級別會產生臟讀,不可重復讀和幻像讀。
讀提交:
保證一個事務修改的數據提交后才能被另外一個事務讀取,
也是大多數數據庫的默認值。可以避免臟讀,但會產生不可重復讀和幻像讀。
重復讀:
在一個事務內兩次讀到的數據是不一樣的,因此稱為是不可重復讀。
串行化:
順序執行事務。除了防止臟讀,不可重復讀外,還避免了幻像讀。
並發性也最低,但最安全。
不可重復讀的重點是修改 :
同樣的條件 , 你讀取過的數據 , 再次讀取出來發現值不一樣了 。
幻讀的重點在於新增或者刪除 :
同樣的條件 , 第 1 次和第 2 次讀出來的記錄數不一樣。
36.MongoDB概述?
mongodb是一個nosql數據庫,我們在項目中通常用它來存儲評論信息,
【評論id,商品id,標題,評分,內容,評論人信息,評論的發布時間】
因為每個商品都會有評論信息,而且某些熱門商品的評論信息可能是數千條,
mongodb正好適用於這種大數據量、高並發、弱事務的互聯網應用。考慮
到mongodb的高可用性我們搭建了3台mongodb數據庫來實現副本集,這樣
不僅可以達到故障自動轉移的特性而且也可以通過讀寫分離提高性能,即便
主服務器宕機了,還會通過投票選舉出下一個主服務器繼續提供服務。
再者考慮到我們的項目最后要部署到多台tomcat通過nginx來實現負載均衡,
為了對項目中的文件以及圖片進行統一的管理,我們就用mongodb來充當文件服務器。
對於大部分的單張圖片和單個文件來說小於16M,所以我們就以常規的方式來將
文件轉換為二進制的字節數組進行保存。考慮到高可用性以及為了應對后期隨着文件數量的不斷
增加而能夠方便進行擴容,我們建立了3個分片並將分片和副本集做了整合,每個分片都是一個副本集,這樣
不僅滿足了大數據量的存儲也避免了分片中單台機器導致的單點故障問題。考慮到可能要處理
大於16M的文件,所以又增加了支持大文件存儲的gridfs,這樣即便再大的文件也會被gridfs分解為多個
chunk進行存儲。
37.Easyui概述?
我們在項目中通常用EasyUI來充當展示層,因為它是一個RIA富客戶端框架,
自身提供了很多功能強大的插件,可以提高用戶的體驗度而且也有助於我們
開發人員直接使用,提高開發效率。我們在項目中使用到的EasyUI插件有Layout布局,
EasyUI的tree,Tab頁面,datagrid,form表單,Dialog對話框,Messager提示信息還有
Accordion手風琴效果,progress進度條等。
EasyUI的tree的生成方式有兩種,一種是通過一條sql語句查詢所有的菜單信息,
然后在java中通過遞歸的方式將其拼裝成符合指定json格式的數據,這種適用
於數據量比較小的情況,通過減少數據庫的訪問次數提高性能, 另一種是通過
ajax異步加載的方式,每點擊一下樹節點就向后台發送一次請求,從而來獲取
該節點下的子節點,這種適用於數據量比較大的情況。這時候如果采用取出全
部數據遞歸拼裝的話就有可能出現內存溢出。
我們當時在項目中是通過Easyui的tree來生成菜單,考慮到菜單的
數據量也不是特別的大,所以就采用了第一種取出所有數據並遞歸將其
拼裝成指定Json的方式來提高性能,再者考慮到每個用戶的菜單信息並
不是經常改變,所以又結合oscache緩存以及帶有雙重判定鎖的單例模式
將其緩存到內存中,從而再次提高了性能。
在點擊樹形菜單,動態添加tab頁的時候一定要注意,為了避免每次點擊
都添加一個新的tab頁,我們的做法是當點擊事件發生時,先判斷當前
選中的菜單通過exist方法判斷所對應的tab頁是否已經存在,如果存在就select方法將其激活選中,否則
再添加新的。多個tab頁出現的另一個問題就是不同tab頁間的數據可能不
同步,所以我們會在每個tab頁上面都增加一個刷新按鈕,可以通過點擊
該按鈕給該tab頁所對應的iframe的src屬性重新賦值,來起到刷新的作用。
datagrid也是我們在項目中經常使用到的,在使用datagrid時應該注意的是分頁
在拼裝好的json數據中,需要響應有total和rows這兩個屬性,其中total用來
指明數據的總條數,rows用來指明當前頁的數據列表;要從頁面獲取參數page 和rows在前台頁面中要保證
columns中的field和rows中的屬性名相對應,否則數據就展現不出來,而且
對於圖片等制定格式數據的展示需要結合formatter對其進行格式化才能進行
正確的顯示。最后就是在datagrid和form表單結合進行數據查詢時調用的是
load方法,進行增刪改后刷新datagrid調用的是reload方法。
38.BootStrap概述?
Bootstrap是一個支持響應式的Css框架它提供了很多組件,
如導航條,面板,菜單,form表單,還有柵格,
而且他們這些都是支持響應式的,可以在各種
設備上進行完美的展現。這里面我感覺最有價值的就是
bootstrap提供的柵格系統,這個柵格系統將
整個頁面分為12列,而且可以根據屏幕的寬窄進行自動
調節,這也是響應式的關鍵所在。在使用柵格系統的時候
要注意最外層樣式是Container,里面是row,row里面包含
的是列,列里面可以用來填充各種各樣的組件。
我在項目中使用bootstrap完成的情況大概是這個樣子,
首先我使用了bootstrap的導航條,並將其固定在頂部,
使其在拖拉滾動條的時候不至於看不到,
之后在導航條的下面采用了bootstrap的柵格系統將其分為左右兩部分,
左邊使用bootstrap的Treeview組件,將菜單展現出來,當點擊treeview
上的菜單節點時結合一個第三方的tab組件,將需要展示的內容放到tab頁內,
並進行上下切分,上面使用了bootstrap的form組件,
下面使用了它的響應式表格以及分頁組件,在進行增加修改時,
使用了第三方的bootbox彈出框。
40.你上家公司在哪?你在哪住?你去公司怎么坐車?
北京市海定區阜外亮甲1號中關注聯網創意產業園27號樓 (豐台區)
海淀區藍靛廠 晨月園小區 遠大路公交站上車 355/79/118線都能到 坐六站(定慧北橋下車)走大概5分鍾就到了
公司附近 在那邊有一個豐台科技原生態主題公園
晨月園附近有個巨人學校
從育新坐606路公交到成府路南口下車然后在步行到公司
41.你期望薪資多少?你上家工資多少?稅后拿到手的有多少?扣了多少錢的稅?
15K 14K 13K 1000
42.你哪個學校畢業的?學的什么專業?你們學校校長叫什么名字?你們學校還有啥其他專業嗎?你大學都學了什么?
鄭州理工專修學院 計算機科學與技術 劉信古
有,還有,酒店服務管理 建築工程 行政管理 軌道交通運營 等等。。。
計算機原理 計算機網絡 高級語言 編程語言 操作系統 數據結構
43.你今年多大了?屬相是啥?
26 馬
44.你為啥從上家公司離職?
合同到期,想換一個新的環境,公司這邊也挽留我,但是在公司也呆了,2.3年了,
想換一個新的平台,來不斷提升充實自己。
45.你交社保了嗎?為啥沒交?
在上家公司的時候,人事說咱們公司的五險一金如果要上的話都是從自己工資里面扣的,
當時感覺沒啥必要也就沒上。
46.你的優缺點是啥?
這幾年做程序,因為要不斷的對代碼進行驗證確認,所有感覺自己現在有點強迫症。
47.你的五年規划是啥?
前2,3年繼續加強自己的技術功底,然后朝着項目經理(技術經理,產品經理)方面發展
48.你啥時候上的大學?哪年畢業的?從火車站怎么到你們學校?你們學校周圍都有啥?
2008年9月 2012年6月 下了火車打個車10來塊錢
(吹牛逼的活) 有一些賣衣服的 賣吃的 小超市 酒店什么的....
49.你知道五險一金都是啥嗎?
養老保險,醫療保險,失業保險,工傷保險,生育險 住房公積金
50.你們公司有多少人?你們公司有哪幾個部門?
60人左右 技術部 銷售部 行政部 人力資源部 財務部
51.你對ajax是怎么理解的(融入ajax跨域的解決方案)?
ajax全稱是異步JavaScript及xml;
ajax的核心JavaScript中的xmlHttpRequest(XHR);
使用ajax可以提高用戶的體驗度,進行異步數據傳輸從而提高性能。ajax不能跨域,所謂不能跨域就是不能跨多個網站(多個域名),不能跨多個項目可以通過jsonp來解決ajax跨域的問題,而jsonp的實質就是通過動態添加script標簽來實現的
52.Ajax超時、Ajax同步異步、原生的Ajax
Ajax是默認沒有超時時間,如果我們想要ajax超時在ajax中有一個timeout這個屬性設置它的時間是根據秒來設置
Ajax 異步是跳轉頁面加載一部分數據當點擊按鈕的時候加載另一部分數據這樣的使用於大數據量的加載
Ajax同步 是跳轉頁面一下子執行了說有的ajax請求加載了所有的數據這樣的如果在大量數據中頁面會卡
Ajax中有async屬性 async =”true”是同步flase是異步 默認的是異步
原生的ajax是xmlhttprequest
53.你對webservice是怎么理解的?
(主動說)
webservice是SOA(面向服務編程)的一種實現,
主要是用來實現異構平台通信也就
是不同平台不同項目之間的數據傳輸,從而避免了信息孤島的問題,
它之所以能夠
進行異構平台通信是因為它是完全基於xml的,
所以說,webService是跨平台,
跨語言,跨框架的,在java中通常有三種技術框架分別是xfire,cxf,axis2。
我們為了保證
webservice的安全性,采用了基於
WS-Security標准的安全驗證(使用回調函數)。
(沒必要主動說)
webservice的三要素分別是:
wsdl(webservice description language)
用來描述發布的接口(服務)
soap(simple object access protocol)
是xml和http的結合,是webservice數據通信的協議
uddi 用來管理,查詢webService的服務 3.uddi(查詢和管理webservice)
(沒必要主動說)
webservice的具體三種實現方式(框架)或者三種實現框架的區別
1. Axis2:可以用多種語言開發,
是一個重量級框架,功能非常強大,
但是它的性能比較低。
2. Xfire:它相比Axis2來說是一個輕量級框架,
它的性能要比Axis2高。
3. cxf:是Xfire的升級版,就好比是,
struts2是webwork的升級,
然后cxf和spring集成起來非常方便,簡易,
性能方面也要比Xfire高。
【注】jdk6 自帶的webservice jws
(主動說)
業務場景
我在以前做項目的時候,其中遇到一個功能,
需要進行兩個項目之間的數據的傳輸,
項目經理讓我去完成這個任務,我根據以往的項目經驗,
想到兩種解決方案,第一種
就是開放另外一個項目的數據庫的權限給我,
然后我直接通過訪問另外一個項目的數據
庫,來得到需要的信息,但后來我分析了下,覺的這種方式不安全,
而且因為當時
這個項目是另外一家公司負責在做,所以數據庫里面的表結構,
以及以后牽涉
到的責任問題都很多,所以我就采用了第二種方案,
即通過webservices的方式,進行
異構系統之間數據信息的傳遞,webservices的具體實現,
有xfire,cxf,axis2,
我根據以往的項目經驗,了解到cxf是xfire的升級版本,適用於java語言,
xfire/cxf 性能比axis2要高,並且和spring整合起來也比較方便,
而axis2支持更多的語言,
性能相對於cxf要低,通過上面分析,
結合我們目前的兩個項目都是基於java
語言的,所以我采用cxf這種方式實現了兩個項目之間數據的傳遞,
我們為了保證
webservice的安全性我們采用了基於
WS-Security標准的安全驗證(使用CXF回調函數)。
(沒必要主動說)
webservice服務端配置流程
首先在web.xml中引入cxfServlet核心類,
指定對以/cxf開頭的url路徑提供webservice服務,
之后我們在要發布成webservice接口上添加@Webservice 注解,
而且還要在實現類上添加同樣的webservice注解並且要說明實現了哪個接口,
之后在spring-webservice.xml中發布webservice服務,
需要通過@Test測試此接口方法
通過jaxws:endpoint這個標簽,
並且在標簽配置implementor和address來表明實現服務的類,
以及發布的地址,
最后在瀏覽器中輸入相關的webservice地址?wsdl來驗證服務是否發布成功。
(沒必要主動說)
webservice客戶端的配置
首先通過wsdl2java根據發布的webservice服務端地址的wsdl
生成客戶端調用的中間橋梁java類,
將生成的java類拷貝到客戶端項目中,
配置spring-client.xml文件,
通過jaxws:client定義一個bean,
並通過address屬性指明要訪問的webservice的服務地址,
通過serviceClass指明充當中間橋梁的服務類,之后獲取該bean,
就可以通過它來訪問發布的webservice接口中的方法。
54.你對負載均衡這塊有認識嗎?
負載均衡:
(了解)
我們在做這個項目時,考慮到服務器性能的問題,最開始想到使用縱向擴展,來增加硬件的配置提高其性能,但這樣做比較耗費資金,而且服務器內存空間也是有限的;所以后來就使用橫向擴展來達到這一目的.
(主動說)
當時我們使用nginx(n g 個 s)+3個tomcat進行負載均衡,在我們不進行負載均衡之前,那所有的請求都由一台tomcat進行處理,這樣會使我們的tomcat所承受的壓力增大,而我們進行負載均衡之后,同樣數量的請求經過nginx將其分發到多台tomcat進行處理,從而降低每台tomcat所承受的壓力,而且當其中一台機器宕機時,其他機器還可以繼續提供服務,保證服務不間斷。
當時項目在部署完成后,遇到這么個問題,用戶登錄輸入驗證碼的時候,明明驗證碼輸入的正確,但總是提醒說驗證碼不正確從而不能正常登錄,經過分析后發現有可能第一次
請求被發送到t1上,那么放在session中的驗證碼就被放到了t1上,當用戶輸入驗證碼點擊登錄時,新發送的請求有可能被發送到t2上面,這樣在進行對比時就肯定會不一致從
而提示驗證碼輸入錯誤,后來我就考慮使用ip_hash這種負載均衡策略來代替默認的輪詢策略,雖然解決了驗證碼錯誤問題,但是在后續的測試中發現如果用戶在使用過程中
突然一台服務器宕機了,那么因為session在這台服務器上存儲着,所以就會提示用戶重新登錄,這樣使用戶的體驗度非常不好,最后就通過將session信息保存到redis服務器中從而在
多台web服務器中實現session共享,這樣就解決了上面所說的那些問題。
怎么避免nginx產生單點故障(被動說)
同時我們為了避免nginx的單點故障,達到高可用性,就在nginx的前面又加了一個F5,從而將請求分配給多個nginx,再通過nginx分配給多個不同的Tomcat。這樣大大的提高了服務的有效性,並且進一步提高了性能。
55.你在linux上怎么部署項目?
1.Linux下常見的分支:
CentOS:服務端【純開源】
RedHat:服務器端【收費】
Ubantu:個人電腦
2.訪問方式:通過SSH/Putty客戶端連接服務器
3.如何使用:
1.虛擬機的好處?
可以在虛擬機中隨意操作系統,不怕影響或損害電腦;
2.克隆(備份):快速創建當前系統的備份,快速創建另外一個虛擬系統;
在manage 下的clone中
linked(鏈接克隆) 軟克隆 優點:速度快,生成文件小;
full(完整克隆) 硬克隆 優點:文件大,速度比較慢;
選擇橋接模式;
只查出四行 ping Ip -c 4
3.快照:可以將當前的虛擬系統快速還原到某一時刻;都是一個虛擬系統。
快照 Snapshot 下的 Take Snapshot
快照的好處:埋下幾個點,方便還原
4.命令:
注意:
rpm是Linux下一種軟件安轉包的后綴名。如*。rpm ,等同於windows中的exe.rpm是一個命令,用來進行和軟件安裝相關的操作。(安轉,卸載,查找)
linux下沒有盤符的概念,它是通過相關的目錄來管理資源的。我們通常在/home中創建文件夾來存放需要安轉的軟件
tab鍵自動補全 *代表當前目錄下的所有文件
JDK默認安裝在 usr/java中
設置jdk的環境變量:
修改/etc/profile文件
用文本編輯器打開 /etc/profile
在profile文件末尾加入:
export JAVA_HOME = /usr/java/jdk.1.7.0_79
export PATH = $JAVA_HOME/binL$PATH
source /etc/profile 使修改立即生效
echo $PATH 查看PATH值
56.你對linux中的常用命令都了解哪些?
1.ifconfig:查看IP地址
2.java -version :查jdk的版本
3.rpm -qa | grep 軟件的名稱 :查找和指定名稱相關的軟件
4.rpm -e --nodeps 軟件的名稱 :卸載指定的軟件
5.rpm -ivh 軟件名稱 :安裝指定的軟件
6.uname -a 查看Linux系統的基本信息(計算機名,操作位數,版本號)
7.LL 查看文件夾下的文件
8.mkdir 創建文件夾
9.vi文件名: 對指定的文件名進行編譯。
按i進入編輯模式,
按ESC鍵進入命令模式
:wq! 強制保存並退出
:q!強制退出(!是強制的意思)
10.pwd :查看當前目錄的完整路徑
11.unzip 文件名.zip :解壓后綴名為zip的壓縮文件
zip 文件名.zip 要壓縮的文件
12.mv 源文件 目標文件名(mv可以移動/重命名)
13.rm -rf 文件夾名 :遞歸強制刪除文件夾及其下的文件
14.service iptables stop 禁用防火牆
15.chmod +x *.sh :使所有的后綴名為sh的文件,擁有可執行的權限
16.在bin目錄下 ./startup.sh 啟動tomcat
17.在bin目錄下通過tail -f ../logs/catalina.out 來查看啟動日志 tail -n 300 ../logs/catalina.out 查看最后三百行的信息
18.cat 文件名:查看整個文件內容
19. ps -ef | grep 進程名:查看指定進程是否啟動
20.kill -9 進程號 :強制殺死進程
killall -9 進程名
21. find / -name 文件名 -print :查看指定文件的路徑
vi 在命令模式下 yy復制當前光標所在行
p粘貼
dd 刪除當前行
vi /etc/sysconfig/iptables 更改防火牆的配置文件,開放新的端口號
重啟防火牆 service iptables restart
查看當前防火牆的狀態 service iptables status
export JAVA_HOME = /usr/java/jdk.1.7.0_79
export PATH = $JAVA_HOME/binL$PATH
source /etc/profile 使修改立即生效
echo $PATH 查看PATH值
57.MySQL主從復制 讀寫分離【主動】
我們在項目中的關系型數據庫采用的是MySQL,考慮到對事務的支持使用的是InnoDB引擎,為了保證數據庫數據的安全,達到高可用性,以及分擔服務器壓力我們對MySQL進行了主從復制的配置並結合MyCat這個數據庫中間件進行讀寫分離。我們項目 目前采用的是一主帶2或者3從的架構。因為互聯網項目一般都是讀的多,寫的少,所以通過這種一主多從的架構分擔了單台數據庫的壓力並且在一台服務器宕機的情況下也能保證項目的基本運行。
58.主從復制的配置步驟:【被動】
主從復制的配置比較簡單,最主要是開啟主服務器的二進制日志並指明一個唯一的標識,從服務器也要指明一個唯一的標識,並且在主服務器上創建賬號,開啟復制權限;在主服務器上運行show master status查看主服務器的狀態,之后在從服務器上用剛才建立的賬號連接指定的的主服務器,並指明要復制的二進制文件以及起始位置,最后運行start slave就可以了,然后通常運行show slave status查看從服務器的狀態,如果slave_io和slave_sql為yes,就證明配置成功了。
59.主從復制的運行原理:【被動】
最主要就是主服務器上的二進制日志以及從服務器上的IO線程,SQL線程,以及中繼日志。主服務器將其自身的改變存入到二進制日志中去,從服務器連接主服務器並通過IO線程讀取主服務器上的二進制日志,將讀取的內容存入自身的中繼日志,之后SQL線程會讀取中繼日志中的sql語句對其進行執行,這樣就保證了從服務和主服務器的一致性。MySQL的主從復制默認是基於sql語句進行的。
60.MyCat概述?
61.項目的生命周期
1.需求分析
2.概要設計
3.詳細設計(用例圖,流程圖,類圖)
4.數據庫設計(powerdesigner)
5.代碼開發(編寫)
6.單元測試(junit 白盒測試)(開發人員)
svn版本管理工具(提交,更新代碼,文檔)
7.集成測試 (黑盒測試,loadrunner(編寫測試腳本)(高級測試))
8.上線試運行 (用戶自己體驗)
9.壓力測試(loadrunner)
10.正式上線
11.維護
62.httpClient
httpClient是一個支持http協議的客戶端編程工具包,我們在java中調用httpClient是通過url模擬了一個http請求,這樣就可以通過java代碼直接發送請求獲得服務端響應數據,首先構建HttpClient,new DefaultHttpClient(); httpClient發送請求的方式也分成兩種形式:一個 new httpGet(),一個是new httpPost() 把請求的url放進去,然后用excute發送請求,獲取響應信息,里面包含狀態碼,成功為200,包含響應內容,將內容轉換為字符串,最后關閉連接,其中post請求是模擬表單提交完成的、不能傳遞參數
63.多線程
1.java中實現線程的方式
在java中實現線程有兩種方式:繼承Thread類,實現Runable接口,一個java main程序默認會開啟兩個線程一個是主線程,一個垃圾回收線程。
2.線程不安全與安全:
多個線程訪問同一個資源,導致結果和期望值不同,我們就說它是 非線程安全的(線程不安全),反之我們就說它是 線程安全的。
了解:
a.多個線程訪問同一個資源(這里的資源通常指的是全局變量或者靜態變量),如果每次運行結果和單線程運行的結果是一樣的,就是線程安
全的。
b.線程安全問題都是由全局變量及靜態變量引起的。
c.若每個線程中對全局變量、靜態變量只有讀操作,而無寫操作,一般來說,這個全局變量是線程安全的;
若有多個線程同時執行寫操作,一般都需要考慮線程同步,否則的話就可能影響線程安全。
3.線程的狀態
1、新建狀態(New):新創建了一個線程對象。
2、就緒狀態(Runnable):線程對象創建后,其他線程調用了該對象的start()方法。該狀態的線程位於可運行線程池中,變得可運行,等待獲取CPU的使用權。
3、運行狀態(Running):就緒狀態的線程獲取了CPU,執行程序代碼。
4、阻塞狀態(Blocked):阻塞狀態是線程因為某種原因放棄CPU使用權,暫時停止運行。直到線程進入就緒狀態,才有機會轉到運行狀態。阻塞的情況分三種:
(一)、等待阻塞:運行的線程執行wait()方法,JVM會把該線程放入等待池中。
(二)、同步阻塞:運行的線程在獲取對象的同步鎖時,若該同步鎖被別的線程占用,則JVM會把該線程放入鎖池中。
(三)、其他阻塞:運行的線程執行sleep()或join()方法,或者發出了I/O請求時,JVM會把該線程置為阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉入就緒狀態。
5、死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命周期
了解:
1、線程的實現有兩種方式,一是繼承Thread類,二是實現Runnable接口,但不管怎樣,當我們new了這個對象后,線程就進入了初始
狀態;
2、當該對象調用了start()方法,就進入可運行狀態;
3、進入可運行狀態后,當該對象被操作系統選中,獲得CPU時間片就會進入運行狀態;
4、進入運行狀態后情況就比較復雜了
4.1、run()方法或main()方法結束后,線程就進入終止狀態;
4.2、當線程調用了自身的sleep()方法或其他線程的join()方法,就會進入阻塞狀態(該狀態既停止當前線程,但並不釋放所占有的資
源)。當sleep()結束或join()結束后,該線程進入可運行狀態,繼續等待OS分配時間片;
4.3、線程調用了yield()方法,意思是放棄當前獲得的CPU時間片,回到可運行狀態,這時與其他進程處於同等競爭狀態,O566S有可能會接
着又讓這個進程進入運行狀態;
4.4、當線程剛進入可運行狀態(注意,還沒運行),發現將要調用的資源被synchronized(同步),獲取不到鎖標記,將會立即進入鎖
池狀態,等待獲取鎖標記(這時的鎖池里也許已經有了其他線程在等待獲取鎖標記,這時它們處於隊列狀態,既先到先得),一旦線程獲
得鎖標記后,就轉入可運行狀態,等待OS分配CPU時間片;
4.5、當線程調用wait()方法后會進入等待隊列(進入這個狀態會釋放所占有的所有資源,與阻塞狀態不同),進入這個狀態后,是不能自
動喚醒的,必須依靠其他線程調用notify()或notifyAll()方法才能被喚醒(由於notify()只是喚醒一個線程,但我們由不能確定具體喚醒的
是哪一個線程,也許我們需要喚醒的線程不能夠被喚醒,因此在實際使用時,一般都用notifyAll()方法,喚醒有所線程),線程被喚醒后
會進入鎖池,等待獲取鎖標記。
補充:(wait和sleep的區別)
wait時會釋放鎖資源但sleep不會釋放鎖資源,wait通常和notify以及notifyAll結合使用,需要notify或者notifyAll對其進行喚醒,sleep通常在指定的時間內自動喚醒。
4.解決線程安全的問題的方案:
a.通過加鎖(synchronized)的方式解決線程安全問題
1.synchronized 方法
2.synchronized 塊(同步代碼塊)
b.避免使用全局變量
c.使用ThreadLocal(參考:http://blog.csdn.net/drifterj/article/details/7782706)
1. 為多線程並發的互斥控制提供了另一種全新的解決思路
2. 通過ThreadLocal為其他模塊的API傳遞參數
5.java線程池 (可參考:http://www.oschina.net/question/565065_86540)
1.減少了創建和銷毀線程的次數,
每個線程都可以被重復利用,
可執行多個任務。
2.可以根據系統的承受能力,
調整線程池中線程的數目,
防止因為消耗過多的內存,
而導致服務器宕機
(每個線程需要大約1MB內存,線程開的越多,
消耗的內存也就越大,最后宕機)。
通常我們使用的線程池是實現了ExecutorService的ThreadPoolExecutor。
6.死鎖
死鎖是因為多線程訪問共享資源,由於訪問的順序不當所造成的,通常是一個線程鎖定了一個資源A,而又想去鎖定資源B;在另一個線程
中,鎖定了資源B,而又想去鎖定資源A以完成自身的操作,兩個線程都想得到對方的資源,而不願釋放自己的資源,造成兩個線程都在等
待,而無法執行的情況。
死鎖產生的原因:是由訪問共享資源順序不當所造成的.
簡單的說:所謂死鎖,是指兩個或兩個以上的線程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。
7.守護線程
在Java中有兩類線程:User Thread(用戶線程)、Daemon Thread(守護線程)
java創建的線程對象.
用個比較通俗的比如,任何一個守護線程都是整個JVM中所有非守護線程的保姆:
只要當前JVM實例中尚存在任何一個非守護線程沒有結束,守護線程就全部工作;只有當最后一個非守護線程結束時,守護線程隨着JVM
一同結束工作。
Daemon的作用是為其他線程的運行提供便利服務,守護線程最典型的應用就是 GC (垃圾回收器),它就是一個很稱職的守護者。
User和Daemon兩者幾乎沒有區別,唯一的不同之處就在於虛擬機的離開:如果 User Thread已經全部退出運行了,只剩下Daemon
Thread存在了,虛擬機也就退出了。 因為沒有了被守護者,Daemon也就沒有工作可做了,也就沒有繼續運行程序的必要了。
64AOP——面向切面編程
1.概念以及和oop的比較
2.AOP:面向切面編程
1.AOP是OOP(面向對象編程)的延續,是Aspect Oriented Programming的縮寫,意思是面向方面編程或者面向切面編程。AOP是基於代理模式來實現的。(23種設計模式:工廠模式、代理模式、單例模式、適配器模式、責任鏈模式、裝飾模式,模式的應用場景不是很明確,什么場景用什么模式都是可以理解或解釋的。一個項目並不是運用的模式越多,則代表項目更強大,反而顯得臃腫,復雜度提高了,從而影響代碼的效率、開發人員的開發效率,項目的維護成等)
2.AOP主要應用於日志記錄,性能統計,安全控制,事務處理等方面。它的主要意圖就要將日志記錄,性能統計,安全控制等等代碼從
核心代碼中清楚的划分出來。
3.AOP代理可以通過jdk動態代理實現,也可以通過cglib實現,默認是通過jdk動態代理實現的。jdk動態代理需要接口的支持,如果沒有接口只有類,則使用cglib來實現。
jdk基於接口,cglib基於類
2.Spring AOP基於代理設計模(基於JDK的動態代理)
所謂代理設計模式:在代理模式中有個接口,接口中有個代理實現和一個真實實現,要用代理實現去代表真實實現。
- 靜態代理:
一個接口,分別有一個真實實現和一個代理實現。靜態代理中,真實實現和代理實現都是實現了同一個接口,並且把真實實現作為參數傳遞給代理實現去調用。
缺點:這種模式的代理類只能為一個接口的對象進行代理,這即是靜態代理。要解決這樣的問題,可以采用動態代理。
- 動態代理(基於jdk的動態代理):
使用一個代理類便可以代理所有接口動態代理,通過代理類的代理,接口和實現類之間可以不直接發生聯系,而可以在運行期(Runtime)實現動態關聯,代理實現 都需要實現InvocationHandler接口,這個時候我們需要用到Proxy里面 的newProxyInstance需要有三個參數1.實現類,2.接口3.當前對象
3.AOP中的概念解釋:
1.切面(Aspect): 由切點(PointCut)和通知(Advice)組成,它既包括橫切邏輯的定義,也包括了連接點的定義。
2.切點(Pointcut):一個切點定位多個類中的多個方法。(定義類或者方法的)
3.通知也叫增強(Advice):由方位和橫切邏輯構成,所謂的方位指的是前置通知,后置通知,返回后通知,環繞通知,拋出異常后通知
4.連接點(JoinPoint):由切點和方位構成,用來描述在在哪些類的指定方法之前或之后執行
方位:
<1>.前置通知(Before advice):在某連接點(join point)之前執行的通知,但這個通知不能阻止連接點前的執行(除非它拋出一個異
常)。
<2>.返回后通知(After returning advice):在某連接點(join point)正常完成后執行的通知:例如,一個方法沒有拋出任何異常,正常返回。
<3>.拋出異常后通知(After throwing advice):在方法拋出異常退出時執行的通知。
<4>后置通知(After (finally) advice):當某連接點退出的時候執行的通知(不論是正常返回還是異常退出)。
<5>環繞通知(Around Advice):包圍一個連接點(join point)的通知,如方法調用。這是最強大的一種通知類型。
環繞通知可以在方法調用前后完成自定義的行為。它也會選擇是否繼續執行連接點或直接返回它們自己的返回值或拋出異常來結束執行
66.Java流概述
文件通常是由一連串的字節或字符構成,組成文件的字節序列稱為字節流,組成文件的字符序列稱為字符流。Java中根據流的方向可以分為輸入流和輸出流。輸入流是將文件或其它輸入設備的數據加載到內存的過程;輸出流恰恰相反,是將內存中的數據保存到文件或其他輸出設備,詳見下圖:
文件是由字符或字節構成,那么將文件加載到內存或再將文件輸出到文件,需要有輸入和輸出流的支持,那么在Java語言中又把輸入和輸出流分為了兩個,字節輸入和輸出流,字符輸入和輸出流,見下表:
InputStream(字節輸入流)
InputStream是字節輸入流,InputStream是一個抽象類,所有繼承了InputStream的類都是字節輸入流,主要了解以下子類即可:
主要方法介紹:
| void |
close() |
| abstract int |
read() |
| int |
read(byte[] b) |
| int |
read(byte[] b, int off, int len) |
Reader(字符輸入流)
所有繼承了Reader都是字符輸如流
主要方法介紹
| abstract void |
close() |
| int |
read() |
| int |
read(char[] cbuf) |
| abstract int |
read(char[] cbuf, int off, int len) |
OutputStream(字節輸出流)
所有繼承了OutputStream都是字節輸出流
主要方法介紹
| void |
close() |
| void |
flush() |
| void |
write(byte[] b) |
| void |
write(byte[] b, int off, int len) |
| abstract void |
write(int b) |
示例代碼:
Writer(字符輸出流)
所有繼承了Writer都是字符輸出流
主要方法介紹
| Writer |
append(char c) |
| abstract void |
close() |
| abstract void |
flush() |
| void |
write(char[] cbuf) |
| abstract void |
write(char[] cbuf, int off, int len) |
| void |
write(int c) |
| void |
write(String str) |
| void |
write(String str, int off, int len) |
緩沖流
緩沖流主要是為了提高效率而存在的,減少物理讀取次數,緩沖流主要有:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter,並且BufferedReader提供了實用方法readLine(),可以直接讀取一行,BuffereWriter提供了newLine()可以寫換行符。
BufferedInputStream(字節輸入緩沖流)
BufferedOutputStream(字節輸出緩沖流)
BufferedReader(字符輸入緩沖流)
BufferedWriter(字符輸出緩沖流)
67.從數組中獲取到最大的數據?
方式有很多
(遞歸)
通過先取出數組中的第一個值 然后用for依次循環是數組中的值是否大於第一個值如果大於第一個值 取出在用for循環 循環以后的值 按照這種方式找到數組中最大的值
68.工作流2.0
工作流2.0的定義是:實現工作過程管理的自動化、智能化和整合化。工作流2.0最主要的特征就是可以靈便的實現數據整合和數據統計,消除信息孤島,既能實現OA辦公系統內部工作流之間的數據整合,如借款與報銷、預算與決算等,又能實現OA辦公系統工作流與其他業務系統之間的數據整合,如HR、ERP、CRM等。工作流2.0能徹底的彌補工作流1.0的不足,它不但實現OA辦公系統內部的數據整合,也實現OA辦公系統和第三方應用系統之間的數據整合。
如果給工作流1.0打上標簽的話,那就是“無紙化、重復工作、流程孤島、系統孤島、數據孤島”;工作流2.0對應的便是“智能化、效率質量提升、外部數據整合、消除信息孤島、內部數據整合”。毫無疑問,工作流2.0更加智能,更加整合,能夠實現數據的同步交換和共享的特征更受用戶歡迎,能有效幫助企業簡化多余流程,是未來工作流技術發展的方向。
69.
JVM -- java virtual machine
JVM就是我們常說的java虛擬機,它是整個java實現跨平台的 最核心的部分,所有的java程序會首先被編譯為.class的類文件,這種類文件可 以在虛擬機上執行,也就是說class並不直接與機器的操作系統相對應,而是經過虛擬機間接與操作系統交互,由虛擬機將程序解 釋給本地系統執行。
JVM 是 Java 平台的基礎,和實際的機器一樣,它也有自己的指令集,並且在運行 時操作不同的內存區域。 JVM 通過抽象操作系統和 CPU 結構,提供了一種與平台無關的代碼執行方法,即與特殊的實現方 法、主機硬件、主機操作系統無關。但是在一些小的方面, JVM 的實現也是互不相同的,比如垃圾回收 算法,線程調度算法(可能不同 OS 有不同的實現)。
JVM 的主要工作是解釋自己的指令集(即字節碼)到 CPU 的指令集或 OS 的系統調用,保護用戶免被惡意程序騷擾。 JVM 對上層的 Java 源文件是不關心的,它關注的只是由源文件生成的類文件( class file )。類文件的 組成包括 JVM 指令集,符號表以及一些補助信息。
JRE -- java runtime environment
JRE是指java運行環境。光有JVM還不能成class的 執行,因為在解釋class的時候JVM需要調用解釋所需要的類庫lib。 在JDK的安裝目 錄里你可以找到jre目錄,里面有兩個文件夾bin和lib,在 這里可以認為bin里的就是jvm,lib中則是jvm工 作所需要的類庫,而jvm和 lib和起來就稱為jre。所以,在你寫完java程序編譯成.class之后,你可以把這個.class文件 和jre一起打包發給朋友,這樣你的朋友就 可以運行你寫程序了。(jre里有運行.class的java.exe)
JRE 是 Sun 公司發布的一個更大的系統,它里面就有一個 JVM 。 JRE 就與具體的 CPU 結構和操作系統有關,我們從 Sun 下載 JRE 的時候就看到了不同的各種版本。同 JVM 一起組成 JRE 的還有一些 API (如 awt , swing 等)。 JRE 是運行 Java 程序必不可少的。
JRE ( Java Runtime Environment ),是運行 Java 程序必不可少的(除非用其他一些編譯環境編譯成.exe可執行文件……),JRE的 地位就象一台PC機一樣,我們寫好的Win32應用程序需要操作系統幫 我們運行,同樣的,我們編寫的Java程序也必須要JRE才能運行。
JRE里面有一個 JVM , JRE 與具體的 CPU 結構和操作系統有關,我們從 Sun 下載 JRE 的時候就看到了不同的各種版本,,同 JVM 一起組成 JRE 的還有 一些 API (如 awt , swing 等), JRE 是 運行 Java 程序必不可少的.
JDK -- java development kit
JDK是java開發工具包,基本上每個學java的人都會先在機器 上裝一個JDK,那他都包含哪幾部分呢?讓我們看一下JDK的安裝目錄。在目錄下面有 六個文件夾、一個src類庫源碼壓縮包、和其他幾個聲明文件。其中,真正在運行java時起作用的 是以下四個文件夾:bin、include、lib、 jre。現在我們可以看出這樣一個關系,JDK包含JRE,而JRE包 含JVM。
bin:最主要的是編譯器(javac.exe)
include:java和JVM交互用的頭文件
lib:類庫
jre:java運行環境
(注意:這里的bin、lib文件夾和jre里的bin、lib是 不同的)總的來說JDK是用於java程序的開發,而jre則 是只能運行class而沒有編譯的功能。
eclipse、idea等 其他IDE有自己的編譯器而不是用JDK bin目錄中自帶的,所以在安裝時你會發現他們只要求你 選中jre路徑就ok了。
三者聯系
Java 喊出的帶有標志性的口號“ Write Once , Run Anywhere (一次編寫,到處運行)”,正是建立在 JRE 的基礎之上。何以實現?就是在 Java 應用程序和操作系統之間增加了一虛擬層—— JRE 。
程序源代碼不是直 接編譯、鏈接成機器代碼,而是先轉化到字節碼( bytecode ) 這種特殊的中間形式,字節碼再轉換成機器碼或系統調用。前者是傳統的編譯方法,生成的機器代碼就不可避免地跟特殊的操作系統和特殊的機器結構相關。
而 Java 程序的字節碼文件可以放到任意裝有 JRE 的計算機運行,再由不同 JRE 的將它們轉化成相應的機器代碼,這就實現了 Java 程序的可移植性。這樣程序員也不用去 關心程序運行的具體環境,而可以專心編寫軟件。這種分層抽象、隱藏細節的思想在計算機科學中處處可見,比如機器組織結構的設計、網絡協議的實現等。 Pascal 語言的發明者 Niklaus Wirth ,就富有預見性地指出應該有這樣一種可移植的語言,其生成的中間代碼可以在一台假想的機器( a hypothetical machine )上運行。
而 Java 虛擬機( Java virtual machine 或 JVM )就是這樣的一台機器,它模擬實際處理器的結構,解釋字節碼。 怎么一會說是 JRE ,一會兒又成了 JVM ,兩者是否同物不同名? 回答是否定的。
JRE的地位就象一台PC機一樣,我們寫好的Win32應用程序需要操作系統幫 我們運行,同樣的,我們編寫的Java程序也必須要JRE才能運行。
要運行Applet,在客戶端必須安裝有 JRE,即“運行時”,容易一點理解,就象所謂的“插件”,要開發JAVA應用程序\Web應用,就必須在服務器端安裝相應的 JVM+JDK 了(開發應用 Java web應用 時,客戶端不需要安裝任何的JVM)
如果你使用JAVA開發應用,就需要安裝 JRE+JDK,就是 J2SE.
如果在客戶端運行Applet,客戶端瀏覽器必須嵌有JAVA JVM,如果沒有,就需要安裝,即: 在客戶端創建JRE(運行時,包含JVM),而客戶端是不需要做開發的,所以,JDK就沒有必要安裝 了。
不同版本的Applet在不同的JVM下可能無法正常運行,而Microsoft JVM只是Sun JVM的“低版本”,微軟在windows xp/2003中干脆將JVM去掉了.
StringBuilder和StringBuffer
StringBuilder和StringBuffer都是可變字符串,前者線程不安全,后者線程安全。
StringBuilder和StringBuffer的大部分方法均調用父類AbstractStringBuilder的實現。其擴容機制首先是把容量變為原來容量的2倍加2。最大容量是Integer.MAX_VALUE,也就是0x7fffffff。Rr54
StringBuilder和StringBuffer的默認容量都是16,最好預先估計好字符串的大小避免擴容帶來的時間消耗。
因為string是不可變的,所以絕對安全。StringBuilder實際上自身維護一個char[]數組,append是沒有synchronized。StringBuffer的append等很多操作都是帶有synchronized的,所以同樣線程安全。
所以單線程字符串拼接一般采用StringBuilder,效率高。多線程環境則采用Stringbuffer,雖然安全,但是相對效率會低些。
StringBuffer 類被final 修飾所以不能繼承沒有子類
2、StringBuffer 對象是可變對象,因為父類的 value [] char 沒有被final修飾所以可以進行引用的改變,而且還提供了方法可以修改被引用對象的內容即修改了數組內容。
3、在使用StringBuffer對象的時候盡量指定大小這樣會減少擴容的次數,也就是會減少創建字符數組對象的次數和數據復制的次數,當然效率也會提升。存儲過程
1.存儲過程只在創造時進行編譯,以后每次執行存儲過程都不需再重新編譯,而一般 SQL 語句每執行一次就編譯一次,所以使用存儲過程可提高數據庫執行速度。
2.當對數據庫進行復雜操作時(如對多個表進行 Update,Insert,Query,Delete 時),可將此復雜操作用存儲過程封裝起來與數據庫提供的事務處理結合一起使用。這些操作,如果用程序來完成,就變成了一條條的 SQL 語句,可能要多次連接數據庫。而換成存儲,只需要連接一次數據庫就可以了。
3.存儲過程可以重復使用,可減少數據庫開發人員的工作量。
4.安全性高,可設定只有某此用戶才具有對指定存儲過程的使用權。
攔截器
攔截器:需要門寫一個普通類,繼承interceptorAdapter,里面定義一個Adapter方法,我們那會兒怎么實現的呢,就是說當用戶登陸成功以后,我都會把它登陸后的信息放到session里面,然后我們取的時候可以直接用看session里面有沒有信息,如果有證明用戶已經登陸了,就讓他繼續執行,如果沒有信息springMVC里面的response.send redrecte這個方法讓它重定向到登陸頁面,還需在配置文件里面配置相應的標簽,標簽里面有兩個屬性:1,path(就是攔截器需要攔截的路徑),然后就是引入咱們的定義的攔截器類,這也就簡單實現e4咱們攔截器這樣一個功能。
mybatis
mybatis 是持久層它是ORM的一個實現,它是半自動化的框架,相比hibernate它的執行效率更高,它可以直接通過寫sql這種方式來操作數據庫,並且對sql的優化也比較方便,hibernate呢它是對jdbc的高度封裝,所以對sql優化方面比較欠缺,在使用的時候呢,在它的配置文件里面的namespacse與咱們的接口進行匹配,像里面的resultMap(返回值集合)resultType(返回對象) parameterType(參數類型對象)parameterMap(參數集合)
遠程接口:
服務端:
1.提供json視圖/xml視圖
2.提供jsonp方式的數據
3.webservice[服務端]
客戶端:
1.ajax【jsonp】
2.httpclient
3.webservice[客戶端]
webservice用於傳統的企業[非互聯網企業]【CXF】
SOA[面向服務編程][思想/理念]
webservice[實現方式]
xfire[技術框架]
cxf
axis2【很多公司】【掌握】
解決了 信息孤島 的問題
跨語言,跨平台。
webService的三要素
1.wsdl(webservie描述語言):描述發布接口的信息
2.soap(簡單對象訪問協議)(webservice使用的協議):http+xml
3.uddi(查詢和管理webservice)
cxf:
服務端的配置:
1.在web.xml中通過cxfServlet這個核心類對指定的url進行攔截
2.通過在接口上加入@webservice的注解
3.通過配置spring-cxf-server.xml這個配置文件進行接口的發布
4.在地址欄輸入http://ip地址:端口號/項目名/web.xml中配置的servlet的url-pattern/spring-cxf-
server.xml中發布的接口的address?wsdl。【驗證】
客戶端的配置:【多種實現方式】【wsdl2java來生成客戶端】【導入jar包】
1.配置環境變量 path=D:\java\apache-cxf-2.7.18\bin
2.wsdl2java -p 包名 -d 目標路徑 服務器生成的接口路徑
3.通過spring-cxf-client.xml來配置客戶端
4.驗證客戶端代碼以及服務端【單元測試】
簡介
之前jsp-->controller-->service-->dao
webservice改變:
服務端:service-->dao
客戶端:jsp-->controller-->遠程service
httpclient/json視圖 改變:
服務端:controller-->service-->dao
客戶端:jsp-->controller-->service-->通過httpclient調用遠程的json視圖
ajax jsonp 改變:
服務端:controller-->service-->dao
客戶端:jsp-->ajax jsonp
