C++面接の知識ポイントまとめ(1)

(1) C++11の新機能

1.nullptr

nullptr の目的は、NULL を置き換えることです。

ある意味従来の C++ は NULL と 0 を同じものとして扱い、コンパイラが NULL をどのように定義するかによって、NULL を ((void*)0) と定義するコンパイラもあれば、直接 0 と定義するコンパイラもあります。 .

C++ では void * を他の型に直接暗黙的に変換することはできませんが、NULL が ((void*)0) として定義されている場合、char *ch = NULL; をコンパイルするときに、NULL を 0 として定義する必要があります。これは依然として問題を引き起こし、C++ のオーバーロード機能で混乱を招きます。

この問題を解決するために、C++11 では nullptr キーワードが導入されました。これは、null ポインターと 0 を区別するために特別に使用されます。nullptr の型は nullptr_t であり、任意のポインターまたはメンバー ポインター型に暗黙的に変換でき、それらとの等値または不等値を比較することもできます。NULL を使用する必要がある場合は、nullptr を直接使用してください。

2. 型推論 auto/decltype

C++11 では、型推定を実装するために auto と decltype の 2 つのキーワードが導入されており、コンパイラが変数の型を判別できるようになっています。

auto str1="aaaaa";//str1的类型是const char*
auto str2="aaaaa"s;//str2的类型是string

末尾の戻り型、auto および decltype の連携 (C++11):

template<typename T, typename U>
auto add(T x, U y) -> decltype(x+y) {
    return x+y;
}

C++14 以降では、通常の関数に戻り値の推論を直接許可することができます。

template<typename T, typename U>
auto add(T x, U y) {
    return x+y;
}

3.インターバル反復

std::vector<int> arr(5, 100);
for(std::vector<int>::iterator i = arr.begin(); i != arr.end(); ++i) {
    std::cout << *i << std::endl;
}

なる:

// & 启用了引用
for(auto &i : arr) {    
    std::cout << i << std::endl;
}

4. 詳細: https://blog.csdn.net/jiange_zh/article/details/79356417

(2) C++でのデータ型判定

1. typeid

