2020年10月秋の募集C ++舞台裏インタビュー質問セットの目録

1. TCPスリーウェイハンドシェイクプロセスでは、どの段階で受け入れが発生しますか?

受け入れは、スリーウェイハンドシェイクの後に発生します。
最初のハンドシェイク:クライアントはsynパケット(syn = j)をサーバーに送信します。
2番目のハンドシェイク:サーバーはsynパッケージを受信し、クライアントのsY(ack = j + 1)を確認すると同時に、ASKパッケージ(ask = k)を送信する必要があります。
3番目のハンドシェイク:クライアントはサーバーからSYN + ACKパケットを受信し、確認応答パケットACK(ack = k + 1)をサーバーに送信します。
ハンドシェイクが完了すると、クライアントとサーバーはtcp接続を確立します。このとき、accept関数を呼び出してこの接続を取得できます。

2. UDPプロトコルを使用しているときに、ターゲットマシンがデータパケットを取得したかどうかを確認するにはどうすればよいですか?

タイムスタンプやインクリメンタルintなど、各パケットに一意のIDを挿入できます。
送信者は、データを送信するときにこのIDと送信時間をローカルに記録します。
受信者は、データを受信した後、応答としてIDを送信者に送信します。
送信者が応答を受信した場合、受信者は対応するデータパケットを受信したことがわかります。指定された時間内に応答を受信しなかった場合、データパケットが失われる可能性があります。上記のプロセスを繰り返し、相手が受信したことが確認されるまで再送信する必要があります。

3. Tencentサーバーは毎秒同時に2WのQQ番号をオンラインで持っており、5分以内に再ログインしたQQ番号を見つけて印刷します。

スペースが大きな配列A [qq番号]を定義するのに十分な大きさで、最初はゼロの場合。このqq番号は、スペースでなく、今回は2以上の
A [qq番号] +
最終集計QQ番号に到達ました成熟したアイデアは2wx 300sであるため、6000.000バケットが使用されます。タイムアウトを削除するアルゴリズムについては後で説明するため、平均バケットサイズは1です。1010qq番号があるとすると、各バケットのq番号は10 10 /(6 * 10〜6 )であり、これが最も挿入された時間です。効率が悪い(同じバケットを挿入する場合、挿入位置は順番に検索されますqqのノード構造は基本的に上記のすべての人と同じであり、後で説明するように出力リストにポインターが追加されます。







struct QQstruct {
    
    
num_type qqnum,
timestamp last_logon_time,
QQstruct *pre,
QQstruct *next,
OutPutlist *out //用于free节点的时候,顺便更新下输出列表
}
另外

2つのポインタリストを追加
するサイズが300最初の循環リンクリストには、QQStructを指すドメインが付属しており、300秒以内にqqポインタを周期的に格納します。
時間が経過するとすぐに料金が下がりますので、すべてのバケットが占めるスペースが2wX30以内であることを確認してください。2つ
目は、問題を出力する必要があるノードである出力リストです。
ログインしたユーザーが5分以内にまったく繰り返さない場合は、1秒あたり2wのノードを
解放します。ただし、解放された場合、ノードがバケットに入れ
られると重複が発生すると更新されるため、時間が本当に超過しているかどうかを判断する必要があります。最終ログイン時刻。もちろん、現時点では、出力する必要のあるリストにq番号を入れてください

4. C ++のメモリ管理方法を教えてください。

C ++では、メモリは主に5つのストレージ領域に分割されます。
スタック:ローカル変数、関数パラメータなどがこの領域に格納され、コンパイラによって自動的に割り当てられて解放されます。スタックはコンピュータシステムのデータ構造に属し、対応する入力スタックと出力スタックがあります。コンピュータ命令によってサポートされ、スタックのアドレスを格納するために特別なレジスタを割り当てます。効率は高く、メモリスペースは連続していますが、スタックのメモリスペースは制限されています。
ヒープ:プログラマーは手動で割り当てと解放(新規、削除)を行う必要があります。これは、動的な割り当て方法です。メモリスペースはほぼ無制限であり、メモリスペースは連続していないため、メモリの断片化が発生します。オペレーティングシステムには、スペースとメモリを記録するリンクリストがあります。メモリ要求を受信すると、リンクリストがトラバースされ、要求されたスペースよりもスペースが大きい最初のヒープノードが検索され、ノードがプログラムに割り当てられ、リンクリストからノードが削除されます。通常、システムは、メモリスペースを解放するために、削除するメモリスペースの最初のアドレスに割り当てられたメモリサイズを記録します。
グローバル/静的ストレージ領域:グローバル変数、静的変数はこの領域に割り当てられ、DATAセクション(グローバル初期化領域)とBSSセクション(グローバル非初期化セクション)を含むプログラムの最後に自動的に解放されます。その中で、初期化されたグローバル変数と静的変数はDATAセクションに格納され、初期化されていないグローバル変数と静的変数はBSSセクションに格納されます。BSSセグメントの機能:プログラムが実行される前にBSSセグメントが自動的にクリアされるため、プログラムが実行される前に、初期化されていないグローバル変数と静的変数が0になります。
テキスト定数領域:定数が格納され、変更は許可されません。プログラムの終了後にシステムによってリリースされます。
プログラムコード領域:プログラムのバイナリコードを保存します
ここに写真の説明を挿入
ここに写真の説明を挿入

主要なインターネット企業からのインタビュー資料やビデオ資料の詳細については、VXの公式アカウントであるZero SoundAcademyをフォローして無料で入手してください。

5.リンクされたリストのマージを順序付けました。

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
    
    
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    
    
if (l1 == NULL) {
    
    
return l2;
} else if (l2 == NULL) {
    
     
return l1;
} else {
    
    
if (l1->val <= l2->val) {
    
    
l1->next = mergeTwoLists(l1->next, l2);
return l1;
} else {
    
    
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
}
};

6.STLのハッシュバケット長定数を含むハッシュテーブルの実現。

ハッシュテーブルの実現には、主にハッシュ関数と衝突処理の2つの問題があります。
1)ハッシュ関数(ハッシュ関数)。最も一般的なハッシュ関数:f(x)= x%TableSize。2
)衝突の問題(異なる要素のハッシュ値は同じです)。線形検出、二次検出、オープンチェーンなど、衝突の問題を解決する方法はたくさんあります。SGLバージョンは、リンクリストを使用して同じハッシュ値の要素を保持するオープンチェーン方式を使用します。
オープンチェーン方式ではテーブルサイズが素数である必要はありませんが、SGI STLは引き続き素数を使用してテーブルサイズを設計し、機能を提供しながら、いつでもアクセスできる28個の素数(徐々に関係の約2倍を示す)を計算します。 、28個のプライム番号の中で「特定の番号に最も近く、特定の番号より大きい」プライム番号を照会するために使用されます。

