記錄某公司(簡稱SMKJ) 的一次面試

昨天去了一家公司面試 Java 開發崗位,這篇文章主要是作一個面試的記錄以及總結。html

這家公司的規模大概100-200人,環境還能夠,在一棟大廈租了兩層辦公室(31層和32層)。一同搭電梯上去的還有一位去應聘測試崗位的妹紙🙂java

這裏要吐槽一下該公司的前臺,因爲跟HR約好了是在31樓面試,我和測試妹紙都去了31樓的前臺,31樓的前臺直接讓咱們去樓上找32樓的前臺,32樓的前臺找了樓下31樓的面試官,結果又把咱們帶回樓下31樓面試。mysql

首先填了一份我的信息表,而後直接進入面試環節(沒有筆試 🙃)。linux

如下是面試時一些問題的記錄:git

一、面向對象的三大特性

答:封裝、繼承、多態。github

二、XML解析

答:
一、解析方式面試

  • DOM:Document Object Model,文檔對象模型。這種方式是W3C推薦的處理XML的一種標準方式。

缺點:必須讀取整個XML文檔,才能構建DOM模型,若是XML文檔過大,形成資源的浪費。
優勢:適合對XML中的數據進行操做(CRUD)。spring

  • SAX:Simple API for XML。這種方式不是官方標準,屬於開源社區XML-DEV,幾乎全部的XML解析器都支持它。

二、解析工具sql

  • JAXP:

DOM或SAX方式進行解析XML。API在JDK之中。數據庫

  • Dom4J:(推薦)

是開源組織推出的解析開發包。(牛,你們都在用,包括SUN公司的一些技術的實現都在用)

三、反射

答:當咱們的程序在運行時,須要動態的加載一些類,這些類可能以前用不到因此不用加載到jvm,而是在運行時根據須要才加載,這樣的好處對於服務器來講不言而喻。

舉個例子,咱們的項目底層有時是用mysql,有時用oracle,須要動態地根據實際狀況加載驅動類,這個時候反射就有用了,假設 com.java.dbtest.myqlConnection,com.java.dbtest.oracleConnection這兩個類咱們要用,這時候咱們的程序就寫得比較動態化,經過Class tc = Class.forName("com.java.dbtest.TestConnection");經過類的全類名讓jvm在服務器中找到並加載這個類,而若是是oracle則傳入的參數就變成另外一個了。這時候就能夠看到反射的好處了,這個動態性就體現出java的特性了!

舉多個例子,你們若是接觸過spring,會發現當你配置各類各樣的bean時,是以配置文件的形式配置的,你須要用到哪些bean就配哪些,spring容器就會根據你的需求去動態加載,你的程序就能健壯地運行。

四、Java 8 新特性

  • Lambda 表達式:Lambda容許把函數做爲一個方法的參數(函數做爲參數傳遞進方法中)。

  • 方法引用:方法引用提供了很是有用的語法,能夠直接引用Java的類方法、對象方法或者構造器。

五、Lambda 表達式

Lambda 表達式咱們能夠理解爲對於函數式接口和其中的抽象方法的具體實現。

Lambda 表達式能夠認爲是一種特殊的匿名內部類,Lambda只能用於函數式接口。

lambda語法以下:

     ([形參列表,不帶數據類型]) -> {
         //執行語句
         [return..;]
     }

代碼演示以下:

public class TestLambda {  
     public static void main(String[] args) {  
           TestLambdaInterface1 t1 = new TestLambdaInterface1() {  
                @Override  
                public void test() {  
                     System.out.println("使用匿名內部類");  
  
                }  
           };  
           
           //與上面的匿名內部類執行效果同樣  
           //右邊的類型會自動根據左邊的類型進行判斷  
           TestLambdaInterface1 t2 = () -> {  
                System.out.println("使用lambda");  
           };  
           t1.test();  
           t2.test(); 
     }
}

@FunctionalInterface  
interface TestLambdaInterface1 {  
     //不帶參數的抽象方法  
     void test();  
}

六、設計模式

單例模式

單例模式:確保一個類只有一個實例,並提供了一個全局訪問點。

實現:

  • 使用一個私有靜態變量、一個私有構造函數以及一個公有靜態函數來實現。

  • 私有構造函數保證了不能經過構造函數來建立對象實例,只能經過公有靜態函數返回惟一的私有靜態變量。

public class Singleton {

    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

代理模式

發佈訂閱模式

MVC 模式

七、Hibernate 的一級緩存、二級緩存

Session 的緩存被稱爲 Hibernate 的第一級緩存。SessionFactory 的外置緩存稱爲 Hibernate 的二級緩存。這兩個緩存都位於持久層,它們存放的都是數據庫數據的拷貝。SessionFactory 的 內置緩存 存放元數據和預約義 SQL,SessionFactory 的內置緩存是隻讀緩存。

緩存的做用:

  • 減小數據庫的訪問頻率,提升訪問性能。

  • 保證緩存中的對象與數據庫同步,位於緩存中的對象稱爲持久化對象。

八、ConcurrentHashMap 的 key 可不能夠爲 null ?

  • HashMap 能夠容許插入 null key 和 null value

  • HashTable 和 ConcurrentHashMap 都不能夠插入 null key 和 null value

九、線程池的線程命名

1、建立線程的時候沒有傳入名字

ThreadPoolManager.potatoPool.execute(new MyThread());

在這種狀況下,線程池會給線程自動命名,若是想改變線程的名稱,那麼須要在線程中的run方法中給線程setName。以下:

public class MyThread extends Thread{  
    public String threadName;  
    public MyThread (String threadName){  
        this.threadName=threadName;  
    }  
    
    @Override  
    public void run() {  
        Thread.currentThread().setName(threadName);  
    }  
  
}

2、建立線程的時候直接傳入名字

ThreadPoolManager.potatoPool.execute(new MyThread("aa"));

十、Linux上安裝好MySQL,只能本機訪問,其餘機器不能訪問的問題

一、權限問題,修改權限

二、防火牆的緣由,修改防火牆配置

十一、線程池核心線程數(core) 和 最大線程數(max)

當全部的核心線程(core) 都在幹活時,新添加的任務會被添加到隊列中等待處理,若是隊列滿了,則新建非核心線程執行任務。

十二、線程池捕獲異常

public class CaptureUncaughtException {  
    public static void main(String[] args) {  
        Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());  
        ExecutorService exec = Executors.newCachedThreadPool();  
        exec.execute(new ExceptionThread2());  // ExceptionThread2 爲任務對象
    }  
}  

/**  
 * MyUncaughtExceptionHandler:捕獲線程異常處理的類,須要實現 UncaughtExceptionHandler 接口
 * @author nnngu  
 */  
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {  
    @Override  
    public void uncaughtException(Thread t, Throwable e) {  
        System.out.println(t+"捕獲到了異常,異常處理的對象爲:"+e); // e:拋出的對象 
    }  
}

1三、Mybatis 的 Mapper

參考:

爲何mybatis的mapper沒有實現類(原理探究)

Mybatis中Mapper映射文件詳解

1四、Jsp和servlet ,jsp的 9大內置對象

Servlet 的生命週期:init、service(doGet、doPost)、destory

JSP 的九大內置對象:

內置對象名 類型
request HttpServletRequest
response HttpServletResponse
config ServletConfig
application ServletContext
session HttpSession
exception Throwable
page Object(this)
out JspWriter
pageContext PageContext

JSP 的四大域對象:

對象
ServletContext context域
HttpServletRequet request域
HttpSession session域
PageContext page域

1五、文件上傳、socket、流

參考:

java文件上傳和下載

1六、Netty

參考:

Netty——基本使用介紹

1七、集合

答:List、Set、Map

List 是有序的,能夠有重複元素

Set 是無序的,不容許有重複元素

Map 是鍵值對

1八、IO 和 NIO

IO 和 NIO 的本質就是阻塞和非阻塞的區別。

阻塞概念:應用程序在獲取網絡數據的時候,若是網絡傳輸數據很慢,那麼程序就一直等着,直到傳輸完畢爲止。

非阻塞概念:應用程序直接能夠獲取已經準備就緒的數據,無需等待。

參考:
Java NIO 系列教程

1九、寫在最後

最後,我發現面試官也有一些錯誤,在此也把它記錄下來:

  • 面試官說 NIO 是 JDK 1.5 以後引入的。(其實 NIO 是 JDK 1.4 開始引入的)
  • 關於線程池的核心線程數(core) 和 最大線程數(max)的問題,面試官說當線程池裏的線程數達到核心線程數(core) 時,新來了任務就會繼續建立線程來處理。(其實當線程數達到核心線程數以後,新來的任務會加入隊列等待處理,只有當隊列滿了纔會繼續建立線程)

先寫到這裏,之後有什麼補充再更新。

本文永久更新地址:https://github.com/nnngu/LearningNotes/blob/master/_posts/2018-03-30-%E6%9F%90%E5%85%AC%E5%8F%B8(%E7%AE%80%E7%A7%B0SMKJ)%E9%9D%A2%E8%AF%95%E8%AE%B0%E5%BD%95.md

相關文章
相關標籤/搜索