typeid(str)==typeid(int/const char*/string...)`

2.シン

int a;
cin>>a;
if(cin.good()){}else{} 

間違えて再入力する必要がある場合は、cin.clear() 関数を使用してエラー ビットをクリアする必要があります。

(3) 仮想関数は C++ でどのように実装されていますか?

仮想関数テーブルと仮想関数ポインタによって実現され、各オブジェクトには仮想関数テーブル ポインタがあり、各クラスには仮想関数テーブルがあります。仮想関数テーブル ポインタは 4 バイトのサイズを持ち、オブジェクトの開始アドレスに格納されます。対応するクラスのすべての仮想関数は、仮想関数テーブルに格納されます。

(4) 仮想機能アドレスの取得方法

クラスに仮想関数がある場合、コンパイラはこのクラスの仮想関数テーブルを生成します.各仮想関数のアドレスは、各仮想関数の宣言順に仮想関数テーブルに格納されます. that this virtual function The function table does not exist in the class, and for each object of this class, and for each object of this class, the compiler will generate a transparent and invisible pointer for it. このポインターは、仮想関数テーブル ポインターであり、仮想関数テーブルの場所を指します。つまり、クラスに仮想関数がある場合、オブジェクト a が宣言されていると仮定すると、32 ビット コンパイルの場合、オブジェクトのメモリ レイアウトの最初の 4 バイトに仮想関数テーブルのアドレスが格納されます。を。したがって、仮想関数テーブルは最初の 4 バイトでわかり、仮想関数テーブルには、各仮想関数のアドレスが仮想関数の宣言順に格納されます。

(5) 64ビットシステムがアドレスを保存するスペースはどれくらいですか

内存地址是16进制保存的,一个内存(内存空间)是一个字节(8bit):
16位操作系统的内存地址占用大小是16位,即2字节
32位操作系统的内存地址占用大小是32位,即4字节
64位操作系统的内存地址占用大小是64位,即8字节
128位操作系统的内存地址占用大小是128位,即16字节

(6) Baidu の Web サイトにアクセスするプロセスはどのようなものですか?

1.DNS 解決

ブラウザは、最初にブラウザ自体によってキャッシュされた DNS レコードを検索します。必要なレコードがブラウザ キャッシュに見つからない場合、またはレコードの有効期限が切れている場合は、ホスト ファイルが検索されます。必要なレコードがホスト ファイルに見つからない場合、またはレコードが期限切れになった場合、ドメイン名解決サーバーは解決要求を送信します。ドメイン名解決サーバーにドメイン名のレコードがない場合は、再帰的 + 反復解決が開始されます。
(まず、ドメイン名解決サーバーがルート ドメイン サーバーに要求を送信し、次にルート ドメイン サーバーが com ドメイン サーバーの IP を通知し、次にドメイン名解決サーバーが com ドメイン サーバーに要求を送信します。 . ルート ドメイン サーバーには www がありません。baidu.com の IP ですが、baidu.com ドメイン サーバーの IP があります。当社のドメイン名解決サーバーは、baidu.com ドメイン サーバーに要求を送信します。 www.baidu.com の IP アドレスが取得されます。)

2. TCP リクエストを開始する

ブラウザは、1024 より大きいローカル ポートを選択して、ターゲット IP アドレスのポート 80 への TCP 接続要求を開始します。標準の TCP ハンドシェイク プロセスの後、TCP 接続が確立されます。

3. HTTP リクエストを開始する

確立された TCP 接続では、Web ページの要求が HTTP プロトコル標準に従って送信されます。

4.負荷分散

(1) 負荷分散とは サーバーが多数のユーザー アクセスをサポートできない場合、ユーザーを 2 つ以上のサーバーに分散させる方法は負荷分散と呼ばれます。
(2) Nginx 負荷分散、LVS-NAT、LVS-DR など、負荷分散には多くの方法があります。ここでは、単純な Nginx 負荷分散を例として取り上げます。
(3)Nginxとは?Nginx はパフォーマンス重視の HTTP サーバーであり、Apache や lighttpd と比較して、メモリが少なく安定性が高いという利点があります。Nginx には、コア、ハンドラー、フィルター、ロードバランサーの 4 種類のモジュールがあります。ここではそのうちの 2 つについて説明します。つまり、ロード バランシングを担当するロード バランサー モジュールと、一連のフィルタリング操作を実行するフィルター モジュールです。

(プラットフォームに負荷分散が装備されている場合、前の手順で DNS 解決によって取得された IP アドレスは、Nginx 負荷分散サーバーの IP アドレスである必要があります。したがって、ブラウザーは Web ページ要求を Nginx 負荷分散サーバーに送信します。Nginx設定した割り当てアルゴリズムとルールに従って、バックエンドのリアル Web サーバーを選択し、それと TCP 接続を確立し、ブラウザーから送信された Web ページ リクエストを転送します. Web サーバーはリクエストを受け取り、応答を生成し、送信しますWeb ページを Nginx 負荷分散サーバーに送信します。Nginx 負荷分散サーバーは、Web ページをフィルター チェーンに渡して処理し、ブラウザーに送り返します。)

5. ブラウザのレンダリング

(1) ブラウザは、ページの内容に応じて DOM ツリーを生成します。CSSの内容に合わせてCSS Rule Tree(ルールツリー)を生成します。JS 実行エンジンを呼び出して JS コードを実行します。
(2) DOM Tree と CSS Rule Tree に従って Render Tree (プレゼンテーションツリー) を生成します。
(3) Render Tree に従って Web ページをレンダリングします。
ブラウザーがページのコンテンツを解析すると、そのページが、読み込まれていない画像、css ファイル、および js ファイルなどの他の静的コンテンツを参照していることが判明したため、6 番目のステップがあります。

6. Web ページの静的リソースの読み込み

次のプロセスは、ブラウザが url に従って、url の下の画像コンテンツをロードすることです。基本的に、ブラウザはプロセスの最初の部分を再開しますが、違いは、サーバーのバックエンドのバランスを取る役割を担うサーバーがアプリケーション サーバーではなく、静的リソースを提供するサーバーであることです。

(7) 連結リストの交差を判断するには? 連結リストがリングを持っているかどうかを判断するには? リングエントリのアドレスを見つけるには? なぜこれを探しているのですか?どのように証明するのですか?

連結リスト交差判定

  1. 2 つのリンクされたリストの最後のノードが同じノードである限り、2 つのリンクされたリストの終了ノードが同じノードであるかどうかを判断し、リンクされたリストが交差する必要があります。
  2. 最初に、2 つの連結リストの長さ lenListA と lenListB をそれぞれ取得し、次に、より長い連結リストを N ステップ、N=(lenListA-lenListB) 絶対値にします。次に、2 つの連結リストのノードが同じになるまで、2 つの連結リストが同時に進みます. このとき、このノードは、2 つの連結リストが交差する開始ノードです.

連結リストにループがあると判断する(高速ポインタと低速ポインタ)

  1. 最初に、このリンク リストの先頭ノードを同時に指す 2 つのポインター 1 と 2 を作成します。
  2. 大きなループを開始し、ループ本体で、ポインター 1 を 1 ノードずつ下に移動させ、ポインター 2 を 2 ノードずつ下に移動させ、2 つのポインターが指すノードが同じかどうかを比較します。同じであれば連結リストに循環があると判断し、異なっていれば次の循環に進む。

リングエントリアドレス

最初に、リンクされたリストの長さを N、リングの長さを n と仮定すると、高速ポインターと低速ポインターの会合ノードを直接計算できます。

1. n>=N/2 の場合、高速ポインターと低速ポインターが交わる n 番目のノード。この時点でスロー ポインターがリング内にある必要があると推測できます。

スローポインターがn歩歩くと、ファストポインターはスローポインターよりn歩多い2n歩歩き、円を一周してn個のノードに戻るだけなので、このタイミングで出会う。

2. n<N/2 の場合、高速ポインタと低速ポインタは (NN%n) 番目のノードに一致します。

N%n<n であるため、この時点で低速ポインタはすでにリング内にあり、高速ポインタは低速ポインタよりも (NN%n) ステップ多く、(NN%n) は n の倍数でなければなりません。速いポインターは遅いポインターよりも速いだけです。円の周りを完全に一周するだけで、この時点で速い針と遅い針が出会います。

(8) 2 つの連結リストが交差するかどうかを判断する方法は?

リングを持つ 2 つの連結リストが交差する場合、2 つの連結リストのリングは同じリングでなければなりません。

まず、2 つのリンクされたリストにリングがあるかどうかを判断し、リングがある場合は、リングのエントリ ポイントを見つけます。連結リスト 1 は、リングのエントリ ポイント loop1 から開始します。これは、loop1 以降のノードはすべてリング上にあるため、将来必ず loop1 に戻るからです。連結リスト 2 のループ エントリ ポイント loop2 が loop1 に戻る前に検出されない場合、連結された 2 つの連結リストは交差せず、null を返します。それ以外の場合は交差します。

(9) unordered_map と map の違い

1.头文件 unordered_map>;  map>
2.unordered_map 内部实现:哈希表;map 内部实现:红黑树
3.unordered_map 查找效率:非常高;map 则需要挨个遍历查找,效率低下
4.unordered_map 是否有序:无序;map 内部实现了红黑树,故map存入元素时会自动排序,且默认升序

おすすめ

転載: blog.csdn.net/qq_46140765/article/details/129666900