1. 程式人生 > 其它 >Java面試題【4】

Java面試題【4】

28)Java 棧和堆的區別

1 棧:為編譯器自動分配和釋放,如函式引數、區域性變數、臨時變數等等
2 堆:為成員分配和釋放,由程式設計師自己申請、自己釋放。否則發生記憶體洩露。典型為使用new申請的堆內容。

3 靜態儲存區:記憶體在程式編譯的時候就已經分配好,這塊記憶體在程式的整個執行期間都存在。它主要存放靜態資料、全域性資料和常量。

二、JavaWeb

29)解釋一下什麼是 servlet

servlet 有良好的生存期的定義,包括載入和例項化、初始化、處理請求以及服務結束。這個生存期由 javax.servlet.Servlet 介面的 init,service 和 destroy 方法表達。

30)描述一下 servlet 生命週期

Servlet 被伺服器例項化後,容器執行其 init 方法,請求到達時執行其 service 方法,service 方法自動派遣執行與請求對應的 doXXX 方法(doGet,doPost)等,當伺服器決定將例項銷燬的時候呼叫其 destroy 方法。

31)servlet基本架構

public class ServletName extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}
}

32)SERVLET API 中 forward() 與 redirect()的區別?

前者僅是容器中控制權的轉向,在客戶端瀏覽器位址列中不會顯示出轉向後的地址;

後者則是完全的跳轉,瀏覽器將會得到跳轉的地址,並重新發送請求連結。這樣,從瀏覽器的位址列中可以看到跳轉後的連結地址。

33)jsp 有哪些動作?作用分別是什麼?

  1. jsp:include:在頁面被請求的時候引入一個檔案。

  2. jsp:useBean:尋找或者例項化一個 JavaBean。

  3. jsp:setProperty:設定 JavaBean 的屬性。

  4. jsp:getProperty:輸出某個 JavaBean 的屬性。

  5. jsp:forward:把請求轉到一個新的頁面。

  6. jsp:plugin:根據瀏覽器型別為 Java 外掛生成 OBJECT 或 EMBED 標記


三、資料庫

34)JdbcUtils (mysql)

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.sql.*;
import java.util.Properties;
public class JdbcUtils {
    /**
     *  建立一個jdbc的工具類,簡化建立連線和釋放資源的操作
     */
    private static String url;
    private static String user;
    private static String password;

