Java經典面試題最全匯總208道(四)
前言
短時間提升自己最快的手段就是背面試題,最近總結瞭Java常用的面試題,分享給大傢,希望大傢都能圓夢大廠,加油,我命由我不由天。
126、Spring 框架中的單例 Beans 是線程安全的麼?
Spring框架並沒有對單例bean進行任何多線程的封裝處理。
關於單例bean的線程安全和並發問題需要開發者自行去搞定。
但實際上,大部分的Spring bean並沒有可變的狀態,所以在某種程度上說Spring的單例bean時線程安全的。
如果你的bean有多種狀態的話,比如view model,就需要自行保證線程安全啦。
最淺顯的解決辦法就是將多態bean的作用域由singleton變更為prototype。
127、請解釋 Spring Bean 的自動裝配?
Spring支持IOC,自動裝配不用類實例化,直接從bean容器中取。
1、配置在xml中
<bean id="employeeDAO" class="com.guor.EmployeeDAOImpl" autowire="byName" />
2、@Autowired自動裝配
128、如何開啟基於註解的自動裝配?
要使用 @Autowired,需要註冊 AutowiredAnnotationBeanPostProcessor,可以有以下兩種方式來實現:
引入配置文件中的<bean>下引入 <context:annotation-config>
<beans> <context:annotation-config /> </beans>
在bean配置文件中直接引入AutowiredAnnotationBeanPostProcessor
<beans> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> </beans>
129、什麼是 Spring Batch?
1、什麼是spring batch?
spring batch是一個輕量級的、完善的批處理框架,它主要的目的在於幫助企業建立健壯、高效的批處理應用。
spring batch是Spring的一個子項目,它使用java語言並基於spring框架作為基礎開發,使得已經使用Spring框架的開發者或者是企業可以更加容易訪問和利用企業服務。
spring batch提供瞭大量可重用的組件,包括瞭日志、追蹤、事務、任務作業統計、任務重啟、跳過、重復、資源管理。
對大數據量和高性能的批處理任務,spring batch同樣提供瞭高級功能和特性來支持。
例如:分區功能、遠程功能。
總的來說,spring batch可以支持簡單的、復雜的和大數據量的批處理作業。
2、spring batch業務場景
周期性的提交批處理
把一個任務並行處理
消息驅動應用分級處理
大規模並行批處理
手工或調度使任務失敗之後重新啟動
有依賴步驟的順序執行(使用工作流驅動擴展)
處理時跳過部分記錄
成批事務:為小批量的或有的存儲過程/腳本的場景使用
130、spring mvc 和 struts 的區別是什麼?
1、攔截機制的不同
Struts2是類級別的攔截,每次請求就會創建一個Action,和Spring整合時Struts2的ActionBean註入作用域是原型模式prototype,然後通過setter,getter吧request數據註入到屬性。
Struts2中,一個Action對應一個request,response上下文,在接收參數時,可以通過屬性接收,這說明屬性參數是讓多個方法共享的。
Struts2中Action的一個方法可以對應一個url,而其類屬性卻被所有方法共享,這也就無法用註解或其他方式標識其所屬方法瞭,隻能設計為多例。
SpringMVC是方法級別的攔截,一個方法對應一個Request上下文,所以方法直接基本上是獨立的,獨享request,response數據。
而每個方法同時又何一個url對應,參數的傳遞是直接註入到方法中的,是方法所獨有的。
處理結果通過ModeMap返回給框架。在Spring整合時,SpringMVC的Controller Bean默認單例模式Singleton,所以默認對所有的請求,隻會創建一個Controller,有應為沒有共享的屬性,所以是線程安全的,如果要改變默認的作用域,需要添加@Scope註解修改。
Struts2有自己的攔截Interceptor機制,SpringMVC這是用的是獨立的Aop方式,這樣導致Struts2的配置文件量還是比SpringMVC大。
2、底層框架的不同
Struts2采用Filter(StrutsPrepareAndExecuteFilter)實現,SpringMVC(DispatcherServlet)則采用Servlet實現。Filter在容器啟動之後即初始化;服務停止以後墜毀,晚於Servlet。Servlet在是在調用時初始化,先於Filter調用,服務停止後銷毀。
3、性能方面
Struts2是類級別的攔截,每次請求對應實例一個新的Action,需要加載所有的屬性值註入,SpringMVC實現瞭零配置,由於SpringMVC基於方法的攔截,有加載一次單例模式bean註入。
所以,SpringMVC開發效率和性能高於Struts2。
4、配置方面
spring MVC和Spring是無縫的。從這個項目的管理和安全上也比Struts2高。
131、請舉例解釋@Required 註解?
@Required註解應用於bean屬性的setter方法,它表明影響的bean屬性在配置時必須放在XML配置文件中。
請舉例說明@Qualifier 註解?
如果在xml中定義瞭一種類型的多個bean,同時在java註解中又想把其中一個bean對象作為屬性,那麼此時可以使用@Qualifier加@Autowired來達到這一目的
若不加@Qualifier這個註解,在運行時會出現“ No qualifying bean of type [com.tutorialspoint.Student] is defined: expected single matching bean but found 2: student1,student2”這個異常。
132、Spring常用註解
Spring常用註解(絕對經典)
133、項目中是如何實現權限驗證的,權限驗證需要幾張表
通過瞭解,現在最普遍的權限管理模型就是RBAC(Role-Based Access Control)。
1、權限控制分類
菜單功能
url控制(控制訪問不同的控制器)
2、RBAC的優缺點
(1)優點
簡化瞭用戶和權限的關系
易擴展、易維護
(2)缺點
RBAC模型沒有提供操作順序的控制機制,這一缺陷使得RBAC模型很難適應哪些對操作次序有嚴格要求的系統。
3、RBAC支持的安全原則
(1)最小權限原則
RBAC可以將角色配置成其完成任務所需的最小權限集合。
(2)責任分離原則
可以通過調用相互獨立互斥的角色來共同完成敏感的任務,例如要求一個記賬員和財務管理員共同參與統一過賬操作。
(3)數據抽象原則
可以通過權限的抽象來體現,例如財務操作用借款、存款等抽象權限,而不是使用典型的讀寫權限。
4、遠古時代的權限控制
當時還沒有RBAC,也沒有這個概念,就是一堆程序員在那鼓搗,覺得登錄這塊該做點什麼。
1、新建一個用戶,對這個用戶進行賦予權限。
2、但是一旦用戶多瞭,權限復雜瞭,這工作量也是蠻大的。
5、RBAC
RBAC 1.0
直接上圖,一目瞭然,當程序不是很復雜的時候,RBAC就是這樣設計的,我們公司的權限驗證模塊就是這樣設計的。
簡簡單單,五張表,解
RBAC 2.0
基於RBAC 1.0模型的基礎上,進行瞭角色的訪問控制
RBAC2中的一個基本限制是互斥角色的限制,互斥角色是指各自權限可以互相制約的兩個角色。
對於這類角色一個用戶在某一次活動中隻能被分配其中的一個角色,不能同時獲得兩個角色的使用權。
該模型有以下幾種約束
- 互斥角色 :同一用戶隻能分配到一組互斥角色集合中至多一個角色,支持責任分離的原則。
互斥角色是指各自權限互相制約的兩個角色。
對於這類角色一個用戶在某一次活動中隻能被分配其中的一個角色,不能同時獲得兩個角色的使用權。
常舉的例子:在審計活動中,一個角色不能同時被指派給會計角色和審計員角色。
- 基數約束 :一個角色被分配的用戶數量受限;一個用戶可擁有的角色數目受限;同樣一個角色對應的訪問權限數目也應受限,以控制高級權限在系統中的分配。
- 先決條件角色 :可以分配角色給用戶僅當該用戶已經是另一角色的成員;對應的可以分配訪問權限給角色,僅當該角色已經擁有另一種訪問權限。
指要想獲得較高的權限,要首先擁有低一級的權限。
- 運行時互斥 :例如,允許一個用戶具有兩個角色的成員資格,但在運行中不可同時激活這兩個角色。
6、rbac的實現理論分析
進入登錄頁面;
拿到通過post傳過來的用戶名和密碼;
使用orm進行過濾查找;
如果能找到值,則說明登錄成功:登錄成功後調用rbac初始化函數,初始化函數的主要功能是獲取用戶的權限和菜單保存到session中,並跳轉客戶列表頁面;
如果失敗,頁面進行友好提示;
7、url權限控制關鍵代碼
134、談談controller,接口調用的路徑問題
1、Spring MVC如何匹配請求路徑
@RequestMapping是用來映射請求的,比如get請求、post請求、或者REST風格與非REST風格的。
該註解可以用在類上或方法上,如果用在類上,表示是該類中所有方法的父路徑。
@RequestMapping("/springmvc") @Controller public class SpringMVCTest { @RequestMapping("/testRequestMapping") public String testRequestMapping(){ System.out.println("testRequestMapping"); return SUCCESS; } }
在類上還添加瞭一個@Controller註解,該註解在SpringMVC中負責處理由DispatcherServlet分發的請求,它把用戶請求的數據經過業務處理層處理之後封裝成一個model,然後再把該model返回給對應的view進行展示。
我們可以通過“springmvc/testRequestMapping”這個路徑來定位到testRequestMapping這個方法,然後執行方法內的方法體。
RequestMapping可以實現模糊匹配路徑,比如:
- ?表示一個字符;
- *表示任意字符;
- **匹配多層路徑;
/springmvc/**/testRequestMapping 就可以匹配/springmvc/stu/getStudentInfo/testRequestMapping 這樣的路徑瞭。
2、SpringMVC如何獲取請求的參數
(1)@PathVariable
該註解用來映射請求URL中綁定的占位符。通過@PathVariable可以將URL中占位符的參數綁定到controller處理方法的入參中。
@RequestMapping("/testPathVariable/{id}") public String testPathVariable(@PathVariable(value="id") Integer id){ System.out.println("testPathVariable:" + id); return SUCCESS; }
在index.jsp中我們添加一條連接,用來觸發一個請求:
<a href="springmvc/testPathVariable/1" rel="external nofollow" >testPathVariable</a>
(2) @RequestParam
該註解也是用來獲取請求參數的,那麼該註解和@PathVariable有什麼不同呢?
@RequestMapping(value="/testRequestParam") public String testRequestParam(@RequestParam(value="username") String username, @RequestParam(value="age", required=false, defaultValue="0") int age){ System.out.println("testRequestParam" + " username:" + username + " age:" +age); return SUCCESS; }
在index.jsp添加超鏈接標簽
<a href="springmvc/testRequestParam?username=jackie&age=12" rel="external nofollow" >testRequestParam</a>
3、REST風格的請求
在SpringMVC中業務最多的應該是CRUD瞭
@RequestMapping(value="/testRest/{id}", method=RequestMethod.PUT) public String testRestPut(@PathVariable(value="id") Integer id){ System.out.println("test put:" + id); return SUCCESS; } @RequestMapping(value="/testRest/{id}", method=RequestMethod.DELETE) public String testRestDelete(@PathVariable(value="id") Integer id){ System.out.println("test delete:" + id); return SUCCESS; } @RequestMapping(value="/testRest", method=RequestMethod.POST) public String testRest(){ System.out.println("test post"); return SUCCESS; } @RequestMapping(value="/testRest/{id}", method=RequestMethod.GET) public String testRest(@PathVariable(value="id") Integer id){ System.out.println("test get:" + id); return SUCCESS; }
135、如何防止表單重復提交
1、通過JavaScript屏蔽提交按鈕(不推薦)
2、給數據庫增加唯一鍵約束(簡單粗暴)
3、利用Session防止表單重復提交(推薦)
4、使用AOP自定義切入實現
136、Spring中都應用瞭哪些設計模式
1、簡單工廠模式
簡單工廠模式的本質就是一個工廠類根據傳入的參數,動態的決定實例化哪個類。
Spring中的BeanFactory就是簡單工廠模式的體現,根據傳入一個唯一的標識來獲得bean對象。
2、工廠方法模式
應用程序將對象的創建及初始化職責交給工廠對象,工廠Bean。
定義工廠方法,然後通過config.xml配置文件,將其納入Spring容器來管理,需要通過factory-method指定靜態方法名稱。
3、單例模式
Spring用的是雙重判斷加鎖的單例模式,通過getSingleton方法從singletonObjects中獲取bean。
/** * Return the (raw) singleton object registered under the given name. * <p>Checks already instantiated singletons and also allows for an early * reference to a currently created singleton (resolving a circular reference). * @param beanName the name of the bean to look for * @param allowEarlyReference whether early references should be created or not * @return the registered singleton object, or {@code null} if none found */ protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return (singletonObject != NULL_OBJECT ? singletonObject : null); }
4、代理模式
Spring的AOP中,使用的Advice(通知)來增強被代理類的功能。
Spring實現AOP功能的原理就是代理模式(① JDK動態代理,② CGLIB字節碼生成技術代理。)對類進行方法級別的切面增強。
5、裝飾器模式
裝飾器模式:動態的給一個對象添加一些額外的功能。
Spring的ApplicationContext中配置所有的DataSource。
這些DataSource可能是不同的數據庫,然後SessionFactory根據用戶的每次請求,將DataSource設置成不同的數據源,以達到切換數據源的目的。
在Spring中有兩種表現:
一種是類名中含有Wrapper,另一種是類名中含有Decorator。
6、觀察者模式
定義對象間的一對多的關系,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並自動更新。
Spring中觀察者模式一般用在listener的實現。
7、策略模式
策略模式是行為性模式,調用不同的方法,適應行為的變化 ,強調父類的調用子類的特性 。
getHandler是HandlerMapping接口中的唯一方法,用於根據請求找到匹配的處理器。
8、模板方法模式
Spring JdbcTemplate的query方法總體結構是一個模板方法+回調函數,query方法中調用的execute()是一個模板方法,而預期的回調doInStatement(Statement state)方法也是一個模板方法。
137、請舉例說明如何在 Spring 中註入一個 Java Collection?
Spring註入有四種方式,
- set註入;
- 構造器註入;
- 基於註解的註入;
- xml配置文件註入;
想要註入java collection,就是註入集合類:
- listsetmapprops:該標簽支持註入鍵和值都是字符串類型的鍵值對。
- list和set都使用value標簽;
- map使用entry標簽;
- props使用prop標簽;
-
138、mybatis 中 #{}和 ${}的區別是什麼?
- #{}帶引號,${}不帶引號;
- #{}可以防止SQL註入;
- ${}常用於數據庫表名、order by子句;
- 一般能用#{}就不要使用${};
139、mybatis 是否支持延遲加載?延遲加載的原理是什麼?
1、mybatis 是否支持延遲加載?
延遲加載其實就是講數據加載時機推遲,比如推遲嵌套查詢的時機。
延遲加載可以實現先查詢主表,按需實時做關聯查詢,返回關聯表結果集,一定程度上提高瞭效率。
mybatis僅支持關聯對象association和關聯集合對象collection的延遲加載,association是一對一,collection是一對多查詢,在mybatis配置文件中可以配置lazyloadingEnable=true/false。
2、延遲加載的原理是什麼?
使用CGLIB為目標對象建立代理對象,當調用目標對象的方法時進入攔截器方法。
比如調用a.getB().getName(),攔截器方法invoke()發現a.getB()為null,會單獨發送事先準備好的查詢關聯B對象的sql語句,把B查詢出來然後調用a.setB(b),也是a的對象的屬性b就有值瞭,然後調用getName(),這就是延遲加載的原理。
140、說一下 mybatis 的一級緩存和二級緩存?
一級緩存是session級別的緩存,默認開啟,當查詢一次數據庫時,對查詢結果進行緩存,如果之後的查詢在一級緩存中存在,則無需再訪問數據庫;
二級緩存是sessionFactory級別的緩存,需要配置才會開啟。當進行sql語句查詢時,先查看一級緩存,如果不存在,訪問二級緩存,降低數據庫訪問壓力。
141、mybatis 有哪些執行器(Executor)?
1、mybatis有三種基本的Executor執行器:
(1)、SimpleExecutor
每執行一次update或select,就開啟一個Statement對象,用完立刻關閉Statement對象。
(2)、PauseExecutor
執行update或select,以sql做為key查找Statement對象,存在就使用,不存在就創建,用完後,不關閉Statement對象,而且放置於Map內,供下一次使用。
簡言之,就是重復使用Statement對象。
(3)、BatchExecutor
執行update,將所有sql通過addBatch()都添加到批處理中,等待統一執行executeBatch(),它緩存瞭多個Statement對象,每個Statement對象都是addBatch()完畢後,等待逐一執行executeBatch()批處理。
與JDBC批處理相同。
2、作用范圍:
Executor的這些特點,都嚴格限制在SqlSession生命周期范圍內。
3、Mybatis中如何指定使用哪一種Executor執行器?
在mybatis的配置文件中,可以指定默認的ExecutorType執行器類型,也可以手動給DefaultSqlSessionFactory的創建SqlSession的方法傳遞ExecutorType類型參數。
142、mybatis 和 hibernate 的區別有哪些?
1、兩者最大的區別
針對簡單邏輯,都有對應的代碼生成工具,可以生成簡單基本的dao層方法;
針對高級查詢,mybatis要手動編寫sql語句和resultMap,而hibernate有良好的映射機制;
2、開發難度對比
hibernate > mybatis
3、日志統計
hibernate有自己的日志統計功能,而mybatis需要借助log4j來記錄日志。
4、數據庫擴展比較
hibernate > mybatis
5、緩存機制比較
因為hibernate對查詢對象有良好的管理機制,用戶無需關心sql,所以使用二級緩存如果出現臟數據,系統會報錯。
而mybatis,如果不能獲取最新數據,應該避免緩存的使用,臟數據的出現會給系統的正常運行帶來很大的隱患。
6、如何選擇
- mybatis需要編寫sql和映射規則,工作量大於hibernate;
- mybatis支持的工具也有限,不能像hibernate那樣有許多插件可以幫助生成映射代碼和關聯關系;
- 對於性能要求不太苛刻的系統,比如管理系統、ERP等推薦hibernate;
- 對於性能要求高、響應快、靈活的系統,比如電商系統,推薦使用mybatis;
143、myBatis查詢多個id、myBatis常用屬性
myBatis查詢多個id(我居然回答用對象來傳遞…)
Page<UserPoJo> getUserListByIds(@Param("ids") List<Integer> ids);
<!--根據id列表批量查詢user--> <select id="getUserListByIds" resultType="com.guor.UserPoJo"> select * from student where id in <foreach collection="ids" item="userid" open="(" close=")" separator=","> #{userid} </foreach> </select>
144、mybatis一級緩存、二級緩存
1、一級緩存:指的是mybatis中sqlSession對象的緩存,當我們執行查詢以後,查詢的結果會同時存入sqlSession中,再次查詢的時候,先去sqlSession中查詢,有的話直接拿出,當sqlSession消失時,mybatis的一級緩存也就消失瞭,當調用sqlSession的修改、添加、刪除、commit()、close()等方法時,會清空一級緩存。
2、二級緩存:指的是mybatis中的sqlSessionFactory對象的緩存,由同一個sqlSessionFactory對象創建的sqlSession共享其緩存,但是其中緩存的是數據而不是對象。
當命中二級緩存時,通過存儲的數據構造成對象返回。查詢數據的時候,查詢的流程是二級緩存 > 一級緩存 > 數據庫。
3、如果開啟瞭二級緩存,sqlSession進行close()後,才會把sqlSession一級緩存中的數據添加到二級緩存中,為瞭將緩存數據取出執行反序列化,還需要將要緩存的pojo實現Serializable接口,因為二級緩存數據存儲介質多種多樣,不一定隻存在內存中,也可能存在硬盤中。
4、mybatis框架主要是圍繞sqlSessionFactory進行的,具體的步驟:
定義一個configuration對象,其中包含數據源、事務、mapper文件資源以及影響數據庫行為屬性設置settings。
- 通過配置對象,則可以創建一個sqlSessionFactoryBuilder對象。
- 通過sqlSessionFactoryBuilder獲得sqlSessionFactory實例。
- 通過sqlSessionFactory實例創建qlSession實例,通過sqlSession對數據庫進行操作。
5、代碼實例
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 加載類路徑下的屬性文件 --> <properties resource="db.properties"/> <!-- 設置類型別名 --> <typeAliases> <typeAlias type="cn.itcast.javaee.mybatis.app04.Student" alias="student"/> </typeAliases> <!-- 設置一個默認的連接環境信息 --> <environments default="mysql_developer"> <!-- 連接環境信息,取一個任意唯一的名字 --> <environment id="mysql_developer"> <!-- mybatis使用jdbc事務管理方式 --> <transactionManager type="jdbc"/> <!-- mybatis使用連接池方式來獲取連接 --> <dataSource type="pooled"> <!-- 配置與數據庫交互的4個必要屬性 --> <property name="driver" value="${mysql.driver}"/> <property name="url" value="${mysql.url}"/> <property name="username" value="${mysql.username}"/> <property name="password" value="${mysql.password}"/> </dataSource> </environment> <!-- 連接環境信息,取一個任意唯一的名字 --> <environment id="oracle_developer"> <!-- mybatis使用jdbc事務管理方式 --> <transactionManager type="jdbc"/> <!-- mybatis使用連接池方式來獲取連接 --> <dataSource type="pooled"> <!-- 配置與數據庫交互的4個必要屬性 --> <property name="driver" value="${oracle.driver}"/> <property name="url" value="${oracle.url}"/> <property name="username" value="${oracle.username}"/> <property name="password" value="${oracle.password}"/> </dataSource> </environment> </environments> <!-- 加載映射文件--> <mappers> <mapper resource="cn/itcast/javaee/mybatis/app14/StudentMapper.xml"/> </mappers> </configuration>
public class MyBatisTest { public static void main(String[] args) { try { //讀取mybatis-config.xml文件 InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); //初始化mybatis,創建SqlSessionFactory類的實例 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); //創建session實例 SqlSession session = sqlSessionFactory.openSession(); /* * 接下來在這裡做很多事情,到目前為止,目的已經達到得到瞭SqlSession對象.通過調用SqlSession裡面的方法, * 可以測試MyBatis和Dao層接口方法之間的正確性,當然也可以做別的很多事情,在這裡就不列舉瞭 */ //插入數據 User user = new User(); user.setC_password("123"); user.setC_username("123"); user.setC_salt("123"); //第一個參數為方法的完全限定名:位置信息+映射文件當中的id session.insert("com.cn.dao.UserMapping.insertUserInformation", user); //提交事務 session.commit(); //關閉session session.close(); } catch (IOException e) { e.printStackTrace(); } } }
145、mybatis如何防止sql註入
註意:但凡是sql註入漏洞的程序,都是因為程序要接受來自客戶端用戶輸入的變量或URL傳遞的參數,並且這個變量或參數是組成sql語句的一部分,對於用戶輸入的內容或傳遞的參數,我們應該要時刻保持警惕,這是安全領域裡的【外部數據不可信任】的原則,縱觀web安全領域的各種攻擊方式,大多數都是因為開發者違反瞭這個原則而導致的,所以自然能想到,就是變量的檢測、過濾、驗證下手,確保變量是開發者所預想的。
1、檢查變量數據類型和格式
數據類型檢查,sql執行前,要進行數據類型檢查,如果是郵箱,參數就必須是郵箱的格式,如果是日期,就必須是日期格式;
隻要是有固定格式的變量,在SQL語句執行前,應該嚴格按照固定格式去檢查,確保變量是我們預想的格式,這樣很大程度上可以避免SQL註入攻擊。
如果上述例子中id是int型的,效果會怎樣呢?無法註入,因為輸入註入參數會失敗。
比如上述中的name字段,我們應該在用戶註冊的時候,就確定一個用戶名規則
比如5-20個字符,隻能由大小寫字母、數字以及漢字組成,不包含特殊字符。
此時我們應該有一個函數來完成統一的用戶名檢查。
不過,仍然有很多場景並不能用到這個方法,比如寫博客,評論系統,彈幕系統,必須允許用戶可以提交任意形式的字符才行,否則用戶體驗感太差瞭。
2、過濾特殊符號
3、綁定變量,使用預編譯語句
146、為什麼要使用 hibernate?
- hibernate對jdbc進行瞭封裝,簡化瞭JDBC的重復性代碼;
- hibernate對dao有一個封裝類hibernateTemplate,可以繼承它,實現簡單的CRUD接口。
- hibernate使用註解和配置文件,可以對實體類和映射文件進行映射;
- hibernate有事務管理機制,保證瞭數據的安全性;
- hibernate有一級緩存和二級緩存;
146、hibernate 中如何在控制臺查看打印的 sql 語句?
public class MyBatisTest { public static void main(String[] args) { try { //讀取mybatis-config.xml文件 InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); //初始化mybatis,創建SqlSessionFactory類的實例 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); //創建session實例 SqlSession session = sqlSessionFactory.openSession(); /* * 接下來在這裡做很多事情,到目前為止,目的已經達到得到瞭SqlSession對象.通過調用SqlSession裡面的方法, * 可以測試MyBatis和Dao層接口方法之間的正確性,當然也可以做別的很多事情,在這裡就不列舉瞭 */ //插入數據 User user = new User(); user.setC_password("123"); user.setC_username("123"); user.setC_salt("123"); //第一個參數為方法的完全限定名:位置信息+映射文件當中的id session.insert("com.cn.dao.UserMapping.insertUserInformation", user); //提交事務 session.commit(); //關閉session session.close(); } catch (IOException e) { e.printStackTrace(); } } }
147、hibernate 有幾種查詢方式?
1、導航對象圖查詢:根據已加載的對象,導航到其他對象。
例如,對於已經加載的Customer對象,調用它的getOrders().iterator()方法就可以導航到所有關聯的Order對象,假如在關聯級別使用瞭延遲加載檢索策略
那麼首次執行此方法時,hibernate會從數據庫中加載關聯的Order對象,否則就從緩存中獲得Order對象。
2、OID方式:按照對象的OID來檢索對象
Session的get()和load()方法提供瞭這種功能,如果在應用程序中先知道瞭OID,就可以使用這種方式檢索對象。
get()和load()的用法完全一樣,都需要兩個參數,一個是持久化對象類名class,一個是行號OID,返回固定的某一行的數據,但是需要註意的是,當輸入的OID不存在時,get()會返回一個空對象,load()則直接報錯。
3、HQL檢索方式:(hibernate query language)
使用面向對象的HQL查詢語言,session的find()方法用於執行HQL查詢語句。
此外,hibernate還提供瞭query接口,它是hibernate提供的專門的HQL查詢接口,能夠執行各種復雜的HQL查詢語句。
它具備以下功能:
- 在查詢語句中設定各種查詢條件;
- 支持投影查詢,即僅檢索出對象的部分屬性;
- 支持分頁查詢;
- 支持連接查詢;
- 支持分組查詢;
- 提供內置函數;
- 能夠調用用戶自定義的SQL函數;
- 支持子查詢;
- 支持動態綁定參數;
例如:
Query query = session.createQuery(“from UserPo”);
獲得一個query對象,註意參數字符串中不是一個SQL語句,from後面的是持久化對象名稱;
List list = query.list();
就可以獲取數據庫中對應表的數據集合。
4、QBC檢索方式:Query By Criteria的API來檢索對象
這種API封裝瞭基於字符串形式的查詢語句,提供瞭更加面向對象的接口。
例:Criteria criteria = session.createCriteria(UserPo.class);
創建一個Criteria對象,參數是所關聯的持久化對象,criteria.add(Restrictions.ge("id",2));將查詢條件加入對象中,後面的操作就和Query對象一樣瞭。
5、本地SQL
使用本地數據庫的SQL查詢語句,hibernate會負責把檢索到的JDBC ResultSet結果映射為持久化對象圖。
148、hibernate 實體類可以被定義為 final 嗎?
可以將hibernate的實體類定義為final,但這種做法不好。
因為hibernate會使用代理模式在延遲關聯的情況下提高性能,如果你把實體類定義成final類之後,因為Java不允許對final類進行擴展
所以hibernate就無法再使用代理瞭,如此一來就限制瞭使用可以提升性能的手段。
不過,如果你的持久化類實現瞭一個接口,而且在該接口中聲明瞭所有定義於實體類中的所有public的方法的話,就能避免出現前面所說的不利後果。
149、在 hibernate 中使用 Integer 和 int 做映射有什麼區別?
hibernate是面向對象的ORM,所以一般定義成封裝類型,要看數據庫中的定義,如果數據庫中有對應字段存在null值,就要定義Integer。
也可以定義基本類型,在配置文件中寫清楚即可。
150、什麼是 Spring Boot?Spring Boot 有哪些優點?
1、Spring Boot簡介
基於Spring4.0設計,不僅繼承瞭Spring框架原有的優秀特性,而且還通過簡化配置來進一步簡化spring應用的整個搭建和開發過程。
另外SpringBoot通過集成大量的框架使得依賴包的版本沖突、引用的不穩定性得到瞭解決。
2、Spring Boot 有哪些優點?
- 快速構建項目,可以選一些必要的組件;
- 對主流框架的無配置集成;
- 內嵌Tomcat容器,項目可獨立運行;
- 刪除瞭繁瑣的xml配置文件;
- 極大地提高瞭開發和部署效率;
- 提供starter,簡化maven配置;
3、SpringBoot有哪些缺點?
版本迭代速度快,一些模塊改動很大;由於無須配置,報錯時很難定位;
151、Spring Boot 中的監視器是什麼?
監聽器也叫listener,是servlet的監聽器,可以用於監聽web應用程序中某些對象的創建、銷毀、增加、修改、刪除等動作的發生,然後做出相應的響應處理。
當范圍對象的狀態發生變化時,服務器自動調用監聽器對象中的方法,常用於系統加載時進行信息初始化,統計在線人數和在線用戶,統計網站的訪問量。
配置監聽器的方法:
- 通過@Component把監聽器加入Spring容器中管理;
- 在application.properties中添加context.listener.classes配置;
- 在方法上加@EventListener註解;
到此這篇關於Java經典面試題最全匯總208道(四)的文章就介紹到這瞭,更多相關Java面試題內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Java中Mybatis,SpringMVC,Spring的介紹及聯系
- Java面試題沖刺第九天–MyBatis
- 為什麼mybatis中的SqlSession一定要關閉
- Mybatis執行流程、緩存原理及相關面試題匯總
- Spring整合Mybatis具體代碼實現流程