首頁 > 軟體

Java經典面試題最全彙總208道(四)

2023-01-18 14:00:57

前言 

短時間提升自己最快的手段就是背面試題,最近總結了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可以實現模糊匹配路徑,比如:

  1. ?表示一個字元;
  2. *表示任意字元;
  3. **匹配多層路徑;

/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注入有四種方式,

  1. set注入;
  2. 構造器注入;
  3. 基於註解的注入;
  4. xml組態檔注入;

想要注入java collection,就是注入集合類:

  1. listsetmapprops:該標籤支援注入鍵和值都是字串型別的鍵值對。
  2. list和set都使用value標籤;
  3. map使用entry標籤;
  4. props使用prop標籤;
  5. 138、mybatis 中 #{}和 ${}的區別是什麼?

  6. #{}帶引號,${}不帶引號;
  7. #{}可以防止SQL隱碼攻擊;
  8. ${}常用於資料庫表名、order by子句;
  9. 一般能用#{}就不要使用${};

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。

  1. 通過設定物件,則可以建立一個sqlSessionFactoryBuilder物件。
  2. 通過sqlSessionFactoryBuilder獲得sqlSessionFactory範例。
  3. 通過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?

  1. hibernate對jdbc進行了封裝,簡化了JDBC的重複性程式碼;
  2. hibernate對dao有一個封裝類hibernateTemplate,可以繼承它,實現簡單的CRUD介面。
  3. hibernate使用註解和組態檔,可以對實體類和對映檔案進行對映;
  4. hibernate有事務管理機制,保證了資料的安全性;
  5. 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查詢語句。

它具備以下功能:

  1. 在查詢語句中設定各種查詢條件;
  2. 支援投影查詢,即僅檢索出物件的部分屬性;
  3. 支援分頁查詢;
  4. 支援連線查詢;
  5. 支援分組查詢;
  6. 提供內建函數;
  7. 能夠呼叫使用者自定義的SQL函數;
  8. 支援子查詢;
  9. 支援動態繫結引數;

例如:

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 有哪些優點?

  1. 快速構建專案,可以選一些必要的元件;
  2. 對主流框架的無設定整合;
  3. 內嵌Tomcat容器,專案可獨立執行;
  4. 刪除了繁瑣的xml組態檔;
  5. 極大地提高了開發和部署效率;
  6. 提供starter,簡化maven設定;

3、SpringBoot有哪些缺點?

版本迭代速度快,一些模組改動很大;由於無須設定,報錯時很難定位;

151、Spring Boot 中的監視器是什麼?

監聽器也叫listener,是servlet的監聽器,可以用於監聽web應用程式中某些物件的建立、銷燬、增加、修改、刪除等動作的發生,然後做出相應的響應處理。

當範圍物件的狀態發生變化時,伺服器自動呼叫監聽器物件中的方法,常用於系統載入時進行資訊初始化,統計線上人數和線上使用者,統計網站的存取量。

設定監聽器的方法:

  1. 通過@Component把監聽器加入Spring容器中管理;
  2. 在application.properties中新增context.listener.classes設定;
  3. 在方法上加@EventListener註解;

到此這篇關於Java經典面試題最全彙總208道(四)的文章就介紹到這了,更多相關Java面試題內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com