    //建立靜態程式碼塊,在類載入的時候執行一次,用來讀取配檔案
    static {
        try {
            //建立properties集合類
            Properties properties = new Properties();
            //注意,用類載入器來動態獲取src下的配置檔案路徑
            ClassLoader classLoader = JdbcUtils.class.getClassLoader();
            URL resource = classLoader.getResource("jdbc.properties");
            String path1 = resource.getPath();
            //用urlDecoder來解決中文jdbc中文路徑亂碼的問題
            String path = URLDecoder.decode(path1, "utf-8");
            System.out.println(path);
            //載入配置檔案
           // properties.load(new FileReader("src/jdbc.properties"));
            //用path來動態的獲取路徑
            properties.load(new FileReader(path));
            //獲取資訊
             url = properties.getProperty("url");
             user = properties.getProperty("user");
             password = properties.getProperty("password");
            String driver = properties.getProperty("driver");

            //註冊驅動
            Class.forName(driver);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

    //1.定義建立連線的方法
    public  static Connection getConnection(){
        try  {
            System.out.println("url"+url);
            Connection connection = DriverManager.getConnection(url, user, password) ;
            return connection;
        }catch (Exception e){
            return null;
        }

    }
    //2.定義釋放資源的方法

    public static void close(Statement statement ,Connection connection){
        if (statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
    //3.釋放資源方法過載
    public static void close(ResultSet rs ,Statement statement ,Connection connection){
        if (rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

35)Jdbc 連線 oracle

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class dbUtil {
  public static Connection getConnection(){
	  Connection conn=null;
	  
	  try {
		String url="jdbc:oracle:thin:@127.0.0.1:1521:orcl";
		  String user="scott";
		  String password="tiger";
		  
		  Class.forName("oracle.jdbc.driver.OracleDriver");//載入資料驅動
		  conn = DriverManager.getConnection(url, user, password);// 連線資料庫
		  
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
		System.out.println("載入資料庫驅動失敗");
	}catch(Exception e){
		e.printStackTrace();
		System.out.println("連線資料庫失敗");
	}
	  return conn;
  }
  public static void close(Connection conn, PreparedStatement ps, ResultSet rs){
	  try {
		if(rs!=null){
			  rs.close();
		  }
	} catch (SQLException e) {
		e.printStackTrace();
	}
	  
	  try {
			if(ps!=null){
				  ps.close();
			  }
		} catch (SQLException e) {
			e.printStackTrace();
		}
	  
	  try {
			if(conn!=null){
				  conn.close();
			  }
		} catch (SQLException e) {
			e.printStackTrace();
		} 
  }
}

36)大資料量下的分頁解決方法

"select * from students order by id limit " + pageSize*(pageNumber-1) + "," + pageSize;

37)ORM是什麼,有什麼作用?

  • 物件關係對映(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向物件與關係資料庫存在的互不匹配的現象的技術。簡單的說,ORM是通過使用描述物件和資料庫之間對映的元資料,將程式中的物件自動持久化到關係資料庫中。

  • ORM是面向物件程式設計語言和關係資料庫發展不同步時的中間解決方案。採用ORM框架後,應用程式不再直接訪問底層資料庫,而是以面向物件的方式來操作持久化物件(建立、修改、刪除等),而ORM框架則將這些面向物件的操作轉換成底層的SQL操作。

    ===

    作者:Dcl_Snow
    連結:https://www.jianshu.com/p/90c4ca01824d
    來源:簡書
    著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

    ===

四、J2EE

38)C/S 與 B/S 區別

1.硬體環境不同
C/S 一般建立在專用的網路上, 小範圍裡的網路環境, 區域網之間再通過專門伺服器提供連線和資料交換服務.
B/S 建立在廣域網之上的, 不必是專門的網路硬體環境,例與電話上網, 租用裝置. 資訊自己管理. 有比 C/S 更強的適應範圍, 一般只要有作業系統和瀏覽器就行
2.對安全要求不同
C/S 一般面向相對固定的使用者群, 對資訊保安的控制能力很強. 一般高度機密的資訊系統採用 C/S 結構適宜. 可以通過 B/S 釋出部分可公開資訊.
B/S 建立在廣域網之上, 對安全的控制能力相對弱, 可能面向不可知的使用者。

3.對程式架構不同
C/S 程式可以更加註重流程, 可以對許可權多層次校驗, 對系統執行速度可以較少考慮.
B/S 對安全以及訪問速度的多重的考慮, 建立在需要更加優化的基礎之上. 比 C/S 有更高的要求 B/S 結構的程式架構是發展的趨勢, 從 MS 的.Net 系列的 BizTalk 2000 Exchange 2000 等, 全面支援網路的構件搭建的系統. SUN 和IBM 推的JavaBean 構件技術等,使 B/S 更加成熟.
4.軟體重用不同
C/S 程式可以不可避免的整體性考慮, 構件的重用性不如在 B/S 要求下的構件的重用性好

B/S 對的多重結構,要求構件相對獨立的功能. 能夠相對較好的重用.就入買來的餐桌可以再利用,而不是做在牆上的石頭桌子
5.系統維護不同
C/S 程式由於整體性, 必須整體考察, 處理出現的問題以及系統升級. 升級難. 可能是再做一個全新的系統
B/S 構件組成,方面構件個別的更換,實現系統的無縫升級. 系統維護開銷減到最小.使用者從網上自己下載安裝就可以實現升級.
6.處理問題不同
C/S 程式可以處理使用者面固定, 並且在相同區域, 安全要求高需求, 與作業系統相關. 應該都是相同的系統
B/S 建立在廣域網上, 面向不同的使用者群, 分散地域, 這是 C/S 無法作到的. 與作業系統平臺關係最小.
7.使用者介面不同
C/S 多是建立的 Window 平臺上,表現方法有限,對程式設計師普遍要求較高
B/S 建立在瀏覽器上, 有更加豐富和生動的表現方式與使用者交流. 並且大部分難度減低, 減低開發成本.
8.資訊流不同
C/S 程式一般是典型的中央集權的機械式處理, 互動性相對低
B/S 資訊流向可變化, B-B B-C B-G 等資訊、流向的變化, 更像交易中心。

39)WEB伺服器和應用伺服器的區別

應用伺服器處理業務邏輯,web伺服器則主要是讓客戶可以通過瀏覽器進行訪問,處理HTML檔案,web伺服器通常比應用伺服器簡單。
WEB伺服器:Apache、IIS、Nginx(也是反向代理伺服器)
應用伺服器:Tomcat、Weblogic、Jboss

舉例:一般來說,大的站點都是將Tomcat與Apache的結合,Apache負責接受所有來自客戶端的HTTP請求,然後將Servlets和JSP的請求轉發給Tomcat來處理。Tomcat完成處理後,將響應傳回給Apache,最後Apache將響應返回給客戶端。

五、MyBatis

40)談談 MyBatis

Mybatis 是一個半自動化的 ORM 框架,它對 jdbc 的操作資料庫的過程進行封裝,使得開發者只需要專注於 SQL 語句本身,而不用去關心註冊驅動,建立 connection 等,Mybatis 通過 xml 檔案配置或者註解的方式將要執行的各種 statement 配置起來,並通過 java 物件和 statement 中的sql 進行對映成最終執行的 sql 語句,最後由 Mybatis 框架執行 sql 並將結果對映成 java 物件並返回。每個 MyBatis 應用程式主要都是使用 SqlSessionFactory 例項的,一個 SqlSessionFactory 例項可以通過 SqlSessionFactoryBuilder 獲得。SqlSessionFactoryBuilder 可以從一個 xml 配置檔案或者一個預定義的配置類的例項獲得。
Mybatis 分為三層
(1) API 介面層:提供給外部使用的介面 API
(2) 資料處理層:負責具體的 SQL
(3) 基礎支撐層:負責最基礎的功能支撐,如連線管理,事務管理,配置載入和快取處。理

41)Mybatis 的優點

