筆試分析之騰訊2013暑期實習

4月份的筆試,考得不好,經過暑期的磨礪,回頭再看那些題目,有些就豁然開朗了

1.關於類型轉換

1.32位機上根據下面的代碼,問哪些說法是正確的?

signedchar a = 0xe0;

unsignedint b = a;

unsignedchar c = a;

A.a>0 && c>0爲真B.a == c爲真C.b的十六進制表示是:0xffffffe0D.上面都不對

我總結了一個規律:

1.任何數在計算機中是以補碼的形式存在的,所以如果我們printf輸出則是補碼輸出

2.signed轉換爲unsigned的時候,最高位的1加入計算,最高位位0的不變

3.unsigned轉換爲signed的過程和上面的相反

4.char型轉換爲int的時候,先做類型提升,提升的時候,無論char是有符號還是無符號,要保證該數的正負性,即如果原數是正,提升補0,原數爲負,提升補1,然後在轉換到第2.3兩種情況下

5.int型轉換爲char型,可能要考little endian/big endian,不管哪種,只要取最低位置的那個字節就可以了

下面的測試程序可以的出上面的結論:

#include <stdio.h>
#include <iostream>

using namespace std;

int main()
{
    /*-signed -> unsigned*/
    signed char s0 = 0xe0;
    unsigned char t0 = s0;
    printf("s0:%d\nt0:%d\n",s0,t0 );

    /*+signed -> unsigned*/
    signed char s1 = 0x0e;
    unsigned char t1 = s1;
    printf("s1:%d\nt1:%d\n",s1,t1 );

    /*unsigned(最高位1) -> signed*/
    unsigned char s2 = 0xe0;
    signed char t2 = s2;
    printf("s2:%d\nt2:%d\n",s2,t2 );

    /*unsigned(最高位0) -> signed*/
   unsigned char s3 = 0x0e;
    signed char t3 = s3;
    printf("s3:%d\nt3:%d\n",s3,t3);

    /*+signed -> signed int -> unsigned int */
    signed char m = 0x0e;
    signed int n = m;
    unsigned int p = m;
    printf("m:%d\nn:%d\np:%d\n", m, n,p);

    /*-signed -> signed int -> unsigned int*/
    signed char a = 0xe0;
    signed int  b = a;
    unsigned int c = a;
    printf("a:%d\nb:%0x\nc:%0x\n",a ,b, c);

    unsigned char a1 = 0xe0;
    signed int  b1 = a1;
    unsigned int c1 = a1;
    printf("a1:%d\nb1:%0x\nc1:%0x\n",a1 ,b1 , c1);

    int x = 0x1234;
    char y = *((char*)&x);
    printf("%0x\n",y);

    return 0;
}

2.關於little endian和big endian

a) Little-Endian就是低位字節排放在內存的低地址端,高位字節排放在內存的高地址端。

b) Big-Endian就是高位字節排放在內存的低地址端,低位字節排放在內存的高地址端

測試程序:

#include <stdio.h>

void main()
{
    int x = 0x12345678, i = 0;
    for(i = 0; i < 4; i++)
        printf("%0x\n", *((char*)&x+i));
}
小端字節輸出:78 56 34 12

大端字節輸出:12 34 56 78

判斷小端大端還有可以使用聯合體,例如:

int main()
{
	union{
		int x;
		char c;
	}u;
	u.x = 1;
	if(u.c == 1)
		printf("little endian\n");
	else
		printf("big endian\n");
	return 0;
}



3.關於虛擬內存調度的算法

在內存有限的情況下,擴展一部分外存作爲虛擬內存,真正的內存只存儲當前運行時所用得到信息,虛擬頁式存儲管理減少了進程所需的內存空間,卻也帶來了運行時間變長這一缺點:進程運行過程中,不可避免地要把在外存中存放的一些信息和內存中已有的進行交換,由於外存的低速,這一步驟所花費的時間不可忽略。因而,採取我們要採取好的算法來減少這部分話費的時間

常見的算法有以下幾種:

LRU:近期最少使用算法,每次替換的是最早替換進來的

FIFO:先進先出算法,維護一個隊列,每次替換的是最早進入隊列的那一頁

OPT:最優替換算法,根據未來的替換頁來替換,說明見圖下說明

先說明一下缺頁的概念,當CPU訪問內存中的數據時,數據不存在就會發生缺頁,此時如果數據在虛擬內存中,我們需要把數據從虛擬內存中置換到內存中,上面三種算法產生的缺頁次數是不一樣的

看如下三個圖(從網上找的,不是自己畫得,但都能很好的說明問題)


說明:當請求2時,2已在內存中,我的理解是做了一個替換2->2,所以下次請求1的時候,2是最近才進入隊列的,需要替換掉2->1

缺頁次數:16次




缺頁次數:15



說明:例如,替換4的時候,我們看到4後面我們需要2和1頁,所以我們此時就不要把2和1替換出來,應該把3替換出來,即3->4,再比如,請求6頁的時候,看到6後面需要2和1,我們就把5替換出來

缺頁次數:11次

我們可以看到OPT算法的效率最高,但是要實現OPT算法,唯一的辦法是讓程序先執行一遍,記錄下實際的頁地址流情況,很明顯實際,實際上,經常把這種算法用來作爲評價其它頁面替換算法好壞的標準。


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