2018年上海後半年JAVA軟體工程師面試真題
- 查詢超過該部門員工大於3個的部門
SELECT deptid FROM table1 GROUP BY deptid HAVING COUNT(deptid) > 3 |
如果員工名稱重複的部門id
SELECT deptid FROM table1
GROUP BY deptid
HAVING COUNT(empname) > 3
- 單例模式
|
1 需要寫個類
2 在類裡面new 一個自己,private final static
3 私有無參構造
4 static 方法,返回自己
3.氣泡排序
package com.day01;
public class 氣泡排序 {
public static void main(String[]
int[] arr = {3,2,1};
for (int i = 0; i < arr.length - i; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp; } }
}
System.out.println(arr[0]); System.out.println(arr[1]); System.out.println(arr[2]);
}
} |
4.找關鍵字次數
package com.day01;
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader;
public class 找關鍵字次數 {
public static void main(String[] args) throws Exception {
StringBuilder sBuilder = new StringBuilder(); // 建立拼接字串
File file = new File("F:\\get.txt"); // 讀取檔案
//建立IO留獨處檔案 InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "utf-8"); BufferedReader br = new BufferedReader(isr); //用於暫時儲存文字內容 String lineTxt = null; //迴圈讀取 while ((lineTxt = br.readLine()) != null) { sBuilder.append(lineTxt); } br.close();
String srcText = sBuilder.toString(); String findText = "d";
int num = appearNumber(srcText,findText); System.out.println(num); }
public static int appearNumber(String srcText,String findText){ int count = 0; int index = 0; while((index = srcText.indexOf(findText,index)) != -1){ index = index + findText.length(); count++; } return count; }
}
|
5.四個訪問修飾符
// 訪問許可權 類 包 子類 其他包 public String aString;
// 繼承的類可以訪問以及和private一樣的許可權 protected String bString;
// 包訪問許可權,即在整個包內均可被訪問 /*default*/ String cString;
//除型別建立者和型別的內部方法之外的任何人都不能訪問的元素 private String dString; |
6.Spring開啟註解的方式
在Spring的配置檔案中 <!-- 使用annotation定義事務 --> 事務: <tx:annotation-driven transaction-manager="defaultTransactionManager" proxy-target-class="true" />
<context:component-scan base-package =“xx.test.*”use-default-filters =“false”>
|
7.資料庫索引
第一,通過建立唯一性索引,可以保證資料庫表中每一行資料的唯一性。 第二,可以大大加快資料的檢索速度,這也是建立索引的最主要的原因。 第三,可以加速表和表之間的連線,特別是在實現資料的參考完整性方面特別有意義。 第四,在使用分組和排序子句進行資料檢索時,同樣可以顯著減少查詢中分組和排序的時間。 第五,通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的效能。
|
索引型別 |
普通索引,唯一索引,主鍵索引,組合索引 |
索引的建立 |
◆建立索引 |
8.執行緒中run和start的區別
每個執行緒都有要執行的任務。執行緒的任務處理邏輯可以在Tread類的run例項方法中直接實現或通過該方法進行呼叫,因此 run()相當於執行緒的任務處理邏輯的入口方法,它由Java虛擬機器在執行相應執行緒時直接呼叫,而不是由應用程式碼進行呼叫。 而start()的作用是啟動相應的執行緒。啟動一個執行緒實際是請求Java虛擬機器執行相應的執行緒,而這個執行緒何時能夠執行是由執行緒排程器決定的。start()呼叫結束並不表示相應執行緒已經開始執行,這個執行緒可能稍後執行,也可能永遠也不會執行。
|
9.執行緒狀態有哪些
第一是建立狀態。在生成執行緒物件,並沒有呼叫該物件的start方法,這是執行緒處於建立狀態。 |
10.索引的優缺點
建立索引可以大大提高系統的效能: |
11.JVM記憶體模型
12.跨域的出現和解決
跨域是指a頁面想獲取b頁面資源,如果a、b頁面的協議、域名、埠、子域名不同,或是a頁面為ip地址,b頁面為域名地址,所進行的訪問行動都是跨域的,而瀏覽器為了安全問題一般都限制了跨域訪問,也就是不允許跨域請求資源。 |
解決跨域:
Jsonp,把請求路徑轉成jsonp的格式,再進行請求
在Contoller中加: // 設定:Access-Control-Allow-Origin頭,處理Session問題 response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin")); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("P3P", "CP=CAO PSA OUR"); if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) { response.addHeader("Access-Control-Allow-Methods", "POST,GET,TRACE,OPTIONS"); response.addHeader("Access-Control-Allow-Headers", "Content-Type,Origin,Accept"); response.addHeader("Access-Control-Max-Age", "120"); } |
SpringBoot跨域解決方案: |
在Controller上加@CrossOrigin |
13.GC回收垃圾的時候System.gc()和 finalize()的區別
收集並刪除未引用的物件。可以通過呼叫"System.gc()"來觸發垃圾回收,但並不保證會確實進行垃圾回收。 JVM的垃圾回收只收集哪些由new關鍵字建立的物件。所以,如果不是用new建立的物件,你可以使用finalize函式來執行清理。 |
14.MyBatis中的$和#有什麼區別?
1 #是將傳入的值當做字串的形式,eg:select id,name,age from student where id =#{id},當前端把id值1,傳入到後臺的時候,就相當於 select id,name,age from student where id ='1'. 2 $是將傳入的資料直接顯示生成sql語句,eg:select id,name,age from student where id =${id},當前端把id值1,傳入到後臺的時候,就相當於 select id,name,age from student where id = 1. 3 使用#可以很大程度上防止sql注入。(語句的拼接) 4 但是如果使用在order by 中就需要使用 $. 5 在大多數情況下還是經常使用#,但在不同情況下必須使用$. |
15.SpringBean的生命週期
16.List中如何去重
方式一,利用HashSet不能新增重複資料的特性 由於HashSet不能保證新增順序,所以只能作為判斷條件: private static void removeDuplicate(List<String> list) { HashSet<String> set = new HashSet<String>(list.size()); List<String> result = new ArrayList<String>(list.size()); for (String str : list) { if (set.add(str)) { result.add(str); } } list.clear(); list.addAll(result); }
方式二,利用LinkedHashSet不能新增重複資料並能保證新增順序的特性 : private static void removeDuplicate(List<String> list) { LinkedHashSet<String> set = new LinkedHashSet<String>(list.size()); set.addAll(list); list.clear(); list.addAll(set); }
方式三,利用List的contains方法迴圈遍歷: private static void removeDuplicate(List<String> list) { List<String> result = new ArrayList<String>(list.size()); for (String str : list) { if (!result.contains(str)) { result.add(str); } } list.clear(); list.addAll(result); } --------------------- 作者:灰色流連 來源:CSDN 原文:https://blog.csdn.net/u012156163/article/details/78338574?utm_source=copy 版權宣告:本文為博主原創文章,轉載請附上博文連結! |
17.Redis儲存機制
Redis儲存機制分成兩種Snapshot和AOF。無論是那種機制,Redis都是將資料儲存在記憶體中。
|
- WebService實現方式
方式1: HttpClient:可以用來呼叫webservie服務,也可以抓取網頁資料 版本1:HttpClient3.0.x 版本2:HttpClient4.x.x(目前最新4.5.2) 這2個版本的使用方式不一樣;變動較大 方式2:純Java(自帶API) jws 方式3:cxf框架 方式4:axis2框架
準備工作: 1.瞭解wsimport java自帶的一個命令(建議使用jdk7,穩定支援) 作用:將wsdl檔案生成本地代理(java程式碼),方便呼叫 語法 wsimport [opations] <wsdl_uri> 4.放在你的專案中進行呼叫: [html] view plain copy
|
- 如何實現執行緒通訊
|
- volatile和synchronized
|
21.QuartZ如何實現
scheduler(排程器):將job和trigger繫結在一起 job(任務) :配置具體哪個類實現定時任務 trigger(觸發器) :配置定時器引數,如:多久執行一次,執行多上次等
|
開啟註解 |
|
22.HashMap的底層原理
https://blog.csdn.net/a2524289/article/details/78888480
23.Dubbo的配置檔案
24.Dubbo底層協議是什麼
NIO方式的TCP協議
25.redis底層協議是什麼
TCP
26.執行緒的活鎖和死鎖
https://blog.csdn.net/qq_29924795/article/details/72772251
27.MQ訊息的丟失和中途宕機解決
服務端丟失 |
把記憶體中的訊息持久化,重啟mq的時候進行從持久化檔案中讀取 |
客戶端丟失 |
使用者發出的訊息還依舊在快取中,mq可以重新進行read |
訊息確認 |
RabbitMQ引入了訊息確認機制,當訊息處理完成後,給Server端傳送一個確認訊息,來告訴服務端可以刪除該訊息了,如果連線斷開的時候,Server端沒有收到消費者發出的確認資訊,則會把訊息轉發給其他保持線上的消費者。 |
28.MQ一般用在哪裡
29.Shiro實現方法
1、 配置 applicationContext-shiro.xml 啟用註解 <!-- 開啟shiro註解模式 --> 2.業務層使用 shiro 註解 @RequiresPermissions("") 3.使用方法註解進行許可權控制, 當權限不足時,代理物件丟擲一個異常
|
30.Shiro資料庫表設計
31.請求型別方式有幾種
GET: 請求指定的頁面資訊,並返回實體主體。 |
32.執行緒池如何實現
https://blog.csdn.net/douunderstand/article/details/72190330
33.redis持久化如何實現
RDB持久化
AOF持久化
3、二者優缺點 RDB存在哪些優勢呢? 1). 一旦採用該方式,那麼你的整個Redis資料庫將只包含一個檔案,這對於檔案備份而言是非常完美的。比如,你可能打算每個小時歸檔一次最近24小時的數 據,同時還要每天歸檔一次最近30天的資料。通過這樣的備份策略,一旦系統出現災難性故障,我們可以非常容易的進行恢復。 2). 對於災難恢復而言,RDB是非常不錯的選擇。因為我們可以非常輕鬆的將一個單獨的檔案壓縮後再轉移到其它儲存介質上。 3). 效能最大化。對於Redis的服務程序而言,在開始持久化時,它唯一需要做的只是fork出子程序,之後再由子程序完成這些持久化的工作,這樣就可以極大的避免服務程序執行IO操作了。 4). 相比於AOF機制,如果資料集很大,RDB的啟動效率會更高。 RDB又存在哪些劣勢呢? 1). 如果你想保證資料的高可用性,即最大限度的避免資料丟失,那麼RDB將不是一個很好的選擇。因為系統一旦在定時持久化之前出現宕機現象,此前沒有來得及寫入磁碟的資料都將丟失。 2). 由於RDB是通過fork子程序來協助完成資料持久化工作的,因此,如果當資料集較大時,可能會導致整個伺服器停止服務幾百毫秒,甚至是1秒鐘。 AOF的優勢有哪些呢? 1). 該機制可以帶來更高的資料安全性,即資料永續性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事實上,每秒同步也是非同步完成的,其 效率也是非常高的,所差的是一旦系統出現宕機現象,那麼這一秒鐘之內修改的資料將會丟失。而每修改同步,我們可以將其視為同步持久化,即每次發生的資料變 化都會被立即記錄到磁碟中。可以預見,這種方式在效率上是最低的。至於無同步,無需多言,我想大家都能正確的理解它。 2). 由於該機制對日誌檔案的寫入操作採用的是append模式,因此在寫入過程中即使出現宕機現象,也不會破壞日誌檔案中已經存在的內容。然而如果我們本次操 作只是寫入了一半資料就出現了系統崩潰問題,不用擔心,在Redis下一次啟動之前,我們可以通過redis-check-aof工具來幫助我們解決資料 一致性的問題。 3). 如果日誌過大,Redis可以自動啟用rewrite機制。即Redis以append模式不斷的將修改資料寫入到老的磁碟檔案中,同時Redis還會創 建一個新的檔案用於記錄此期間有哪些修改命令被執行。因此在進行rewrite切換時可以更好的保證資料安全性。 4). AOF包含一個格式清晰、易於理解的日誌檔案用於記錄所有的修改操作。事實上,我們也可以通過該檔案完成資料的重建。 AOF的劣勢有哪些呢? 1). 對於相同數量的資料集而言,AOF檔案通常要大於RDB檔案。RDB 在恢復大資料集時的速度比 AOF 的恢復速度要快。 2). 根據同步策略的不同,AOF在執行效率上往往會慢於RDB。總之,每秒同步策略的效率是比較高的,同步禁用策略的效率和RDB一樣高效。 二者選擇的標準,就是看系統是願意犧牲一些效能,換取更高的快取一致性(aof),還是願意寫操作頻繁的時候,不啟用備份來換取更高的效能,待手動執行save的時候,再做備份(rdb)。rdb這個就更有些 eventually consistent的意思了。 4、常用配置 RDB持久化配置 Redis會將資料集的快照dump到dump.rdb檔案中。此外,我們也可以通過配置檔案來修改Redis伺服器dump快照的頻率,在開啟6379.conf檔案之後,我們搜尋save,可以看到下面的配置資訊: save 900 1 #在900秒(15分鐘)之後,如果至少有1個key發生變化,則dump記憶體快照。 save 300 10 #在300秒(5分鐘)之後,如果至少有10個key發生變化,則dump記憶體快照。 save 60 10000 #在60秒(1分鐘)之後,如果至少有10000個key發生變化,則dump記憶體快照。 AOF持久化配置 在Redis的配置檔案中存在三種同步方式,它們分別是: appendfsync always #每次有資料修改發生時都會寫入AOF檔案。 appendfsync everysec #每秒鐘同步一次,該策略為AOF的預設策略。 appendfsync no #從不同步。高效但是資料不會被持久化。
|
34.Spring傳播機制是如何實現的
https://www.cnblogs.com/softidea/p/5962612.html
https://blog.csdn.net/weixin_38070406/article/details/78157603
35.列印菱形
Scanner input = new Scanner(System.in); // TODO 自動生成的方法存根 System.out.println("請輸入行數:"); int m=input.nextInt(); //確定列印菱形的行數,可以自行設定 int n=m/2+1; int t=m/2; for(int i=1;i<=n;i++)//列印菱形的上半部分 { for(int j=(n-i);j>0;j--) System.out.print(" "); //列印空格數 for(int k=2*i-1;k>0;k--) System.out.print("*"); //列印*號 System.out.println( |