1. ASP.NET MVC のリクエスト処理フロー
ユーザーが MVC アプリケーションにアクセスすると、リクエストはまず HTTP パイプラインを通過します。具体的には、パイプラインの PostResolveRequestCache イベントで UrlRoutingModule が実行され、リクエスト URL に合致するルートが特定されます。その後、対応する MvcHandler が生成され、コントローラーのインスタンス化、アクションの実行へと進みます。最後に、アクションの結果(ActionResult)がビューエンジンによってレンダリングされ、レスポンスとして返されます。
2. Web API の役割と利点
Web API は、RESTful なサービスを構築するための軽量なフレームワークです。HTTP プロトコルの機能をフルに活用し、主にデータの提供やシステム間の連携に使用されます。フロントエンドとバックエンドを完全に分離(デカップリング)できるため、SPA(Single Page Application)やモバイルアプリとの相性が非常に良いのが特徴です。
3. データベースの断片化(フラグメンテーション)とは
断片化とは、テーブルへのアクセス時に通常よりも多くのディスク I/O が発生し、パフォーマンスが低下する状態を指します。大きく分けて以下の 2 種類があります。
- 論理的な断片化(OSレベル): データベースファイルがディスク上で連続した領域に配置されていない状態。ファイルサイズの頻繁な自動拡張などが原因で発生します。
- インデックスの断片化: データの挿入・更新・削除(DML操作)によって発生します。
4. 内部断片化と外部断片化
内部断片化: インデックスページ内の空き領域が増える現象です。例えば、データの削除によってページ内に隙間ができ、1 ページに収まるはずのデータが複数のページに分散してしまうことで、読み取り時の I/O 効率が悪化します。
外部断片化: インデックスの論理的な順序と、物理的なページ配置の順序が一致しなくなる現象です。データの挿入に伴う「ページ分割」が主な原因です。範囲検索などで順次読み取りを行う際の性能に悪影響を及ぼします。
5. 断片化の解消方法
- インデックスの再構築(Rebuild): 既存のインデックスを削除して作り直します。最も効果的ですが、実行中にテーブルがロックされる可能性があります(Online オプションで軽減可能)。
- インデックスの再構成(Reorganize): 既存のページを整理します。リソース消費が少なく、実行中もアクセスを妨げませんが、劇的な改善は見込めない場合があります。
- フィルファクター(Fill Factor)の設定: インデックス作成時にページにあえて空き領域(予約領域)を作ることで、ページ分割の頻度を下げ、断片化の発生を抑制します。
6. カーソルの概念と注意点
カーソルは、結果セットから 1 行ずつデータを取り出して処理するための仕組みです。ポインタのように現在の行を指し示します。複雑なロジックを 1 行ごとに適用したい場合に便利ですが、メモリ消費が激しくパフォーマンスが低下しやすいため、可能な限りセットベース(SQL文一括処理)の操作が推奨されます。
7. エンディアン(Big Endian / Little Endian)
マルチバイトのデータをメモリに配置する際の順序を指します。
- ビッグエンディアン: 上位バイトから順に低位アドレスへ配置。人間にとって読みやすく、数値比較に適しています(TCP/IPなど)。
- リトルエンディアン: 下位バイトから順に低位アドレスへ配置。計算処理の効率が良いとされます(Intel系プロセッサ、C#の整数型など)。
8. AJAX のメリットとデメリット
メリット: ページ全体をリロードせずにデータ更新が可能、非同期通信によるユーザー体験の向上、サーバー負荷の分散。
デメリット: ブラウザの「戻る」ボタンが効かない、SEO(検索エンジン最適化)に工夫が必要、クライアントサイドのコード量増加による複雑化。
9. バブルソートの実装例
隣接する要素を比較し、必要に応じて入れ替えるシンプルなアルゴリズムです。
public void BubbleSort(int[] data)
{
bool isSwapped;
int n = data.Length;
for (int i = 0; i < n - 1; i++)
{
isSwapped = false;
for (int j = 0; j < n - 1 - i; j++)
{
if (data[j] > data[j + 1])
{
// 要素の入れ替え
int temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
isSwapped = true;
}
}
// 入れ替えが発生しなければ終了
if (!isSwapped) break;
}
}
10. .NET と C# の関係
.NET: アプリケーションを実行するための共通言語ランタイム(CLR)やクラスライブラリを含むフレームワーク(基盤)です。
C#: .NET 上で動作するプログラムを記述するためのオブジェクト指向プログラミング言語です。C# 以外にも VB.NET や F# などが .NET 基盤を利用できます。
11. アクセス修飾子の種類
- private: 同一クラス内のみ。
- protected: 同一クラスおよび派生クラス内。
- internal: 同一アセンブリ(プロジェクト)内。
- public: 制限なし。
12. String と StringBuilder の違い
String は不変(Immutable)です。結合のたびに新しいメモリ領域が確保されるため、大量の結合操作ではパフォーマンスが低下します。一方、StringBuilder は可変(Mutable)であり、既存のバッファ内で文字列を操作するため、ループ内での文字列操作などに適しています。
13. フィボナッチ数列の再帰実装
public int GetFibonacci(int n)
{
if (n <= 0) return 0;
if (n == 1 || n == 2) return 1;
return GetFibonacci(n - 1) + GetFibonacci(n - 2);
}
14. ref パラメーターと out パラメーター
どちらも参照渡しに使用されますが、以下の点が異なります。
- ref: 渡す前に変数を初期化しておく必要があります。メソッド内で値を書き換えるかどうかは任意です。
- out: 渡す前の初期化は不要ですが、メソッド内で必ず値を代入(初期化)して終了する必要があります。
15. 装箱(Boxing)と拆箱(Unboxing)
値型(int, structなど)を object 型などの参照型に変換することをボックス化(Boxing)と呼び、ヒープ領域にコピーが作成されます。逆に、参照型から値型へ戻すことをボックス化解除(Unboxing)と呼びます。これらはオーバーヘッドを伴うため、多用するとパフォーマンスに影響します。
16. Web API の認証(JWT)
ステートレスな認証を実現するために、JSON Web Token(JWT)がよく使われます。ユーザーがログインすると、サーバーは署名付きのトークンを発行します。クライアントは以降のリクエストの HTTP ヘッダーにこのトークンを含めることで、自身の身元を証明します。
17. クラス(Class)と構造体(Struct)
- クラス: 参照型。ヒープメモリに配置されます。継承が可能です。
- 構造体: 値型。スタックメモリに配置されます。継承はできません。軽量なデータ保持に適しています。
18. SQL: 行から列への変換 (PIVOT)
SQL Server では PIVOT 演算子を使用して、行データを列方向に展開できます。逆の操作は UNPIVOT です。
19. ADO.NET の主要コンポーネント
SqlConnection: データベースとの接続。SqlCommand: SQL命令の実行。SqlDataReader: 前方参照専用の高速なデータ読み取り。SqlDataAdapter: データベースと DataSet/DataTable 間の橋渡し。
20. マネージドコード(Managed Code)
共通言語ランタイム(CLR)の制御下で実行されるコードのことです。ガベージコレクションによるメモリ管理、型安全性のチェック、例外処理などのサービスを CLR から受けられます。C# で書かれたコードのほとんどはマネージドコードです。