  • 基於 SQL 語句程式設計,相當靈活,不會對應用程式或者資料庫的現有設計造成任何影響,SQL 寫在 XML 裡,解除 sql 與程式程式碼的耦合,便於統一管理;提供 XML 標籤,支援編寫動態 SQL 語句,並可重用。
  • 與 JDBC 相比,減少了 50%以上的程式碼量,消除了 JDBC 大量冗餘的程式碼,不需要手動開關連線;
  • 很好的與各種資料庫相容(因為 MyBatis 使用 JDBC 來連線資料庫,所以只要 JDBC 支援的資料庫 MyBatis 都支援)。
    能夠與 Spring 很好的整合;
  • 提供對映標籤,支援物件與資料庫的 ORM 欄位關係對映;提供物件關係對映標籤,支援物件關係元件維護。

42)Mybatis 的優點

  1. Sql 語句的編寫工作量較大,尤其當欄位多、關聯表多時,對開發人員編寫 Sql 語句的功底有一定要求。
  2. 對效能的要求很高,或者需求變化較多的專案,如網際網路專案,MyBatis 將是不錯的選擇。

43)Mybatis 的程式設計過程是怎樣的

  1. 建立 SqlSessionFactory
  2. 通過 SqlSessionFactory 建立 SqlSession
  3. 通過 sqlsession 執行資料庫操作
  4. 呼叫 sqlsession.commit()提交事務
  5. 呼叫 sqlsession.close()關閉會話

