最近面試了幾家公司,發現大部分公司面試題有相似的地方。現在此記錄下我還記得的一些題:
1.Java Map 按Key排序和按Value排序:
2.從一個文件中統計每個單詞的次數,排序輸出:

package com.test.string; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * java實現讀取英文文章,統計其中每個單詞出現的次數並輸出 * @author halbert * */ public class FileWordCount { public void count() throws IOException{ BufferedReader reader = new BufferedReader(new FileReader("D:\\test\\english.txt")); StringBuffer buffer = new StringBuffer(); String line = null; while( (line = reader.readLine()) != null ){ buffer.append(line); } reader.close(); Pattern expression = Pattern.compile("[a-zA-Z]+"); //定義正則表達式匹配單詞 String string = buffer.toString(); Matcher matcher = expression.matcher(string); Map<string integer=""> map = new TreeMap<string integer="">(); String word = ""; int n = 0; Integer times = 0; while(matcher.find()){ //是否匹配單詞 word = matcher.group(); //得到一個單詞,樹映射中的鍵 n++; if( map.containsKey(word) ){ //如果該鍵存在,則表示單詞出現過 times = map.get(word); //得到單詞出現的次數 map.put(word, times+1); } else { map.put(word, 1); //否則單詞是第一次出現,直接放入map } } List<Map.Entry<string integer="">> list = new ArrayList<Map.Entry<string integer="">>(map.entrySet()); Comparator<Map.Entry<string integer="">> comparator = new Comparator<Map.Entry<string integer="">>(){ @Override public int compare(Entry<string integer=""> left, Entry<string integer=""> right) { return (left.getValue()).compareTo(right.getValue()); } }; Collections.sort(list, comparator); System.out.println("統計分析如下:"); System.out.println("t 文章中單詞總數" + n + "個"); System.out.println("具體的信息在原文件目錄的result.txt文件中"); BufferedWriter bufw = new BufferedWriter(new FileWriter("D:\\test\\result.txt")); for(Entry<string integer=""> me : list){ bufw.write(me+""); bufw.newLine(); } bufw.write("english.txt中的單詞總數" + n + "個"); bufw.newLine(); bufw.write("english.txt中不同單詞" + map.size() + "個"); bufw.close(); } public static void main(String[] args) { try { FileWordCount fwc = new FileWordCount(); fwc.count(); } catch (IOException e) { e.printStackTrace(); } } }
參考鏈接:java程序員的從0到1:統計某字符串在某文件中出現的次數(面試題)
3.手寫arraylist:
參考鏈接:java面試題答疑(手寫arraylist、進制轉換、多線程、動態代理)
4.手寫一把可重入鎖:

public class MyLock implements Lock { private boolean isLocked = false; //定義一個變量,標記鎖是否被使用 private Thread runningThread = null; //第一次線程進來的時候,正在運行的線程為null private int count = 0; //計數器 @Override public synchronized void lock() { Thread currentThread = Thread.currentThread(); //不斷的重復判斷,isLocked是否被使用,如果已經被占用,則讓新進來想嘗試獲取鎖的線程等待,直到被正在運行的線程喚醒 //除了判斷當前鎖是否被占用之外,還要判斷正在占用該鎖的是不是本線程自己 while(isLocked && currentThread != runningThread) { //如果鎖已經被占用,而占用者又是自己,則不進入while循環 try { wait(); }catch (InterruptedException e) { e.printStackTrace(); } } //進入該代碼塊有三種情況: // 1.第一個線程進來,此時isLocked變量的值為false,線程沒有進入while循環體里面 // 2.線程進入那個循環體里面,調用了wait()方法並經歷了等待階段,現在已經被另一個線程喚醒, // 3.線程不是第一次進來,但是新進來的線程就是正在運行的線程,則直接來到這個代碼塊 // 喚醒它的線程將那個變量isLocked設置為true,該線程才跳出了while循環體 //跳出while循環體,本線程做的第一件事就是趕緊占用線程,並告訴其他線程說:嘿,哥們,我占用了,你必須等待,計數器+1,並設置runningThread的值 isLocked = true; //將isLocked變量設置為true,表示本線程已經占用 runningThread = currentThread; //給正在運行的線程變量賦值 count++; //計數器自增 } @Override public void lockInterruptibly() throws InterruptedException { } @Override public boolean tryLock() { return false; } @Override public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { return false; } @Override public synchronized void unlock() { //線程釋放鎖,釋放鎖的過程分為三步 //1. 判斷發出釋放鎖的請求是否是當前線程 //2. 判斷計數器是否歸零,也就是說,判斷本線程自己進來了多少次,是不是全釋放鎖了 //3. 還原標志變量 if(runningThread == Thread.currentThread()) { count--;//計數器自減 if(count == 0) { //判斷是否歸零 isLocked = false; //將鎖的狀態標志為未占用 runningThread = null; //既然已經真正釋放了鎖,正在運行的線程則為null notifyAll(); //通知所有等待的線程,誰搶到我不管 } } } @Override public Condition newCondition() { return null; } } --------------------- 作者:SpringChang 來源:CSDN 原文:https://blog.csdn.net/zhang5476499/article/details/83794711 版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
參考鏈接:Java並發編程:自己動手寫一把可重入鎖
5.說幾個JAVA中的單例模式,然后你最喜歡用哪個?為什么?
餓漢式和懶漢式。

//第一種形式: 餓漢式單例類 //餓漢式單例類.在類初始化時,已經自行實例化 public class Singleton { private Singleton(){} private static Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } } //第二種形式:懶漢式單例類 public class Singleton { private Singleton(){} private static Singleton instance = null; public static synchronized Singleton getInstance() { if (instance==null)instance=new Singleton(); return instance; } }
第一種形式要更加安全些
instance = new Singleton();
static屬於類的資源,類資源在jvm加載類的時候就加載好了,instance一直引用這new Singleton(),所以永遠都不會釋放一直存在與內存中直到程序結束運行;
第2種的話如果兩個線程同一時刻去訪問getInstance的時候就可能創建兩個實例,所以不安全;
解決辦法(加上同步鎖)。
參考鏈接:快速理解Java中的五種單例模式
6.說說你對Java中的棧內存和堆內存的看法:
參考鏈接:JAVA面試、進階必備——堆內存與棧內存
7.http在傳輸時是無狀態的,你是如何解決的:
可以使用Cookie來解決無狀態的問題,Cookie就相當於一個通行證,第一次訪問的時候給客戶端發送一個Cookie,當客戶端再次來的時候,拿着Cookie(通行證),那么服務器就知道這個是”老用戶“。
參考鏈接:Java面試之http知識點(必問) HTTP面試題都在這里
8.設計一個秒殺系統
參考鏈接:如何設計一個秒殺系統 秒殺系統設計(JAVA)
9.設計一個大數據高並發系統
秒殺系統和高並發系統均有視頻,百度雲鏈接:

鏈接: https://pan.baidu.com/s/1ooQaputdmsoHm9qT-PyXRw 提取碼: 686e
其實C#和Java中大部分語法類似,故就算只想走Java部分題也有參考價值。
1.面向對象的三個特性,請簡述。
封裝:將對象中的方法,屬性隱藏起來。外屆程序調用對象的方法,只能通過對象提供給外部的接口來調用。這樣可以可以讓人忽略代碼的具體細節實現,使代碼更易維護。同時因為不能直接調用、修改對象內部的私有屬性,在一定程度上保證了系統安全性。
繼承:主要用於代碼復用,將多次使用的公共代碼提取出來,以達到提高編碼效率目的。
多態:所謂的多態是指在繼承體系中,所有派生類都從基類繼承接口,但由於每個派生類都是獨立的實體,因此在接收同一消息的時候,可能會生成不同的響應。多態的作用作為隱藏代碼實現細節,使得代碼能夠模塊化;擴展代碼模塊,實現接口重用。
2.用.net做B/S結構的系統,您是用幾層結構來開發,每一層之間的關系以及為什么要這樣分層?
三層。從下至上分別為:數據訪問層、業務邏輯層(又或成為領域層)、表示層;
數據訪問層:有時候也稱為是持久層,其功能主要是負責數據庫的增刪查改操作;
業務邏輯層:是整個系統的核心,它與這個系統的業務(領域)有關
表示層:是系統的UI部分,負責使用者與整個系統的交互。
優點: 分工明確,條理清晰,易於調試,而且具有可擴展性。
缺點: 增加成本。
3.列舉ASP.NET 頁面之間傳遞值的幾種方式。
有頁面傳值、存儲對象傳值、ajax、類、model、表單等。但是一般來說,常用的較簡單有QueryString,Session,Cookies,Application,Server.Transfer。
QueryString 傳遞一個或多個安全性要求不高或是結構簡單的數值。但是對於傳遞數組或對象的話,就不能用這個方法了
session(viewstate) 簡單,但易丟失 作用於用戶個人,過量的存儲會導致服務器內存資源的耗盡。
application 對象的作用范圍是整個全局,也就是說對所有用戶都有效。其常用的方法用Lock和UnLock
cookie 簡單,但可能不支持,可能被偽造 Cookie是存放在客戶端的,而session是存放在服務器端的。而且Cookie的使用要配合ASP.NET內置對象Request來使用 input ttype="hidden" 簡單,可能被偽造 url參數簡單,顯示於地址欄,長度有限
Server.Transfer 把流程從當前頁面引導到另一個頁面中,新的頁面使用前一個頁面的應答流 數據庫穩定,安全,但性能相對弱
參考鏈接:ASP.NET頁面之間傳遞值的幾種方式
4.事件和委托的區別
事件是委托的封裝,可以理解為一種特殊的委托。
事件里面其實就兩個方法(即add_event()和remove_event())和一個私有的委托變量,這兩個方法里面分別是對這個私有的委托變量進行的合並和移除,當調用事件的+=時其實是調用的事件里面的add_event()方法,同樣-=調用的是remove_event()方法。
事件只能夠從對象外部增加新的響應方法和刪除已知的響應方法,而不能主動去觸發事件和獲取其他注冊的響應方法等信息。如果使用公有的delegate則不能做這些限制,也就是說事件對委托做了限制,使委托使用起來更加方便。也有人說事件是對委托的閹割,大概也是這個意思。
5.C#中的接口和類有什么異同
異:
不能直接實例化接口。
接口不包含方法的實現。
接口、類和結構可從多個接口繼承。但是C# 只支持單繼承:類只能從一個基類繼承實現。
類定義可在不同的源文件之間進行拆分。
同:
接口、類和結構可從多個接口繼承。
接口類似於抽象基類:繼承接口的任何非抽象類型都必須實現接口的所有成員。
接口可以包含事件、索引器、方法和屬性。
一個類可以實現多個接口。
6.SQL注入是什么意思以及防止SQL注入:
參考鏈接:sql注入是什么意思以及防止sql注入?
1. 取出表A中第31到第40記錄:
1、假設ID是連續的:
select top 10 * from A where ID not in (select top 30 ID from A)
或
select * from A where ID between 31 and 40
2、假設ID是不連續的:
select top 40 * from A except select top 30 * from A
或
select top 10 * from A where ID > (select max(ID) from A where ID in (select top 30 ID from A))
或
select top 10 * from A where ID not in (select top 30 ID from A)
2.
原表:
courseid coursename score
-------------------------------------
1 java 70
2 oracle 90
3 xml 40
4 jsp 30
5 servlet 80
-------------------------------------
為了便於閱讀,查詢此表后的結果顯式如下(及格分數為60):
courseid coursename score mark
---------------------------------------------------
1 java 70 pass
2 oracle 90 pass
3 xml 40 fail
4 jsp 30 fail
5 servlet 80 pass
---------------------------------------------------
寫出此查詢語句
---------------------
select courseid, coursename ,score ,decode(sign(score-60),-1,'fail','pass') as mark from course
sql題練習鏈接:https://blog.csdn.net/qq_30946681/article/details/80233652