1. 程式人生 > >【面試總結】騰訊MIG一面

【面試總結】騰訊MIG一面

找朋友內推的騰訊MIG一面,問了專案,也問了很多基礎的東西,現總結如下:

1、函式呼叫的匹配順序

函式模板、模板顯式特化函式和普通函式的優先選擇順序,總結出以下4點:
1)如果有引數型別完全匹配的普通函式,則呼叫之;

2)否則,如果有匹配的模板顯式特化函式,則呼叫之;

3)否則,如果模板函式能夠推匯出一個引數型別完全匹配的函式例項,則呼叫之;

4)否則,如果呼叫函式的實參能夠進行隱式轉換成與普通函式或者模板顯式特化函式的型別匹配,則呼叫之;

5)如果以上四條都不能匹配,則函式匹配失敗,發生編譯錯誤。

2、類的建構函式呼叫虛擬函式

簡直了,這在《Effective C++》裡 #9 絕不在建構函式和解構函式裡呼叫虛擬函式 

有詳細的介紹,我居然堂而皇之地忘記了。

base class 構造期間 virtual 函式絕不會下降到 derived class 階層。非正式的說法也許比較傳神:在 base class 構造期間, vritual 函式不是 virtual 函式。

借用下面的例子說明之:

#include <iostream>
using namespace std;

class base
{
	public:
		base(){fun();}
		virtual void fun(){cout << "base::fun" << endl;}
};

class derived: public base
{
	public:
		derived(){fun();}
		virtual void fun(){cout << "derived::fun" << endl;}
};

int main()
{	
	derived d;
	return 0;
}

輸出為:
base::fun		//構建base部分時呼叫了 base::fun
derived::fun		//構建derived部分時呼叫了 derived::fun


3、對比紅黑樹和AVL樹

答的不好,大家自行 google。

4、shell,awk熟不熟?

(⊙v⊙)嗯,用的不多,還需學習

5、詳細介紹下IPC

關於此,可以去看我的 【Linux程式設計】系列,持續更新中。。。

6、熟不熟悉一些開源的東西?

(⊙v⊙)嗯,不。。。

7、Linux程序排程策略

猝。。。

查看了幾天資料,先看寫最基本的策略:

最常見的策略有:

1)FIFO:又稱FCFS(First-Come-First-Served),最基本的策略。

Processes are dispatched according to their arrival time on the ready queue. Being a nonpreemptive discipline, once a process has a CPU, it runs to completion. 

2)RR:輪轉排程。簡單,公平,被廣泛使用策略。

In the round robin scheduling, processes are dispatched in a FIFO manner but are given a limited amount of CPU time called a time-slice or a quantum.

3)SJF(Shortest-Job-First):Shortest-Job-First (SJF) is a non-preemptive discipline in which waiting job (or process) with the smallest estimated run-time-to-completion is run next.

4)SRT(Shortest-Remaining-Time):The SRT is the preemtive. The process with the smallest estimated run-time to completion is run next, including new arrivals.In SRT scheme, a running process may be preempted by a new arrival process with shortest estimated run-time.

5)Priority Scheduling:The basic idea is straightforward: each process is assigned a priority, and priority is allowed to run. Equal-Priority processes are scheduled in FCFS order. The shortest-Job-First (SJF) algorithm is a special case of general priority scheduling algorithm.Priority scheduling can be either preemptive or non preemptive.A major problem with priority scheduling is indefinite blocking or starvation. A solution to the problem of indefinite blockage of the low-priority process is aging. Aging is a technique of gradually increasing the priority of processes that wait in the system for a long period of time.

6)Multilevel Queue Scheduling

In a multilevel queue scheduling processes are permanently assigned to one queues.

The processes are permanently assigned to one another, based on some property of the process, such as

  • Memory size
  • Process priority
  • Process type

Algorithm choose the process from the occupied queue that has the highest priority, and run that process either

  • Preemptive or
  • Non-preemptively

Each queue has its own scheduling algorithm or policy.

Possibility I (Main)

    If each queue has absolute priority over lower-priority queues then no process in the queue could run unless the queue for the highest-priority processes were all empty.

Possibility II 
    If there is a time slice between the queues then each queue gets a certain amount of CPU times, which it can then schedule among the processes in its queue. For instance:

  • 80% of the CPU time to foreground queue using RR.
  • 20% of the CPU time to background queue using FCFS.

Since processes do not move between queue so, this policy has the advantage of low scheduling overhead, but it is inflexible.


7)Multilevel Feedback Queue Scheduling

Multilevel feedback queue-scheduling algorithm allows a process to move between queues. It uses many ready queues and associate a different priority with each queue.

The Algorithm chooses to process with highest priority from the occupied queue and run that process either preemptively or unpreemptively. If the process uses too much CPU time it will moved to a lower-priority queue. Similarly, a process that wait too long in the lower-priority queue may be moved to a higher-priority queue. Note that this form of aging prevents starvation.