44)Mybatis 中#和$的區別?

  1. ${}是 Properties 檔案中的變數佔位符,它可以用於標籤屬性值和 sql 內部,屬於靜態文字替換

  2. {}是 sql 的引數佔位符,Mybatis 會將 sql 中的#{}替換為?號,在 sql 執行前會使用PreparedStatement 的引數設定方法,按序給 sql 的? 號佔位符設定引數值。

  3. 方式能夠很大程度防止 sql 注入。

    $方式無法防止 Sql 注入。
    $方式一般用於傳入資料庫物件,例如傳入表名。

  4. 為什麼 # 可以防止SQL注入?參考作者:https://www.cnblogs.com/coder-who/

    • 1.什麼是SQL注入

      答:SQL注入是通過把SQL命令插入到web表單提交或通過頁面請求的查詢字串,最終達到欺騙伺服器執行惡意的SQL指令。

        注入攻擊的本質是把使用者輸入的資料當做程式碼執行。

        舉例如: 表單有兩個使用者需要填寫的表單資料,使用者名稱和密碼,如果使用者輸入admin(使用者名稱),111(密碼),若資料庫中存在此使用者則登入成功。SQL大概是這樣

            SELECT * FROM XXX WHERE userName = admin and password = 111

           但若是遭到了SQL注入,輸入的資料變為 admin or 1 =1 # 密碼隨便輸入,這時候就直接登入了,SQL大概是這樣

            SELECT * FROM XXX WHERE userName = admin or 1 = 1 # and password = 111 ,因為 # 在sql語句中是註釋,將後面密碼的驗證去掉了,而前面的條件中1 = 1始終成立,所以不管密碼正確與否,都能登入成功。

      2.mybatis中的#{} 為什麼能防止sql注入,${}不能防止sql注入

      答: #{}在mybatis中的底層是運用了PreparedStatement 預編譯,傳入的引數會以 ? 形式顯示,因為sql的輸入只有在sql編譯的時候起作用,當sql預編譯完後,傳入的引數就僅僅是引數,不會參與sql語句的生成,而${}則沒有使用預編譯,傳入的引數直接和sql進行拼接,由此會產生sql注入的漏洞。

    • 再次理解sql預編譯前後傳引數的區別?參考作者:https://blog.csdn.net/weixin_46099269

      • select * from user where uid=#{id} and password=#{pwd};
        這時資料庫就會進行預編譯,並進行一個快取動作,快取一條這樣的語句:
        select * from user where uid=? and password=?;
        當我們呼叫這條語句,並實際向#{id}中的id傳了一個值 “deftiii” or 1=1# 時,不需要在編譯,資料庫會直接找對應的表中有沒有名字是 “deftiii” or 1=1# 的使用者,而不再有編譯sql語句的過程。

45)使用 MyBatis 的 mapper 介面呼叫時有哪些要求?

  • Mapper介面方法名和 mapper.xml 中定義的每個 sql 的 id 相同
  • Mapper 介面方法的輸入引數型別和 mapper.xml 中定義的每個 sql 的 parameterType 的型別相同
  • Mapper 介面方法的輸出引數型別和 mapper.xml 中定義的每個 sql 的 resultType 的型別相同
  • Mapper.xml 檔案中的 namespace 即是 mapper 介面的類路徑

46)簡述 Mybatis 的 Xml 對映檔案和 Mybatis 內部資料結構間的對映關係?

  • Mybatis 將所有 Xml 配置資訊都封裝到 All-In-One 重量級物件 Configuration 內部。
  • 標籤會被解析為 ParameterMap 物件,其每個子元素會被解析為ParameterMapping 物件。
  • 標籤會被解析為 ResultMap 物件,其每個子元素會被解析為ResultMapping 物件。
  • 每一個