后台開發面試題(.net與java)


最近面試了幾家公司,發現大部分公司面試題有相似的地方。現在此記錄下我還記得的一些題:

JAVA部分:

1.Java Map 按Key排序和按Value排序:

參考鏈接: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();
        }

    }

}
View Code

 

參考鏈接: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 
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
View Code

 

參考鏈接: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;
    }


} 
View Code

 

第一種形式要更加安全些
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 
View Code

 

 

.NET部分:

其實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注入?

 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM