(持續更新) C# 面試技術點、常見SQL技術點 和 第三方相關開發技術點

這篇博客 持續更新.方便大家面試前 複習

1. 文中的錯誤 
2. 更好的答案
3. 建議增加的知識點
4. 有哪些更好的建議
 .......
 大家可以在評論區留言

目錄

C#

1. 簡述 private、 protected、 public、 internal 修飾符的訪問權限。

private : 私有成員, 在類的內部纔可以訪問。
protected : 保護成員,該類內部和繼承類中可以訪問。
public : 公共成員,完全公開,沒有訪問限制。
internal: 在同一命名空間內可以訪問。

2 .列舉ASP.NET 頁面之間傳遞值的幾種方式。

1.使用QueryString, 如…?id=1; response. Redirect()…
2.使用Session變量
3.使用Server.Transfer

3.C#中的委託是什麼?事件是不是一種委託?

委託可以把一個方法作爲參數代入另一個方法。 委託可以理解爲指向一個函數的引用。
是,是一種特殊的委託

4.override與重載的區別

重載是方法的名稱相同。參數或參數類型不同,進行多 次重載以適應不同的需要
Override 是進行基類中函數的重寫。爲了適應需要。

5.用.net做B/S結構的系統,您是用幾層結構來開發,每一層之間的關係以及爲什麼要這樣分層?

一般爲3層 數據訪問層,業務層,表示層。

數據訪問層對數據庫進行增刪查改。
業務層一般分爲二層,業務表觀層實現與表示層的溝通,業務規則層實現用戶密 碼的安全等。
表示層爲了與用戶交互例如用戶添加表單。

優點:

分工明確,條理清晰,易於調試,而且具有可擴展性。

缺點:

增加成本。

6.CTS、CLS、CLR分別作何解釋?

CTS:通用語言系統。
CLS:通用語言規範。
CLR:公共語言運行庫。

7.什麼是裝箱和拆箱?

從值類型接口轉換到引用類型裝箱。
從引用類型轉換到值類型拆箱。

8.什麼是受管制的代碼?

unsafe:非託管代碼。不經過CLR運行。

9.常用的調用WebService的方法有哪些?

1.使用WSDL.exe命令行工具。
2.使用VS.NET中的Add Web Reference菜單選項

10.在C#中,string str = null 與 string str = “” 請儘量使用文字或圖象說明其中的區別。

string str = null 是不給他分配內存空間,
string str = “” 給它分配 長度爲空字符串的內存空間。

11.類(class)與結構(struct)的區別

Class可以被實例化,屬於引用類型,是分配在內存的堆上的
Struct屬於值類型,是分配在內存的棧上的.

12.GC是什麼? 爲什麼要有GC?

GC是垃圾收集器。程序員不用擔心內存管理,因爲垃圾收集器會自動進行管 理。
要請求垃圾收集,可以調用下面的方法之一:
System.gc()
Runtime.getRuntime().gc()

13.String s = new String(“xyz”);創建了幾個String Object?

兩個對象,一個是“xyx”,一個是指向“xyx”的引用對象s。

14.啓動一個線程是用run()還是start()?

啓動一個線程是調用start()方法,使線程所代表的虛擬處理機處於可運行狀 態,這意味着它可以由JVM調度並執行。這並不意味着線程就會立即運行。
run()方法可以產生必須退出的標誌來停止一個線程。

15.是否可以繼承String類?

String類是final類故不可以繼承。

16.try {}裏有一個return語句,那麼緊跟在這個try後的finally {}裏的code會不會被執行,什麼時候被執行,在return前還是後?

會執行,在return前執行。

17.兩個對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?

不對,有相同的hash code。

18.當一個線程進入一個對象的一個synchronized方法後,其它線程是否可進入此對象的其它方法?

不能,一個對象的一個synchronized方法只能由一個線程訪問。

19.Session有什麼重大BUG,微軟提出了什麼方法加以解決?

是iis中由於有進程回收機制,系統繁忙的話Session會丟失
可以用SQL Server數據庫的方式存儲Session不過這種方式比較慢,
而且無法 捕獲Session的END事件。

20.進程和線程的區別?

進程是系統進行資源分配和調度的單位;
線程是CPU調度和分派的單位,一個 進程可以有多個線程,這些線程共享這個進程的資源。

21.堆和棧的區別?

棧:由編譯器自動分配、釋放。在函數體中定義的變量通常在棧上。
堆:一般由程序員分配釋放。用new、malloc等分配內存函數分配得到的就是在堆 上。

22.成員變量和成員函數前加static的作用?

它們被稱爲常成員變量和常成員函數,又稱爲類成員變量和類成員函數。分 別用來反映類的狀態。
比如類成員變量可以用來統計類實例的數量,類成員函數 負責這種統計的動作。

23.ASP.NET與ASP相比,主要有哪些進步?

asp解釋形,aspx編譯型,性能提高,有利於保護源碼。

24.請說明在.net中常用的幾種頁面間傳遞參數的方法,並說出他們的優缺點。

session(viewstate) 簡單,但易丟失
application 全局
cookie 簡單,但可能不支持,可能被僞造
input ttype=“hidden” 簡單,可能被僞造
url參數 簡單,顯示於地址欄,長度有限
數據庫 穩定,安全,但性能相對弱

25.DataReader與Dataset有什麼區別?

DataReader是隻能向前的只讀遊標,
Dataset是內存中虛擬的數據庫。

26.什麼是虛函數?什麼是抽象函數?

虛函數:沒有實現的,可由子類繼承並重寫的函數。
抽象函數:規定其非虛子類必須實現的函數,必須被重寫。

27.什麼是code-Behind技術。

ASPX,RESX和CS三個後綴的文件,這個就是代碼分離.
實現了HTML代碼和服務器代碼分離.方便代碼編寫和整理.

28.什麼是SOAP,有哪些應用。

simple object access protocal,簡單對象接受協議.
以xml爲基本編碼結構,建立在已有通信協議上 的一種規範Web Service使用的協議…

29.C#中 property 與 attribute的區別,他們各有什麼用處,這種機制的好處在哪裏?

一個是屬性,用於存取類的字段,
一個是特性,用來標識類,方法等的附加性質

30.當整數a賦值給一個object對象時,整數a將會被?

裝箱

31.public static const int A=1;這段代碼有錯誤麼?是什麼?

const不能用static修飾。

32.float f=-123.567F; int i=(int)f;i的值現在是?

-123

33. Net MVC 由控制器向視圖傳遞數據的對象有哪些?

viewBag , viewData , TempleData , 普通Model , 強類型Model , Razor Engine


34. 列舉 MVC ActionResult 的幾種返回類型

  1. ViewResult ,
  2. PartialViewResult ,
  3. ContentResult ,
  4. JsonResult ,
  5. FileResult ,
  6. Null,
  7. Redirect / RedirectToAction / RedirectToRoute

35. 正則表達式 的特殊符號中 “\d{6,12}表示?”

6-12位數字


36. JQuery $(document).ready() 與 window.onload 有啥區別?

1.執行的時間不同
onload 必須等到頁面內包括圖片的所有元素加載完畢後才能執行,
read()是DOM結構繪製完畢後就執行,不必等到加載完畢.
2. 簡化寫法
window.onload沒有簡化寫法
$(document).ready(function(){}) 可以簡寫成 $(function(){});


37. a=8 ,b=24 在不使用 第三方的前提下,把ab的值互換。

  1. a=a+b; b=a-b; a=a-b;
  2. a=10=0x0a=00001010b(在內存或計算機處理數據時), b=15=0x0f=00001111b(在內存或計算機處理數據時)
    所以,在a=b=a^=b;執行計算時,
    先執行:a=b(最右邊),即a=ab=00001010b^00001111b=00000101b=0x05
    再執行:b=a(中間),即b=ba=00001111b^00000101b=00001010b=0x0a=10
    再執行:a=b(最左邊),即a=ab=00000101b^00001010b=00001111b=0x0f=15
    故達成目標。
  3. a=b(b=ab); // 13個字節
  4. a=b+(b=a)*0; // 11個字節

38.什麼是強類型,什麼是弱類型?哪種更好些?爲什麼?

弱類型語言允許將一塊內存看做多種類型。
比如直接將整型變量與字符變量相加。
C 和 C++是靜態語言,也是弱類型語言;
Perl 和 PHP 是動態語言,但也是弱類型語言。

強類型語言在沒有強制類型轉化前,不允許兩種不同類型的變量相互操作。
Java、C#和Python等都是強類型語言。
使用哪種語言還是要按需而定。編寫簡單小應用,使用弱類型語言可節省很多代碼量,有更高的開發效率。
而對於構建大型項目,使用強類型語言可能會比使用弱類型更加規範可靠。

39. UDP連接和TCP連接有什麼異同?

  1. 簡單的說TCP與UDP的區別是有無連接狀態。
  2. TCP是面向連接的,UDP是面向無連接的。TCP(Transmission Control Protocol,傳輸控制協議),UDP(User Datagram Protocol,用戶數據包協議)
  3. TCP UDP是兩個協議,簡單的說,TCP連接要對方確認的,而UDP卻不需要對方確認收到包,所以TCP連接更加安全,
  4. 傳輸層協議一般有TCP和UDP,TCP爲可靠傳輸,協議本身會保證數據傳輸的可靠,但爲此會付出很多額外的網絡開銷。UDP爲不可靠傳輸,所以傳輸效率比較高,本端只負責發送數據,不保證對端能否收到。對於UDP,可靠性可以在應用層實現

40. 產生一個int數組,長度爲100,並向其中隨機插入1-100,不能重複。

namespace Wolfy.RandomDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] result = GetRandom(100);
            for (int i = 0; i < result.Length; i++)
            {
                Console.WriteLine(result[i]);
            }
            Console.WriteLine("over:" + result.Length);
            Console.Read();
        }
        /// <summary>
        /// 獲得無重複隨機數組
        /// </summary>
        /// <param name="n">上限n</param>
        /// <returns>返回隨機數組</returns>
        static int[] GetRandom(int n)
        {
            //容器A和B
            int[] arryA = new int[n];
            int[] arryB = new int[n];
            //填充容器a
            for (int i = 0; i < arryA.Length; i++)
            {
                arryA[i] = i + 1;
            }
            //隨機對象
            Random r = new Random();
            //最後一個元素的索引 如n=100,end=99
            int end = n - 1;
            for (int i = 0; i < n; i++)
            {
                //生成隨機數 因爲隨機的是索引 所以從0到100取,end=100
                //一個大於等於 minValue 且小於 maxValue 的 32 位帶符號整數,
                //即:返回的值範圍包括 minValue 但不包括 maxValue。 
                //如果 minValue 等於 maxValue,則返回 minValue
                //
                int minValue = 0;
                int maxValue = end + 1;
                int ranIndex = r.Next(minValue, maxValue);
                //把隨機數放在容器B中
                arryB[i] = arryA[ranIndex];
                //用最後一個元素覆蓋取出的元素
                arryA[ranIndex] = arryA[end];
                //縮減隨機數生成的範圍
                end--;
            }
            //返回生成的隨機數組
            return arryB;
        }
    }
}

SQL Server

SQL優化

1. 技術點

  1. 對查詢進行優化,要儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
  1. 應儘量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,
    如:
    select id from t where num is null
    最好不要給數據庫留NULL,儘可能的使用 NOT NULL填充數據庫. 備註、描述、評論之類的可以設置爲 NULL,其他的,最好不要使用NULL。 不要以爲 NULL 不需要空間,
    比如:char(100) 型,在字段建立時,空間就固定了, 不管是否插入值(NULL也包含在內),都是佔用 100個字符的空間的,如果是varchar這樣的變長字段 null 不佔用空間。 可以在num上設置默認值0,確保表中num列沒有null值,
    然後這樣查詢:
    select id from t where num = 0
  1. 應儘量避免在 where 子句中使用 != 或 <> 操作符,否則將引擎放棄使用索引而進行全表掃描。
  1. 應儘量避免在 where 子句中使用 or 來連接條件,如果一個字段有索引,一個字段沒有索引,將導致引擎放棄使用索引而進行全表掃描,
    如:
    select id from t where num=10 or Name = 'admin'
    可以這樣查詢:
    select id from t where num = 10 union all select id from t where Name = 'admin'
  1. in 和 not in 也要慎用,否則會導致全表掃描,
    如:
    select id from t where num in(1,2,3)
    對於連續的數值,能用 between 就不要用 in 了:
    select id from t where num between 1 and 3
    很多時候用 exists 代替 in 是一個好的選擇:
    select num from a where num in(select num from b)
    用下面的語句替換:
    select num from a where exists(select 1 from b where num=a.num)
  1. 下面的查詢也將導致全表掃描:
    select id from t where name like ‘%abc%’
    若要提高效率,可以考慮全文檢索。
  1. 如果在 where 子句中使用參數,也會導致全表掃描。
    因爲SQL只有在運行時纔會解析局部變量,但優化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然
    而,如果在編譯時建立訪問計劃,變量的值還是未知的,因而無法作爲索引選擇的輸入項。如下面語句將進行全表掃描:
    select id from t where num = @num
    可以改爲強制查詢使用索引:
    select id from t with(index(索引名)) where num = @num
  1. 應儘量避免在 where 子句中對字段進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。如:
    select id from t where num/2 = 100
    應改爲:
    select id from t where num = 100*2
  1. 應儘量避免在where子句中對字段進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。如:
    select id from t where substring(name,1,3) = ’abc’ -–name以abc開頭的id
    select id from t where datediff(day,createdate,’2005-11-30′) = 0 -–‘2005-11-30’ --生成的id
    應改爲:
    select id from t where name like 'abc%' select id from t where createdate >= '2005-11-30' and createdate < '2005-12-1'
  1. 不要在 where 子句中的“=”左邊進行函數、算術運算或其他表達式運算,否則系統將可能無法正確使用索引。
  1. 在使用索引字段作爲條件時,如果該索引是複合索引,那麼必須使用到該索引中的第一個字段作爲條件時才能保證系統使用該索引,否則該索引將不會被使用,並且應儘可能的讓字段順序與索引順序相一致。
  1. 不要寫一些沒有意義的查詢,如需要生成一個空表結構:
    select col1,col2 into #t from t where 1=0
    這類代碼不會返回任何結果集,但是會消耗系統資源的,應改成這樣:
    create table #t(…)
  1. Update 語句,如果只更改1、2個字段,不要Update全部字段,否則頻繁調用會引起明顯的性能消耗,同時帶來大量日誌。
  1. 對於多張大數據量(這裏幾百條就算大了)的表JOIN,要先分頁再JOIN,否則邏輯讀會很高,性能很差。
  1. select count(*) from table;
    這樣不帶任何條件的count會引起全表掃描,並且沒有任何業務意義,是一定要杜絕的。
  1. 索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因爲 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有 必要。
  1. 應儘可能的避免更新 clustered 索引數據列,因爲 clustered 索引數據列的順序就是表記錄的物理存儲順序,一旦該列值改變將導致整個表記錄的順序的調整,會耗費相當大的資源。若應用系統需要頻繁更新
    clustered 索引數據列,那麼需要考慮是否應將該索引建爲 clustered 索引。
  1. 儘量使用數字型字段,若只含數值信息的字段儘量不要設計爲字符型,這會降低查詢和連接的性能,並會增加存儲開銷。這是因爲引擎在處理查詢和連 接時會逐個比較字符串中每一個字符,而對於數字型而言只需要比較一次就夠了。
  1. 儘可能的使用 varchar/nvarchar 代替 char/nchar ,因爲首先變長字段存儲空間小,可以節省存儲空間,其次對於查詢來說,在一個相對較小的字段內搜索效率顯然要高些。
  1. 任何地方都不要使用 select * from t ,用具體的字段列表代替“*”,不要返回用不到的任何字段。
  1. 儘量使用表變量來代替臨時表。如果表變量包含大量數據,請注意索引非常有限(只有主鍵索引)。
  1. 避免頻繁創建和刪除臨時表,以減少系統表資源的消耗。臨時表並不是不可使用,適當地使用它們可以使某些例程更有效,例如,當需要重複引用大型表或常用表中的某個數據集時。但是,對於一次性事件,最好使用導出表。
  1. 在新建臨時表時,如果一次性插入數據量很大,那麼可以使用 select into 代替 create table,避免造成大量 log , 以提高速度;如果數據量不大,爲了緩和系統表的資源,應先create table,然後insert
  1. 如果使用到了臨時表,在存儲過程的最後務必將所有的臨時表顯式刪除,先 truncate table ,然後 drop table ,這樣可以避免系統表的較長時間鎖定。
  1. 儘量避免使用遊標,因爲遊標的效率較差,如果遊標操作的數據超過1萬行,那麼就應該考慮改寫。
  1. 使用基於遊標的方法或臨時表方法之前,應先尋找基於集的解決方案來解決問題,基於集的方法通常更有效。
  1. 與臨時表一樣,遊標並不是不可使用。對小型數據集使用 FAST_FORWARD 遊標通常要優於其他逐行處理方法,尤其是在必須引用幾個表才能獲得所需的數據時。在結果集中包括“合計”的例程通常要比使用遊標執行的速度快。如果開發時 間允許,基於遊標的方法和基於集的方法都可以嘗試一下,看哪一種方法的效果更好。
  1. 在所有的存儲過程和觸發器的開始處設置 SET NOCOUNT ON ,在結束時設置 SET NOCOUNT OFF 。無需在執行存儲過程和觸發器的每個語句後向客戶端發送 DONE_IN_PROC 消息。
  1. 儘量避免大事務操作,提高系統併發能力。
  1. 儘量避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理。

2. 實際案例分析

拆分大的 DELETE 或INSERT 語句,批量提交SQL語句   如果你需要在一個在線的網站上去執行一個大的 DELETE 或 INSERT 查詢,你需要非常小心,要避免你的操作讓你的整個網站停止相應。因爲這兩個操作是會鎖表的,表一鎖住了,別的操作都進不來了。
Apache 會有很多的子進程或線程。所以,其工作起來相當有效率,而我們的服務器也不希望有太多的子進程,線程和數據庫鏈接,這是極大的佔服務器資源的事情,尤其是內存。
如果你把你的表鎖上一段時間,比如30秒鐘,那麼對於一個有很高訪問量的站點來說,這30秒所積累的訪問進程/線程,數據庫鏈接,打開的文件數,可能不僅僅會讓你的WEB服務崩潰,還可能會讓你的整臺服務器馬上掛了。
所以,如果你有一個大的處理,你一定把其拆分,
使用 LIMIT oracle(rownum),sqlserver(top)條件是一個好的方法。

下面是一個mysql示例:

while(1){

//每次只做1000條
mysql_query(“delete from logs where log_date <=2012-11-01’ limit 1000);

if(mysql_affected_rows() == 0)
{
     //刪除完成,退出!
     break}

//每次暫停一段時間,釋放表讓其他進程/線程訪問。
usleep(50000)
}

問答

1. 觸發器的作用?

觸發器是一中特殊的存儲過程,主要是通過事件來觸發而被執行的。
它可以強化約束,來維護數據的完整性和一致性,可以跟蹤數據庫內的操作從而不允許未經許可的更新和變化。可以聯級運算。
如,某表上的觸發器上包含對另一個表的數據操作,而該操作又會導致該表觸發器被觸發。

2. 什麼是存儲過程?用什麼來調用?

存儲過程是一個預編譯的SQL 語句,
優點是允許模塊化的設計,就是說只需創建一次,以後在該程序中就可以調用多次。
如果某次操作需要執行多次SQL ,使用存儲過程比單純SQL 語句執行要快。
可以用一個命令對象來調用存儲過程。

3. 索引的作用?和它的優點缺點是什麼?

索引就一種特殊的查詢表,數據庫的搜索引擎可以利用它加速對數據的檢索。
它很類似與現實生活中書的目錄,不需要查詢整本書內容就可以找到想要的數據。
索引可以是唯一的,創建索引允許指定單個列或者是多個列。
缺點是它減慢了數據錄入的速度,同時也增加了數據庫的尺寸大小。

4. 維護數據庫的完整性和一致性,你喜歡用觸發器還是自寫業務邏輯?爲什麼?

我是這樣做的,儘可能使用約束,如check, 主鍵,外鍵,非空字段等來約束,這樣做效率最高,也最方便。
其次是使用觸發器,這種方法可以保證,無論什麼業務系統訪問數據庫都可以保證數據的完整新和一致性。
最後考慮的是自寫業務邏輯,但這樣做麻煩,編程複雜,效率低下。

5. 什麼是事務?什麼是鎖?

事務:
被綁定在一起作爲一個邏輯工作單元的SQL 語句分組,
如果任何一個語句操作失敗那麼整個操作就被失敗,以後操作就會回滾到操作前狀態,或者是上有個節點。
爲了確保要麼執行,要麼不執行,就可以使用事務。
要將有組語句作爲事務考慮,就需要通過ACID 測試,
原子性,一致性,隔離性和持久性

鎖:
在所以的 DBMS中,鎖是實現事務的關鍵,鎖可以保證事務的完整性和併發性。與現實生活中鎖一樣,它可以使某些數據的擁有者,在某段時間內不能使用某些數據或數據結構。當然鎖還分級別的。

6. 什麼叫視圖?遊標是什麼?

視圖:
一種虛擬的表,具有和物理表相同的功能。
可以對視圖進行增,改,查,操作,試圖通常是有一個表或者多個表的行或列的子集。
對視圖的修改不影響基本表。
它使得我們獲取數據更容易,相比多表查詢。

遊標:
是對查詢出來的結果集作爲一個單元來有效的處理。
遊標可以定在該單元中的特定行,從結果集的當前行檢索一行或多行。
可以對結果集當前行做修改。
一般不使用遊標,但是需要逐條處理數據的時候,遊標顯得十分重要。

7.SQL Server 中使用的一些數據庫對象嗎?

表格、
視圖、
用戶定義的函數,
存儲過程,
觸發器

等等

8. NULL是什麼意思?

NULL(空)這個值是數據庫世界裏一個非常難纏的東西,所以有不少應聘者會在這個問題上跌跟頭您也不要覺得意外。
NULL這個值表示UNKNOWN(未知):它不表示“”(空字符串)。
假設您的SQL Server數據庫裏有ANSI_NULLS,當然在默認情況下會有,對NULL這個值的任何比較都會生產一個NULL值。
您不能把任何值與一個 UNKNOWN值進行比較,並在邏輯上希望獲得一個答案。
您必須使用IS NULL操作符。

9.什麼是索引?SQL Server 2000裏有什麼類型的索引?

簡單地說,索引是一個數據結構,用來快速訪問數據庫表格或者視圖裏的數據。

聚集索引

聚集索引在索引的葉級保存數據。這意味着不論聚集索引裏有表格的哪個(或哪些)字段,這些字段都會按順序被保存在表格。由於存在這種排序,所以每個表格只會有一個聚集索引。

非聚集索引

非聚集索引在索引的葉級有一個行標識符。這個行標識符是一個指向磁盤上數據的指針。它允許每個表格有多個非聚集索引。

10.什麼是主鍵?什麼是外鍵?

主鍵是表格裏的(一個或多個)字段,只用來定義表格裏的行;主鍵裏的值總是唯一的。

外鍵是一個用來建立兩個表格之間關係的約束。這種關係一般都涉及一個表格裏的主鍵字段與另外一個表格(儘管可能是同一個表格)裏的一系列相連的字段。那麼這些相連的字段就是外鍵。

11.什麼是觸發器?SQL Server 2000有什麼不同類型的觸發器?

觸發器是一種專用類型的存儲過程,它被捆綁到SQL Server 2000的表格或者視圖上。在SQL Server 2000裏,有INSTEAD-OF和AFTER兩種觸發器。

INSTEAD-OF觸發器是替代數據操控語言(Data Manipulation Language,DML)語句對錶格執行語句的存儲過程。
例如,如果我有一個用於TableA的INSTEAD-OF-UPDATE觸發器,同時對這個表格執行一個更新語句,那麼INSTEAD-OF-UPDATE觸發器裏的代碼會執行,而不是我執行的更新語句則不會執行操作。

AFTER觸發器要在DML語句在數據庫裏使用之後才執行。這些類型的觸發器對於監視發生在數據庫表格裏的數據變化十分好用。

12. 如何確定一個帶Fld1字段的TableB表格裏只具有Fld1字段裏的那些值,而這些值同時在名爲TableA的表格的Fld1字段裏?

第一個答案(而且是您希望聽到的答案)是使用外鍵限制。外鍵限制用來維護引用的完整性。它被用來確保表格裏的字段只保存有已經在不同的(或者相同的)表格裏的另一個字段裏定義了的值。這個字段就是候選鍵(通常是另外一個表格的主鍵)。

另外一種答案是觸發器。觸發器可以被用來保證以另外一種方式實現與限制相同的作用,但是它非常難設置與維護,而且性能一般都很糟糕。由於這個原因,微軟建議開發人員使用外鍵限制而不是觸發器來維護引用的完整性。

13. 對一個投入使用的在線事務處理表格有過多索引需要有什麼樣的性能考慮?

對一個表格的索引越多,數據庫引擎用來更新、插入或者刪除數據所需要的時間就越多,
因爲在數據操控發生的時候索引也必須要維護。

14. 你可以用什麼來確保表格裏的字段只接受特定範圍裏的值?

這個問題可以用多種方式來回答,但是隻有一個答案是“好”答案。
您希望聽到的回答是 Check限制,它在數據庫表格裏被定義,用來限制輸入該列的值。

觸發器也可以被用來限制數據庫表格裏的字段能夠接受的值,但是這種辦法要求觸發器在表格裏被定義,這可能會在某些情況下影響到性能。因此,微軟建議使用Check限制而不是其他的方式來限制域的完整性。

15.什麼是相關子查詢?如何使用這些查詢?

相關子查詢是一種包含子查詢的特殊類型的查詢。
查詢裏包含的子查詢會真正請求外部查詢的值,從而形成一個類似於循環的狀況。

SQL題

1. 查詢出每門課都大於80 分的學生姓名

name kecheng fenshu
張三 語文 81
張三 數學 75
李四 語文 76
李四 數學 90
王五 語文 81
王五 數學 100
王五 英語 90

    select distinct name from table 
    	where name not in 
    	(select distinct name from table where fenshu<=80)
    	
    select name from table group by name having min(fenshu)>80

2. 刪除 除了自動編號不同, 其他都相同的學生冗餘信息

自動編號 學號 姓名 課程編號 課程名稱 分數
1 2005001 張三 0001 數學 69
2 2005002 李四 0001 數學 89
3 2005001 張三 0001 數學 69
 delete tablename where 自動編號
 			not in (
 		 			select min(自動編號) from tablename group by 學號, 姓名, 課程編號, 課程名稱, 分數
 		 			)

3.顯示所有可能的比賽組合

一個叫 team 的表,
裏面只有一個字段name,
一共有4 條紀錄,分別是a,b,c,d, 對應四個球隊,
現在四個球隊進行比賽,用一條sql 語句顯示所有可能的比賽組合.

select a.name, b.name
	from team a, team b 
	 where a.name < b.name

4.查詢出所有月份的發生額都比101 科目相應月份的發生額高的科目

從TestDB 數據表中查詢出所有月份的發生額都比101 科目相應月份的發生額高的科目。
請注意:TestDB 中有很多科目,都有1 -12 月份的發生額。

AccID :科目代碼,Occmonth :發生額月份,DebitOccur :發生額。
數據庫名:JcyAudit

select a.*
	from TestDB a 
	,(select Occmonth,max(DebitOccur) Debit101ccur from TestDB where AccID='101' group by Occmonth) b
		where a.Occmonth = b.Occmonth and a.DebitOccur > b.Debit101ccur

5.行與列的轉換

year month amount
1 Java 70
1991 1 1.1
1991 2 1.2
1991 3 1.3
1991 4 1.4
1992 1 2.1
1992 2 2.2
1992 3 2.3
1992 4 2.4

查成這樣一個結果

year m1 m2 m3 m4
1991 1.1 1.2 1.3 1.4
1992 2.1 2.2 2.3 2.4
select year, 
(select amount from aaa m where month=1   and m.year=aaa.year) as m1,
(select amount from aaa m where month=2   and m.year=aaa.year) as m2,
(select amount from aaa m where month=3   and m.year=aaa.year) as m3,
(select amount from aaa m where month=4   and m.year=aaa.year) as m4
from aaa   group by year


6.如果B 的key 在A 中也有,就把B 的value 換爲A 中對應的value

有兩個表A 和B ,均有key 和value 兩個字段,
如果B 的key 在A 中也有,就把B 的value 換爲A 中對應的value
這道題的SQL 語句怎麼寫?

update b 
	set b.value=(select a.value from a where a.key=b.key)
	 where b.id in 
	 			(select b.id from b,a where b.key=a.key)

7. 拷貝表( 拷貝數據, 源表名:a目標表名:b)

 insert into b (a, b, c) select d,e,f from a; 

8. 顯示文章、提交人和最後回覆時間

select a.title,a.username,b.adddate 
	from table a, ( select max(adddate) adddate  from table where table.title = a.title) b

9. 日程安排提前五分鐘提醒

select * from 日程安排 where datediff('minute',f 開始時間,getdate())>5

10. 兩張關聯表,刪除主表中已經在副表中沒有的信息

Delete from info 
	 where not exists ( select * from infobz where info.infid=infobz.infid )

11. 判斷是否及格

原表

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

12.關聯數據

id department
1 設計
2 市場
3 售後
id dptID name
1 1 張三
2 1 李四
3 2 王五
4 3 彭六
5 4 陳七

用一條SQL語句,怎麼顯示如下結果

id dptID department name
1 1 設計 張三
2 1 設計 李四
3 2 市場 王五
4 3 售後 彭六
5 4 黑人 陳七
SELECT testtable2.* , ISNULL(department,'黑人')
	FROM testtable1 
	right join 	testtable2 on testtable2.dptID = testtable1.ID

13.合併數據

表A,結構如下:

p_ID p_Num s_id
1 10 01
1 12 02
2 8 01
3 11 01
3 8 03

其中:p_ID爲產品ID,p_Num爲產品庫存量,s_id爲倉庫ID。請用SQL語句實現將上表中的數據合併,合併後的數據爲:

p_ID s1_id s2_id s3_id
1 10 12 0
2 8 0 0
3 11 0 8

其中:s1_id爲倉庫1的庫存量,s2_id爲倉庫2的庫存量,s3_id爲倉庫3的庫存量。如果該產品在某倉庫中無庫存量,那麼就是0代替。

select p_id ,
sum(case when s_id=1 then p_num else 0 end) as s1_id
,sum(case when s_id=2 then p_num else 0 end) as s2_id
,sum(case when s_id=3 then p_num else 0 end) as s3_id
from myPro group by p_id

14.大題 (很多個sql)

爲管理業務培訓信息,建立3個表:

S表

S#學號 SN學員姓名 SD所屬單位 SA學員年齡

C表

C#課程編號 CN課程名稱

SC表

S#學號 C#所選的課程編號 G學習成績
  1. 使用標準SQL嵌套語句查詢選修課程名稱爲’稅收基礎’的學員學號和姓名?
select s# ,sn from s where S# in(select S# from c,sc where c.c#=sc.c# and cn=’稅收基礎’)
  1. 使用標準SQL嵌套語句查詢選修課程編號爲’C2’的學員姓名和所屬單位?
select sn,sd from s,sc where s.s#=sc.s# and sc.c#=’c2’
  1. 使用標準SQL嵌套語句查詢不選修課程編號爲’C5’的學員姓名和所屬單位?
select sn,sd from s where s# not in(select s# from sc where c#=’c5’)
  1. 查詢選修了課程的學員人數
select 學員人數=count(distinct s#) from sc
  1. 查詢選修課程超過5門的學員學號和所屬單位?
select sn,sd from s where s# in(select s# from sc group by s# having count(distinct c#)>5)

15. 查詢A(ID,Name)表中第31至40條記錄,ID作爲主鍵可能不是連續增長的列

select top 10 * from A 
	 where ID >(select max(ID) from (select top 30 ID from A order by A ) T) order by A

16…查詢表A中存在ID重複三次以上的記錄

select * from(select count(ID) as count from table group by ID)T
	 where T.count>3

緩存

Redis

1、什麼是Redis?

  1. Redis本質上是一個Key-Value類型的內存數據庫,很像memcached,整個數據庫統統加載在內存當中進行操作,定期通過異步操作把數據庫數據flush到硬盤上進行保存。
  2. 因爲是純內存操作,Redis的性能非常出色,每秒可以處理超過 10萬次讀寫操作,是已知性能最快的Key-Value DB。
  3. Redis的出色之處不僅僅是性能,Redis最大的魅力是支持保存多種數據結構,此外單個value的最大限制是1GB,不像 memcached只能保存1MB的數據,因此Redis可以用來實現很多有用的功能,比方說用他的List來做FIFO雙向鏈表,實現一個輕量級的高性 能消息隊列服務,用他的Set可以做高性能的tag系統等等。
  4. Redis也可以對存入的Key-Value設置expire時間,因此也可以被當作一 個功能加強版的memcached來用。 Redis的主要缺點是數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫,因此Redis適合的場景主要侷限在較小數據量的高性能操作和運算上。

2、Redis相比memcached有哪些優勢?

  1. memcached所有的值均是簡單的字符串,redis作爲其替代者,支持更爲豐富的數據類型
  2. redis的速度比memcached快很多
  3. redis可以持久化其數據

3、Redis支持哪幾種數據類型?

String
List
Set
Sorted Set
hash

4、Redis主要消耗什麼物理資源?

內存

5、Redis的全稱是什麼?

Remote Dictionary Server

6、Redis有哪幾種數據淘汰策略?

  1. noeviction:返回錯誤當內存限制達到並且客戶端嘗試執行會讓更多內存被使用的命令(大部分的寫入指令,但DEL和幾個例外)
  2. allkeys-lru: 嘗試回收最少使用的鍵(LRU),使得新添加的數據有空間存放。
  3. volatile-lru: 嘗試回收最少使用的鍵(LRU),但僅限於在過期集合的鍵,使得新添加的數據有空間存放。
  4. allkeys-random: 回收隨機的鍵使得新添加的數據有空間存放。
  5. volatile-random: 回收隨機的鍵使得新添加的數據有空間存放,但僅限於在過期集合的鍵。
  6. volatile-ttl: 回收在過期集合的鍵,並且優先回收存活時間(TTL)較短的鍵,使得新添加的數據有空間存放。

7、一Redis–各個數據類型最大存儲量

Strings類型:一個String類型的value最大可以存儲512M
Lists類型:list的元素個數最多爲2^32-1個,也就是4294967295個。
Sets類型:元素個數最多爲2^32-1個,也就是4294967295個。
Hashes類型:鍵值對個數最多爲2^32-1個,也就是4294967295個。
Sorted sets類型:跟Sets類型相似

8、爲什麼Redis需要把所有數據放到內存中?

Redis爲了達到最快的讀寫速度將數據都讀到內存中,並通過異步的方式將數據寫入磁盤。所以redis具有快速和數據持久化的特徵。如果不將數據放在內存中,磁盤I/O速度爲嚴重影響redis的性能。在內存越來越便宜的今天,redis將會越來越受歡迎。 如果設置了最大使用的內存,則數據已有記錄數達到內存限值後不能繼續插入新值。

9、Redis集羣方案應該怎麼做?都有哪些方案?

  1. twemproxy,大概概念是,它類似於一個代理方式,使用方法和普通redis無任何區別,設置好它下屬的多個redis實例後,使用時在本需要連接redis的地方改爲連接twemproxy,它會以一個代理的身份接收請求並使用一致性hash算法,將請求轉接到具體redis,將結果再返回twemproxy。使用方式簡便(相對redis只需修改連接端口),對舊項目擴展的首選。
    問題:twemproxy自身單端口實例的壓力,使用一致性hash後,對redis節點數量改變時候的計算值的改變,數據無法自動移動到新的節點。
  2. codis,目前用的最多的集羣方案,基本和twemproxy一致的效果,但它支持在 節點數量改變情況下,舊節點數據可恢復到新hash節點。
  3. redis cluster3.0自帶的集羣,特點在於他的分佈式算法不是一致性hash,而是hash槽的概念,以及自身支持節點設置從節點。具體看官方文檔介紹。
  4. 在業務代碼層實現,起幾個毫無關聯的redis實例,在代碼層,對key 進行hash計算,然後去對應的redis實例操作數據。 這種方式對hash層代碼要求比較高,考慮部分包括,節點失效後的替代算法方案,數據震盪後的自動腳本恢復,實例的監控,等等。

10、Redis集羣方案什麼情況下會導致整個集羣不可用?

有A,B,C三個節點的集羣,在沒有複製模型的情況下,如果節點B失敗了,那麼整個集羣就會以爲缺少5501-11000這個範圍的槽而不可用。

11、MySQL裏有2000w數據,redis中只存20w的數據,如何保證redis中的數據都是熱點數據?

redis內存數據集大小上升到一定大小的時候,就會施行數據淘汰策略。

12、Redis有哪些適合的場景?

  1. 會話緩存(Session Cache)
    最常用的一種使用Redis的情景是會話緩存(session cache)。用Redis緩存會話比其他存儲(如Memcached)的優勢在於:Redis提供持久化。當維護一個不是嚴格要求一致性的緩存時,如果用戶的購物車信息全部丟失,大部分人都會不高興的,現在,他們還會這樣嗎?
    幸運的是,隨着 Redis 這些年的改進,很容易找到怎麼恰當的使用Redis來緩存會話的文檔。甚至廣爲人知的商業平臺Magento也提供Redis的插件。
  2. 全頁緩存(FPC)
    除基本的會話token之外,Redis還提供很簡便的FPC平臺。回到一致性問題,即使重啓了Redis實例,因爲有磁盤的持久化,用戶也不會看到頁面加載速度的下降,這是一個極大改進,類似PHP本地FPC。
    再次以Magento爲例,Magento提供一個插件來使用Redis作爲全頁緩存後端。
    此外,對WordPress的用戶來說,Pantheon有一個非常好的插件 wp-redis,這個插件能幫助你以最快速度加載你曾瀏覽過的頁面。
  3. 隊列
    Reids在內存存儲引擎領域的一大優點是提供 list 和 set 操作,這使得Redis能作爲一個很好的消息隊列平臺來使用。Redis作爲隊列使用的操作,就類似於本地程序語言(如Python)對 list 的 push/pop 操作。>
    如果你快速的在Google中搜索“Redis queues”,你馬上就能找到大量的開源項目,這些項目的目的就是利用Redis創建非常好的後端工具,以滿足各種隊列需求。例如,Celery有一個後臺就是使用Redis作爲broker,你可以從這裏去查看。
  4. 排行榜/計數器
    Redis在內存中對數字進行遞增或遞減的操作實現的非常好。集合(Set)和有序集合(Sorted Set)也使得我們在執行這些操作的時候變的非常簡單,Redis只是正好提供了這兩種數據結構。所以,我們要從排序集合中獲取到排名最靠前的10個用戶–我們稱之爲“user_scores”,我們只需要像下面一樣執行即可:
    當然,這是假定你是根據你用戶的分數做遞增的排序。如果你想返回用戶及用戶的分數,你需要這樣執行:
    ZRANGE user_scores 0 10 WITHSCORES
    Agora Games就是一個很好的例子,用Ruby實現的,它的排行榜就是使用Redis來存儲數據的,你可以在這裏看到。
  5. 發佈/訂閱
    最後(但肯定不是最不重要的)是Redis的發佈/訂閱功能。發佈/訂閱的使用場景確實非常多。我已看見人們在社交網絡連接中使用,還可作爲基於發佈/訂閱的腳本觸發器,甚至用Redis的發佈/訂閱功能來建立聊天系統!(不,這是真的,你可以去核實)。

13、Redis和Redisson有什麼關係?

Redisson是一個高級的分佈式協調Redis客服端
能幫助用戶在分佈式環境中輕鬆實現一些Java的對象
(Bloom filter, BitSet, Set, SetMultimap, ScoredSortedSet, SortedSet, Map, ConcurrentMap, List, ListMultimap, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, ReadWriteLock, AtomicLong, CountDownLatch, Publish / Subscribe, HyperLogLog)。

14、說說Redis哈希槽的概念?

Redis集羣沒有使用一致性hash,而是引入了哈希槽的概念,
Redis集羣有16384個哈希槽,每個key通過CRC16校驗後對16384取模來決定放置哪個槽,
集羣的每個節點負責一部分hash槽。

15、Redis集羣的主從複製模型是怎樣的?

爲了使在部分節點失敗或者大部分節點無法通信的情況下集羣仍然可用,所以集羣使用了主從複製模型,每個節點都會有N-1個複製品.

16、Redis集羣會有寫操作丟失嗎?爲什麼?

Redis並不能保證數據的強一致性,這意味這在實際中集羣在特定的條件下可能會丟失寫操作。

17、Redis集羣之間是如何複製的?

異步複製

18、Redis集羣最大節點個數是多少?

16384個。

18、Redis集羣如何選擇數據庫?

Redis集羣目前無法做數據庫選擇,默認在0數據庫。

18、怎麼測試Redis的連通性?

Ping

19、如何保持redis和數據庫之間的一致性?

  1. 讀操作優先讀取redis,不存在的話就去訪問MySql,並把讀到的數據寫回Redis中;
  2. 寫操作的話,直接寫MySql,成功後再寫入Redis,替換掉原來的舊數據
    可以在MySql端定義CRUD觸發器,在觸發CRUD操作後寫數據到Redis,也可以在Redis端解析binlog,再做相應的操作
  3. 設定合理的超時時間,即經過超時時間,自動將redis中相應的數據刪除。這樣最差的情況是在超時時間內,內存存在不一致。當然這種策略要考慮redis和數據庫主從同步的耗時,所以在第二次刪除前最好休眠一定的時間,比如500毫秒,這樣無疑又增加了寫請求的耗時。

20、Redis中的管道有什麼用?

一次請求/響應服務器能實現處理新的請求即使舊的請求還未被響應。這樣就可以將多個命令發送到服務器,而不用等待回覆,最後在一個步驟中讀取該答覆。
這就是管道(pipelining),是一種幾十年來廣泛使用的技術。例如許多POP3協議已經實現支持這個功能,大大加快了從服務器下載新郵件的過程。

21、怎麼理解Redis事務?

事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端發送來的命令請求所打斷。
事務是一個原子操作:事務中的命令要麼全部被執行,要麼全部都不執行。

22、Redis事務相關的命令有哪幾個?

MULTI
EXEC
DISCARD
WATCH

23、Redis key的過期時間和永久有效分別怎麼設置?

EXPIRE 和 PERSIST命令。

24、Redis如何做內存優化?

儘可能使用散列表(hashes),散列表(是說散列表裏面存儲的數少)使用的內存非常小,所以你應該儘可能的將你的數據模型抽象到一個散列表裏面。 比如你的web系統中有一個用戶對象,不要爲這個用戶的名稱,姓氏,郵箱,密碼設置單獨的key,而是應該把這個用戶的所有信息存儲到一張散列表裏面.

25、Redis回收進程如何工作的?

一個客戶端運行了新的命令,添加了新的數據。
Redi檢查內存使用情況,如果大於maxmemory的限制, 則根據設定好的策略進行回收。
一個新的命令被執行,等等。
所以我們不斷地穿越內存限制的邊界,通過不斷達到邊界然後不斷地回收回到邊界以下。
如果一個命令的結果導致大量內存被使用(例如很大的集合的交集保存到一個新的鍵),不用多久內存限制就會被這個內存使用量超越。

26、Redis回收使用的是什麼算法?

LRU算法Redis中採用兩種算法進行內存回收,引用計數算法以及LRU算法,在操作系統內存管理一節中,我們都學習過LRU算法(最近最久未使用算法)
https://www.cnblogs.com/WJ5888/p/4371647.html

27、Redis如何做大量數據插入?

Redis2.6開始redis-cli支持一種新的被稱之爲 pipe mode 的新模式用於執行大量數據插入工作。
官方文檔給的解釋:http://www.redis.cn/topics/mass-insert.html

28、爲什麼要做Redis分區?

分區可以讓Redis管理更大的內存,Redis將可以使用所有機器的內存。如果沒有分區,你最多隻能使用一臺機器的內存。分區使Redis的計算能力通過簡單地增加計算機得到成倍提升,Redis的網絡帶寬也會隨着計算機和網卡的增加而成倍增長。
Redis 分區的優勢、不足以及分區類型
官方文檔提供的講解:http://www.redis.net.cn/tutorial/3524.html

29、你知道有哪些Redis分區實現方案?

  1. 客戶端分區就是在客戶端就已經決定數據會被存儲到哪個redis節點或者從哪個redis節點讀取。大多數客戶端已經實現了客戶端分區。
  2. 代理分區 意味着客戶端將請求發送給代理,然後代理決定去哪個節點寫數據或者讀數據。代理根據分區規則決定請求哪些Redis實例,然後根據Redis的響應結果返回給客戶端。redis和memcached的一種代理實現就是Twemproxy
  3. 查詢路由(Query routing) 的意思是客戶端隨機地請求任意一個redis實例,然後由Redis將請求轉發給正確的Redis節點。Redis Cluster實現了一種混合形式的查詢路由,但並不是直接將請求從一個redis節點轉發到另一個redis節點,而是在客戶端的幫助下直接redirected到正確的redis節點。

30、Redis分區有什麼缺點?

涉及多個key的操作通常不會被支持。例如你不能對兩個集合求交集,因爲他們可能被存儲到不同的Redis實例(實際上這種情況也有辦法,但是不能直接使用交集指令)。
同時操作多個key,則不能使用Redis事務.
分區使用的粒度是key,不能使用一個非常長的排序key存儲一個數據集
(The partitioning granularity is the key, so it is not possible to shard a dataset with a single huge key like a very big sorted set).
當使用分區的時候,數據處理會非常複雜,例如爲了備份你必須從不同的Redis實例和主機同時收集RDB / AOF文件。
分區時動態擴容或縮容可能非常複雜。Redis集羣在運行時增加或者刪除Redis節點,能做到最大程度對用戶透明地數據再平衡,但其他一些客戶端分區或者代理分區方法則不支持這種特性。然而,有一種預分片的技術也可以較好的解決這個問題。

31、Redis持久化數據和緩存怎麼做擴容?

如果Redis被當做緩存使用,使用一致性哈希實現動態擴容縮容。
如果Redis被當做一個持久化存儲使用,必須使用固定的keys-to-nodes映射關係,節點的數量一旦確定不能變化。否則的話(即Redis節點需要動態變化的情況),必須使用可以在運行時進行數據再平衡的一套系統,而當前只有Redis集羣可以做到這樣。

32、分佈式Redis是前期做還是後期規模上來了再做好?爲什麼?

既然Redis是如此的輕量(單實例只使用1M內存),爲防止以後的擴容,最好的辦法就是一開始就啓動較多實例。即便你只有一臺服務器,你也可以一開始就讓Redis以分佈式的方式運行,使用分區,在同一臺服務器上啓動多個實例。
一開始就多設置幾個Redis實例,例如32或者64個實例,對大多數用戶來說這操作起來可能比較麻煩,但是從長久來看做這點犧牲是值得的。
這樣的話,當你的數據不斷增長,需要更多的Redis服務器時,你需要做的就是僅僅將Redis實例從一臺服務遷移到另外一臺服務器而已(而不用考慮重新分區的問題)。一旦你添加了另一臺服務器,你需要將你一半的Redis實例從第一臺機器遷移到第二臺機器。

33、Twemproxy是什麼?

Twemproxy是Twitter維護的(緩存)代理系統,代理Memcached的ASCII協議和Redis協議。它是單線程程序,使用c語言編寫,運行起來非常快。它是採用Apache 2.0 license的開源軟件。 Twemproxy支持自動分區,如果其代理的其中一個Redis節點不可用時,會自動將該節點排除(這將改變原來的keys-instances的映射關係,所以你應該僅在把Redis當緩存時使用Twemproxy)。
Twemproxy本身不存在單點問題,因爲你可以啓動多個Twemproxy實例,然後讓你的客戶端去連接任意一個Twemproxy實例。
Twemproxy是Redis客戶端和服務器端的一箇中間層,由它來處理分區功能應該不算複雜,並且應該算比較可靠的。

34、Redis與其他key-value存儲有什麼不同?

Redis有着更爲複雜的數據結構並且提供對他們的原子性操作,這是一個不同於其他數據庫的進化路徑。Redis的數據類型都是基於基本數據結構的同時對程序員透明,無需進行額外的抽象。
Redis運行在內存中但是可以持久化到磁盤,所以在對不同數據集進行高速讀寫時需要權衡內存,應爲數據量不能大於硬件內存。
在內存數據庫方面的另一個優點是, 相比在磁盤上相同的複雜的數據結構,在內存中操作起來非常簡單,這樣Redis可以做很多內部複雜性很強的事情。 同時,在磁盤格式方面他們是緊湊的以追加的方式產生的,因爲他們並不需要進行隨機訪問。

35、都有哪些辦法可以降低Redis的內存使用情況呢?

如果你使用的是32位的Redis實例,可以好好利用Hash,list,sorted set,set等集合類型數據,
因爲通常情況下很多小的Key-Value可以用更緊湊的方式存放到一起。

36、Redis的內存用完了會發生什麼?

如果達到設置的上限,Redis的寫命令會返回錯誤信息(但是讀命令還可以正常返回。)或者你可以將Redis當緩存來使用配置淘汰機制,當Redis達到內存上限時會沖刷掉舊的內容。

37、Redis是單線程的,如何提高多核CPU的利用率?

可以在同一個服務器部署多個Redis的實例,並把他們當作不同的服務器來使用,在某些時候,無論如何一個服務器是不夠的,
所以,如果你想使用多個CPU,你可以考慮一下分片(shard)。

38、一個Redis實例最多能存放多少的keys?List、Set、Sorted Set他們最多能存放多少元素?

理論上Redis可以處理多達2的32-1的keys,並且在實際中進行了測試,每個實例至少存放了2億5千萬的keys。我們正在測試一些較大的值。
任何list、set、和sorted set都可以放232個元素。
換句話說,Redis的存儲極限是系統中的可用內存值。

39、Redis常見性能問題和解決方案?

  1. Master最好不要做任何持久化工作,如RDB內存快照和AOF日誌文件
  2. 如果數據比較重要,某個Slave開啓AOF備份數據,策略設置爲每秒同步一次
  3. 爲了主從複製的速度和連接的穩定性,Master和Slave最好在同一個局域網內
  4. 儘量避免在壓力很大的主庫上增加從庫
  5. 主從複製不要用圖狀結構,用單向鏈表結構更爲穩定,即:Master <- Slave1 <- Slave2 <- Slave3…
    這樣的結構方便解決單點故障問題,實現Slave對Master的替換。如果Master掛了,可以立刻啓用Slave1做Master,其他不變。

40、Redis提供了哪幾種持久化方式?

RDB持久化方式能夠在指定的時間間隔能對你的數據進行快照存儲.
AOF持久化方式記錄每次對服務器寫的操作,當服務器重啓的時候會重新執行這些命令來恢復原始的數據,AOF命令以redis協議追加保存每次寫的操作到文件末尾.Redis還能對AOF文件進行後臺重寫,使得AOF文件的體積不至於過大.
如果你只希望你的數據在服務器運行的時候存在,你也可以不使用任何持久化方式.
你也可以同時開啓兩種持久化方式, 在這種情況下,
當redis重啓的時候會優先載入AOF文件來恢復原始的數據,因爲在通常情況下AOF文件保存的數據集要比RDB文件保存的數據集要完整.
最重要的事情是瞭解RDB和AOF持久化方式的不同,讓我們以RDB持久化方式開始。

41、如何選擇合適的持久化方式?

一般來說, 如果想達到足以媲美PostgreSQL的數據安全性, 你應該同時使用兩種持久化功能。
如果你非常關心你的數據, 但仍然可以承受數分鐘以內的數據丟失,那麼你可以只使用RDB持久化。
有很多用戶都只使用AOF持久化,但並不推薦這種方式:因爲定時生成RDB快照(snapshot)非常便於進行數據庫備份, 並且 RDB 恢復數據集的速度也要比AOF恢復的速度要快,
除此之外, 使用RDB還可以避免之前提到的AOF程序的bug。

42、修改配置不重啓Redis會實時生效嗎?

針對運行實例,有許多配置選項可以通過 CONFIG SET 命令進行修改,而無需執行任何形式的重啓。
從 Redis 2.2 開始,可以從 AOF 切換到 RDB 的快照持久性或其他方式而不需要重啓 Redis。
檢索 ‘CONFIG GET *’ 命令獲取更多信息。 但偶爾重新啓動是必須的,如爲升級 Redis 程序到新的版本,或者當你需要修改某些目前 CONFIG 命令還不支持的配置參數的時候。


消息隊列

RabbitMQ

1、爲什麼要引入MQ系統,直接讀寫數據庫不行嗎?

其實就是問問你消息隊列都有哪些使用場景,然後你項目裏具體是什麼場景,說說你在這個場景裏用消息隊列是什麼?

面試官問你這個問題,期望的一個回答是說,你們公司有個什麼業務場景,這個業務場景有個什麼技術挑戰,如果不用 MQ 可能會很麻煩,但是你現在用了 MQ 之後帶給了你很多的好處。

先說一下消息隊列常見的使用場景吧,其實場景有很多,但是比較核心的有 3 個:解耦、異步、削峯。

解耦:多系統多進程的數據交換,用pub/sub (發佈/訂閱) .
.
異步:把大數據量的同步處理改爲異步.
.
削峯:一般的A 系統使用 MySQL,扛到每秒 2k 個請求就差不多了,如果每秒請求到 5k 的話,可能就直接把 MySQL 給打死了,導致系統崩潰,用戶也就沒法再使用系統了。如果使用 MQ, 每秒 5k 個請求寫入 MQ,A 系統每秒鐘最多處理 2k 個請求,因爲 MySQL 每秒鐘最多處理 2k 個。A 系統從 MQ 中慢慢拉取請求,每秒鐘就拉取 2k 個請求,不要超過自己每秒能處理的最 大請求數量就 ok,這樣下來,哪怕是高峯期的時候,A 系統也絕對不會掛掉,這又設計請求排隊的問題。

2、消息隊列有什麼優缺點?

優點:

解耦、異步、削峯

缺點:

系統可用性降低
系統引入的外部依賴越多,越容易掛掉。本來你就是 A 系統調用 BCD 三個系統的接口就好了,人 ABCD 四個系統好好的,沒啥問題,你偏加個 MQ 進來,萬一 MQ 掛了咋整,MQ 一掛,整套 系統崩潰的,你不就完了?
.
系統複雜度提高
硬生生加個 MQ 進來,你怎麼保證消息沒有重複消費?怎麼處理消息丟失的情況?怎麼保證消息傳遞的順序性?頭大頭大,問題一大堆,痛苦不已。
.
一致性問題
A 系統處理完了直接返回成功了,人都以爲你這個請求就成功了;但是問題是,要是 BCD 三個系統那裏,BD 兩個系統寫庫成功了,結果 C 系統寫庫失敗了,咋整?你這數據就不一致了。

3、Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什麼優缺點?

https://blog.csdn.net/Dome_/article/details/84990563

4、RabbitMQ 的高可用性如何保證?

相關鏈接: www.javazhiyin.com/22905.html

RabbitMQ 有三種模式:單機模式、普通集羣模式、鏡像集羣模式

單機模式

單機模式不存在高可用。

普通集羣模式

普通集羣模式也不存在高可用性,意思就是在多臺機器上啓動多個 RabbitMQ 實例,每個機器啓動一個。但是你創建的 queue,只會放在一個 RabbitMQ 實例上,但是每個實例都同步 queue 的元數據(元數據可以認爲是 queue 的一些配置信息,通過元數據,可以找到 queue 所在實例)。你消費的時候,實際上如果連接到了另外一個實例,那麼那個實例會從 queue 所在實例上
拉取數據過來。這種方式確實很麻煩,也不怎麼好,沒做到所謂的分佈式,就是個普通集羣。因爲這導致你要麼消費者每次隨機連接一個實例然後拉取數據,要麼固定連接那個
queue 所在實 例消費數據,前者有數據拉取的開銷,後者導致單實例性能瓶頸。而且如果那個放 queue 的實例宕機了,會導致接下來其他實例就無法從那個實例拉取,如果你開啓了消息持久化,讓 RabbitMQ 落地存儲消息的話,消息不一定會丟,得等這個實例恢復了,然後纔可以繼續從這個 queue 拉取數據。

鏡像集羣模式

鏡像集羣模式的策略是高可用策略,指定的時候可以要求數據同步到所有節點的,也可以要求同步到指定數量的節點,再次創建 queue
的時候,應用這個策略,就會自動將數據同步到其他的 節點上去了。

5、如何解決消息隊列的延時以及過期失效問題?

其實本質針對的場景,都是說,
可能你的消費端出了問題,不消費了;
或者消費的速度極其慢,造成消息堆積了,MQ存儲快要爆了,甚至開始過期失效刪除數據了。

針對這個問題可以有事前、事中、事後三種處理

事前:開發預警程序,監控最大的可堆積消息數,超過就發預警消息(比如短信),不要等出生產事故了再處理。

事中:看看消費端是不是故障停止了,緊急重啓。

事後:中華石杉老師就是說的這一種
點擊查看相關網址
需要對消費端緊急擴容,增加處理消費者進程,如擴充10倍處理,但其實這也有個問題,即數據庫的吞吐是有限制的,如果是消費到數據庫也是沒辦法巨量擴容的,所以還是要在吞吐能力支持下老老實實的泄洪消 費。所以事前預防還是最重要的。否則出發刪除過期數據,那就需要再重寫生產消息的程序,重新產生消息。

6、RabbitMQ如何保證不丟數據?

需要考慮3個可能丟數據的地方:生產端、隊列本身、消費端

生產端:

開啓事務(不推薦,太耗性能降低吞吐),推薦開啓 confirm 模式,在生產者那裏設置開啓 confirm 模式之後,你每次寫的消息都會分配一個唯一的 id,然後如果寫入了RabbitMQ 中,RabbitMQ 會給你回傳一個 ack 消息,告訴你說這個消息 ok 了。如果 RabbitMQ 沒能處理這個消息,會回調你的一個 nack 接口,告訴你這個消息接收失敗,你可以重試。而 且你可以結合這個機制自己在內存裏維護每個消息 id 的狀態,如果超過一定時間還沒接收到這個消息的回調,那麼你可以重發。

隊列本身:

就是 RabbitMQ 自己弄丟了數據,這個你必須開啓 RabbitMQ 的持久化,就是消息寫入之後會持久化到磁盤,哪怕是 RabbitMQ 自己掛了,恢復之後會自動讀取之前存儲的數據,一般數據不會丟。
設置持久化有兩個步驟:

  1. 創建 queue 的時候將其設置爲持久化,這樣就可以保證 RabbitMQ 持久化 queue 的元數據,但是它是不會持久化 queue 裏的數據的。
  2. 第二個是發送消息的時候將消息的 deliveryMode 設置爲 2。就是將消息設置爲持久化的,此時 RabbitMQ 就會將消息持久化到磁盤上去。

消費端:

其實和kafka的原理很類似,kafka即手動提交offsize。用RabbitMQ 提供的 ack 機制,簡單來說,就是你必須關閉 RabbitMQ 的自動 ack,通過自己的一個 api 來調用就行,然後每次你自己代碼裏確保處理完的時候,再在程序裏ack
這樣的話,如果你還沒處理完,不就沒有 ack 了?那 RabbitMQ 就認爲你還沒處理完,這個時候 RabbitMQ 會把這個消費分配給別 的 consumer 去處理,消息是不會丟的。

7、如何保證隊列的消息不被重複消費?

這個需要靈活作答,考察的是思考力,因爲消費的場景有很多,有數據庫、有緩存、有第三方接口

  1. 比如針對數據庫,你拿到這個消息做數據庫的insert操作。那就容易了,給這個消息做一個唯一主鍵(或者UUID),那麼就算出現重複消費的情況,就會導致主鍵衝突,避免數據庫出現髒數據。
  2. 再比如redis緩存,你拿到這個消息做redis的set的操作,那就容易了,不用解決,因爲你無論set幾次結果都是一樣的,set操作本來就算冪等操作。
  3. 再比如第三方接口,需要確定兩點,第三方接口程序是有去重能力的,那麼髒一點直接丟數據過去,如果沒有去重能力,還是需要我們來寫程序去重,就是第2點的辦法。

8、集羣節點類型都有什麼?

節點的存儲類型分爲兩種:磁盤節點 ,內存節點

磁盤節點就是配置信息和元信息存儲在磁盤上,內存節點把這些信息存儲在內存中,當然內次節點的性能是大大超越磁盤節點的。
單節點系統必須是磁盤節點,否則每次你重啓RabbitMQ之後所有的系統配置信息都會丟失。
RabbitMQ要求集羣中至少有一個磁盤節點,當節點加入和離開集羣時,必須通知磁盤節點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章