在此基礎上我們瞭解下 Linux 核心主要運用到的三種排程策略:
1)SCHED_FIFO:注意與上面的 FIFO 區分。先入先出排程演算法(實時排程策略,RT),相同優先順序的任務先到先服務,高優先順序的任務可以搶佔低優先順序的任務。

2)SCHED_RR:注意與上面的 RR 區分。輪轉排程演算法(實時排程策略,RT),採用時間片,相同優先順序的任務當用完時間片會被放到佇列尾部(與SCHED_FIFO的主要區別),以保證相同優先順序的公平性。同樣,高優先順序的任務可以搶佔低優先順序的任務。

不同點:

     當採用SHCED_RR策略的程序的時間片用完,系統將重新分配時間片,並置於就緒佇列尾。放在佇列尾保證了所有具有相同優先順序的RR任務的排程公平。    

    SCHED_FIFO一旦佔用cpu則一直執行,一直執行直到有更高優先順序任務到達或自己放棄。

    如果有相同優先順序的實時程序(根據優先順序計算的排程權值是一樣的)已經準備好,FIFO時必須等待該程序主動放棄後才可以執行這個優先順序相同的任務。而RR可以讓每個任務都執行一段時間。

相同點:

    RR和FIFO都只用於實時任務。

    建立時優先順序大於0(1-99)。

    按照可搶佔優先順序排程演算法進行。

    就緒態的實時任務立即搶佔非實時任務。


3)SCHED_NORMAL:也叫(SCHED_OTHER),用於普通任務,通過CFS排程器實現。

在核心中,程序優先順序的取值範圍是通過一個巨集定義的,這個巨集的名稱是MAX_PRIO,它的值為140

而這個值又是由另外兩個值相加組成的,一個是代表nice值取值範圍的NICE_WIDTH巨集,另一個是代表實時程序(realtime)優先順序範圍的MAX_RT_PRIO巨集。

說白了就是,Linux實際上實現了140個優先順序範圍,取值範圍是從0-139,這個值越小,優先順序越高。nice值的-2019,對映到實際的優先順序範圍是100-139

核心的優先順序表示

對於CFS策略,這個策略是在2008年被提出。在這個重新設計的排程器中,時間片,動態、靜態優先順序以及IO消耗,CPU消耗的概念都不再重要。CFS採用了一種全新的方式,對上述功能進行了比較完善的支援。其設計的基本思路是:我們想要實現一個對所有程序完全公平的排程器。

CFS策略裡很重要的一個概念是:虛擬執行時(vruntime)

對於CFS來說,衡量的時間累積的絕對值都是一樣紀錄在vruntime中的,但是不同優先順序的程序時間增長的比率是不同的,高優先順序程序時間增長的慢,低優先順序時間增長的快。比如,nice為19的程序,實際佔用cpu為1秒,那麼在vruntime中就記錄1s。但是如果是-20的程序,那麼它很可能實際佔CPU用10s,在vruntime中才會紀錄1s。CFS還包含睡眠公平概念以便確保那些目前沒有執行的任務(例如,等待 I/O)在其最終需要時獲得相當份額的處理器。

1)CFS如何實現pick next

                                                                

所有可執行的任務通過不斷地插入操作最終都儲存在以時間為順序的紅黑樹中,對處理器需求最多的任務(最小虛擬執行時)儲存在樹的左側,處理器需求最少的任務(最大虛擬執行時)儲存在樹的右側。 為了公平,CFS排程器會選擇紅黑樹最左邊的葉子節點作為下一個將獲得cpu的任務。這樣,樹左側的程序就被給予時間運行了。

2)tick中斷
    在CFS中,tick中斷首先更新排程資訊。然後調整當前程序在紅黑樹中的位置。調整完成後如果發現當前程序不再是最左邊的葉子,就標記need_resched標誌,中斷返回時就會呼叫scheduler()完成程序切換。否則當前程序繼續佔用CPU。從這裡可以看到 CFS拋棄了傳統的時間片概念。Tick中斷只需更新紅黑樹,以前的所有排程器都在tick中斷中遞減時間片,當時間片或者配額被用完時才觸發優先順序調整並重新排程。

3)紅黑樹鍵值計算
    理解CFS的關鍵就是了解紅黑樹鍵值的計算方法。該鍵值由三個因子計算而得:一是程序已經佔用的CPU時間;二是當前程序的nice值;三是當前的cpu負載。程序已經佔用的CPU時間對鍵值的影響最大,其實很大程度上我們在理解CFS時可以簡單地認為鍵值就等於程序已佔用的 CPU時間。因此該值越大,鍵值越大,從而使得當前程序向紅黑樹的右側移動。另外CFS規定,nice值為1的程序比nice值為0的程序多獲得10%的 CPU時間。在計算鍵值時也考慮到這個因素,因此nice值越大,鍵值也越大。

關於程序排程,還可以參見《,這篇文章貼地氣地講述了Linux程序排程。

總之感覺跪了。。還需努力