Java面試題更新帖(2020年04月19日更新)

一、Spring

1.談一談Spring中的IOC容器和DI依賴注入

答:Spring中的IOC容器,即inverse of control控制反轉,舉個例子,在使用Spring之前,我們在service層使用dao層的對象時,我們都習慣new一個dao層的對象使用,這是一種很強的依賴,不符合Java中低耦合高內聚的原則,爲了解耦,我們就引入了工廠模式,原來我們獲取對象的方式都是自己new出來,現在由工廠創建對象提供給我們,原來是我們主動的,現在是被動的,這就稱之爲控制反轉,這個工廠其實是一個Map,我們稱之爲容器。

SpringIOC容器使用過程
//1.使用 ApplicationContext 接口,就是在獲取 spring 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根據 bean 的 id 獲取對象
IAccountService aService = (IAccountService) ac.getBean("accountService");
System.out.println(aService);
IAccountDao aDao = (IAccountDao) ac.getBean("accountDao");
System.out.println(aDao);

BeanFactory和ApplicationContext的區別?

BeanFactory 纔是 Spring 容器中的頂層接口。
ApplicationContext 是它的子接口。
創建對象的時間點不一樣。
ApplicationContext:只要一讀取配置文件,默認情況下就會創建對象。
BeanFactory:什麼使用什麼時候創建對象。

IOC中的bean標籤?

用於配置對象讓 spring 來創建的。
默認情況下它調用的是類中的無參構造函數。如果沒有無參構造函數則不能創建成功。

id:給對象在容器中提供一個唯一標識。用於獲取對象。
class:指定類的全限定類名。用於反射創建對象。默認情況下調用無參構造函數。
scope:指定對象的作用範圍。
* singleton :默認值,單例的.
* prototype :多例的.
* request  :WEB 項目中,Spring 創建一個 Bean 的對象,將對象存入到 request 域中.
* session  :WEB 項目中,Spring 創建一個 Bean 的對象,將對象存入到 session 域中.
* global session  :WEB 項目中,應用在 Portlet 環境.如果沒有 Portlet 環境那麼
globalSession 相當於 session.
init-method:指定類中的初始化方法名稱。
destroy-method:指定類中銷燬方法名稱。

bean的作用範圍和生命週期?

單例對象:scope="singleton"
一個應用只有一個對象的實例。它的作用範圍就是整個引用。
生命週期:
對象出生:當應用加載,創建容器時,對象就被創建了。
對象活着:只要容器在,對象一直活着。
對象死亡:當應用卸載,銷燬容器時,對象就被銷燬了。
多例對象:scope="prototype"
每次訪問對象時,都會重新創建對象實例。
生命週期:
對象出生:當使用對象時,創建新的對象實例。
對象活着:只要對象在使用中,就一直活着。
對象死亡:當對象長時間不用時,被 java 的垃圾回收器回收了。

Spring中的依賴注入DI

DI,dependency injection。

構造函數注入

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
    <constructor-arg name="name" value=" 張三 "></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
    <constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>

Set方法注入,最常用

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
    <property name="name" value="test"></property>
    <property name="age" value="21"></property>
    <property name="birthday" ref="now"></property>
</bean>
<bean id="now" class="java.util.Date"></bean>

p命名空間注入,實際上還是調用set方法注入

2.Spring中的註解

@Component:相當於<bean id="" class="">;註解內只有一個屬性value,用來指定bean的id值;衍生出了三種註解分別用於三層架構的不同層,@Controller,@Service,@Repository。

@Autowired:自動按照類型注入。當使用註解注入屬性時,set方法可以省略。它只能注入其他 bean 類型。當有多個類型匹配時,使用要注入的對象變量名稱作爲 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到就報錯。

@Qualifier:在自動按照類型注入的基礎之上,再按照 Bean 的 id 注入。它在給字段注入時不能獨立使用,必須和@Autowire 一起使用;但是給方法參數注入時,可以獨立使用。該註解有一個屬性value:指定 bean 的 id。

@Resource:直接按照 Bean 的 id 注入。它也只能注入其他 bean 類型。該註解只有一個屬性name:指定 bean 的 id。

@Value:注入基本數據類型和 String 類型數據的,該註解有一個屬性value:用於指定值。

@Scope:相當於:<bean id="" class="" scope="">,指定 bean 的作用範圍。該註解只有一個屬性value:指定範圍的值。取值:singleton prototype request session globalsession。

@Configuration:用於指定當前類是一個 spring 配置類,當創建容器時會從該類上加載註解。獲取容器時需要使用AnnotationApplicationContext(有@Configuration 註解的類.class)。該註解有一個屬性value:用於指定配置類的字節碼。

@ComponentScan:用於指定 spring 在初始化容器時要掃描的包。作用和在 spring 的 xml 配置文件中的:
<context:component-scan base-package="com.itheima"/>是一樣的。寫在@Configuration下面一行,@ComponentScan("com.itheima")

@Bean:該註解只能寫在方法上,表明使用此方法創建一個對象,並且放入 spring 容器。name:給當前@Bean 註解方法創建的對象指定一個名稱(即 bean 的 id)。

3.談一談你對Spring中的AOP的理解

AOP:全稱是 Aspect Oriented Programming 即:面向切面編程。簡單的說它就是把我們程序重複的代碼抽取出來,在需要執行的時候,使用動態代理的技術,在不修改源碼的基礎上,對我們的已有方法進行增強。

連接點(JointPoint):指的是項目中的所有方法,我們可以爲每一個方法都加上寫日誌的代碼,所以每一個候選者都是連接點

切入點(pointcut):那我們肯定不是每個方法都要加日誌,那些需要處理的連接點我們稱作切入點

通知(Advice):寫日誌的代碼就叫做通知,意思就是具體增強的那部分代碼

切面(Aspect)切入點+通知=切面

<bean id="log" class="com.wanglei.utils.Logger"></bean>
<!--配置AOP-->
<aop:config>
        <!--配置切入點-->
        <aop:pointcut id="accountServicePoint" expression="execution(* com.wanglei.service.impl.*.*(..))"></aop:pointcut>
        <!--配置切面=通知+切入點-->
        <aop:aspect id="logAdvice" ref="log">
            <!--前置通知-->
            <aop:before method="printLog1" pointcut-ref="accountServicePoint"></aop:before>
            <!--後置通知-->
            <aop:after-returning method="printLog2" pointcut-ref="accountServicePoint"></aop:after-returning>
            <!--異常通知-->
            <aop:after-throwing method="printLog3" pointcut-ref="accountServicePoint"></aop:after-throwing>
            <!--最終通知-->
            <aop:after method="printLog4" pointcut-ref="accountServicePoint"></aop:after>

        </aop:aspect>
</aop:config>

二、SpringMVC

1.SpringMVC的處理流程

(1)客戶端發送請求至前端控制器DispatcherServlet;
(2) DispatcherServlet收到請求後,調用HandlerMapping處理器映射器,請求獲取Handle;
(3)處理器映射器根據請求url找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生成)一併返回給DispatcherServlet;
(4)DispatcherServlet 調用 HandlerAdapter處理器適配器
(5)HandlerAdapter 經過適配調用 具體處理器(Handler,也叫後端控制器);
(6)Handler執行完成返回ModelAndView;
(7)HandlerAdapter將Handler執行結果ModelAndView返回給DispatcherServlet;
(8)DispatcherServlet將ModelAndView傳給ViewResolver視圖解析器進行解析;
(9)ViewResolver解析後返回具體View;
(10)DispatcherServlet對View進行渲染視圖(即將模型數據填充至視圖中)
(11)DispatcherServlet響應用戶。

 

2.請求參數的綁定

基本數據類型和String,要求請求路徑中必須是key=value格式

    <a href="param?info=wanglei">向後臺傳遞wanglei</a>

    @RequestMapping(path = "/param")
    public String paramMethod(String info){
        System.out.println(info);
        return "success";
    }

POJO對象,要求表單中的name屬性和user實體類中的屬性必須相同纔可以通過set方法注入

    <form action="beanparam" method="post">
        用戶名:<input name="username" type="text"><br>
        年&nbsp齡:<input name="userage" type="text"><br>
        賬戶名:<input name="account.accountname" type="text"><br>
        賬戶密碼:<input name="account.accountpass" type="text"><br>
        <input type="submit" name="提交">
    </form>

    @RequestMapping(path = "/beanparam")
    public String parambeanMethod(User user){
        System.out.println(user);
        return "success";
    }

請求路徑佔位符綁定參數:要求請求路徑必須是/delProducts.do/3格式

    //使用佔位符,保證佔位符和@PathVariable("ids")一樣
    @RequestMapping("/delProducts.do/{ids}")
    @ResponseBody
    public String delProducts(@PathVariable("ids") String ids){
        if (ids.contains(",")){
            String[] split = ids.split(",");
            Integer id = Integer.valueOf(split[0]);
            productService.delProducts(id);
            System.out.println("================id"+id);
        }else {

        }

        return "刪除ok";
    }

3.請求參數中文亂碼

<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

4.Cookie和Session

Cookie和Session都是屬於javaweb中的會話技術,會話:一次會話類似於生活中的一次談話,會話技術的作用是在一次會話中共享數據,分爲客戶端會話技術(cookie)和服務器端會話技術(session)。

HTTP協議是無狀態的協議。一旦數據交換完畢,客戶端與服務器端的連接就會關閉,再次交換數據需要建立新的連接。這就意味着服務器無法從連接上跟蹤會話。

區別:Cookie保存在客戶端瀏覽器中,而Session保存在服務器上。Cookie機制是通過檢查客戶身上的“通行證”來確定客戶身份的話,那麼Session機制就是通過檢查服務器上的“客戶明細表”來確認客戶身份。Session相當於程序在服務器上建立的一份客戶檔案,客戶來訪的時候只需要查詢客戶檔案表就可以了。
 

5.轉發和重定向

轉發:是在服務器內部控制權的轉移,是由服務器區請求,客戶端並不知道是怎樣轉移的,因此客戶端瀏覽器的地址不會顯示出轉向的地址。地址欄不會發生變化。
重定向:是服務器告訴了客戶端要轉向哪個地址,客戶端再自己去請求轉向的地址,因此會顯示轉向後的地址,也可以理解瀏覽器至少進行了兩次的訪問請求。地址欄會變化。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章