7.ハッシュテーブルを再ハッシュする方法と、そこに格納されているリソースを処理する方法。

まず、再ハッシュが必要な理由を考えます
。loadFactor(load factor)<= 1の場合、ハッシュテーブルルックアップの予想される複雑さはO(1)であるためです。したがって、ハッシュテーブルに要素を追加するたびに、それがloadFactor <1の場合にのみ追加できます。
C ++のベクトル展開方法を模倣して、loadFactor == 1がハッシュテーブルで見つかるたびに、元のバケット配列(新しいバケット配列と呼ばれる)のダブルスペースが開かれ、元のバケット配列のすべての要素が新しいバケット配列に転送されます。バケット配列内。ここでの転送では、要素を1つずつ新しいバケットに再ハッシュする必要があることに注意してください。

8. redisのマスタースレーブレプリケーションはどのように機能しますか?

古いバージョンのRedisには、同期とコマンド伝播のみがあります。新しいバージョンのコピー機能には、同期機能の一部が追加されています。
1)同期:
2)コマンド伝播:
マスターサーバーが実行する書き込みコマンド、つまりマスターサーバーとスレーブサーバーの不整合を引き起こす書き込みコマンドをスレーブサーバーに送信して実行する場合スレーブサーバーが同じ書き込みコマンドを実行する場合、マスターサーバーとスレーブサーバーは再び一貫した状態に戻ります。
3)部分同期:(切断後の再複製)
複製オフセット:マスターサーバーとスレーブサーバーの複製オフセットを比較することにより、プログラムはマスターサーバーとスレーブサーバーが一貫した状態にあるかどうかを簡単に知ることができます。
コピーバックログバッファ:メインサービスは、最新の書き込みコマンドをコピーバックログバッファに保存します。コピーバックログバッファは、ファーストイン、ファーストアウトのキューです。
サーバー実行ID:スレーブは最後に同期されたマスターサーバーのIDを記録します。

9. ubuntuが起動すると、システムは何をしますか?

  1. BIOS
    BIOSプログラムをロードすると、最初にコンピューターのハードウェアが基本的な動作条件を満たしているかどうかがチェックされます。これは「ハードウェアセルフテスト」と呼ばれます。ハードウェアのセルフチェックが完了すると、BIOSは制御権をスタートアッププログラムの次のステージに移します。
  2. 読み取りMBR
    コンピューターは、デバイスの最初のセクターを読み取ります。つまり、最初の512バイトを読み取ります。512バイトの最後の2バイトが0x55と0xAAの場合は、デバイスを起動に使用できることを示します。そうでない場合は、デバイスを起動に使用できないことを示し、制御は「開始シーケンス」で次のデバイスに転送されます。 。
  3. ブートローダ
    コンピュータは、「マスター・ブート・レコード」の前にあるマシンコードの446バイトを読み取った後、この場合では、それはもはや転送は、特定のパーティションにコントロールしていないが、プリインストールされた「ブートローダー」を実行します、ユーザーは起動するオペレーティングシステムを選択します。
    ブートローダーは、オペレーティングシステムカーネルが実行される前に実行される小さなプログラムです。この小さなプログラムを通じて、ハードウェアデバイスを初期化し、メモリスペースのマップを確立して、システムのソフトウェアとハ​​ードウェア環境を適切な状態にし、オペレーティングシステムカーネルの最終呼び出しの準備をすべて行うことができます。
    ブートローダーにはいくつかの種類があり、その中でGrub、Lilo、spfdiskが一般的なローダーです。Linux環境では、現在最も人気のあるブートマネージャーはGrubです。
  4. カーネルのロード
    カーネルがロードされます。カーネルがロードされた後、オペレーティングシステムが初期化され、プロセスの優先度に従ってプロセスが開始されます。

10.プログラムはいつスレッドを使用する必要があり、いつシングルスレッドが効率的ですか?

1時間のかかる操作にスレッドを使用して、アプリケーションの応答を改善します。2C
/ Sアーキテクチャのサーバー側の同時スレッドなどの並列操作にスレッドを使用して、ユーザーの要求に応答します。
3マルチCPUシステムでは、スレッドを使用してCPU使用率を高めます
。4プログラム構造を改善します。長くて複雑なプロセスは、複数のスレッドに分割され、いくつかの独立または半独立の実行部分になる可能性があります。このようなプログラムは、理解と変更を容易にします。
それ以外の場合は、シングルスレッドが使用されます。

おすすめ

転載: blog.csdn.net/lingshengxueyuan/article/details/108208100