インタビュー質問カタログ - 後続のコンテンツ補足
- Python の基本
-
- Python の新しいスタイルのクラスと古いスタイルのクラスの違い
- Python の `__init__` メソッドと `__new__` メソッドの違い
- シングルトン パターンは Python でどのような問題を解決しますか? 達成方法
- Python 変数のスコープは何ですか? 行動範囲はどこですか
- Python での GIL ロック
- Python のイテレータとジェネレータの違い
- Python はスレッド通信とプロセス通信をどのように実装しますか?
- 開発パターンにおけるオブザーバーパターンとは何ですか?
- 優れた Python 開発パターンとはどのようなものでしょうか?
- フロントエンドとバックエンド間のデータの不一致をトラブルシューティングするにはどうすればよいですか?
- git-flow とは何ですか?
- プロセス、スレッド、コルーチンの違いは何ですか? 基礎となる実装ロジックは?
- ガベージコレクションのメカニズムとは何ですか?
- 循環参照の問題を解決するにはどうすればよいですか?
- Python の内省/反省とは何ですか?
- データベース
-
- データベースの最適化方法にはどのようなものがありますか?
- SQL クエリ時間と特定のクエリ プロセスを表示するにはどうすればよいですか?
- テーブル結合クエリの最適化方法にはどのようなものがありますか?
- 運用中にデッドロックが発生し、データ全体がハングした場合はどうすればよいですか?
- トークンとセッションの長所と短所は何ですか?
- 異なる Web サイトへの直接ログインを実現するにはどうすればよいですか? Aさんはログイン後、Bさんに直接ログインします。
- 数千万のテーブルを最適化するにはどうすればよいでしょうか?
- データベースの同時実行性をテストするにはどうすればよいですか?
- Redis における HGET、GET、HSET、SET の違いと使用シナリオは何ですか? 読み取りと書き込みの効率は?
- ハッシュ可能な値とは何ですか?
- バイナリセキュリティとは何ですか?
- 時系列データとは
- 一般的に使用される時系列データ データベース
- 一般的なツリー構造とその長所と短所は?
- データベースで外部キーの使用が推奨されないのはなぜですか
- enum の代わりに tinyint を使用することが推奨される理由
- プレフィックスインデックスとは何ですか
- 実践的な質問
- バックエンド関連
- コンテナ化された
Python の基本
Python の新しいスタイルのクラスと古いスタイルのクラスの違い
新しいスタイルのクラスのポリモーフィック継承では C3 アルゴリズムが使用され、古いスタイルのクラスでは深さ優先アルゴリズムが使用されます。
Python の__init__
と__new__
メソッドの違い
新しいクラスを作成するときは、まず__new__
インスタンスを作成するメソッドを呼び出してから、__init__
対応するパラメーターを新しいインスタンスに割り当てるメソッドを呼び出します。新しいクラスを作成せずに直接呼び出すと、__init__
関数がトリガーされるだけで、__new__
メソッドはインスタンスを返しますが、__init__
メソッドはインスタンスを返しません。
シングルトン パターンは Python でどのような問題を解決しますか? 達成方法
Python のシングルトン モードは、プログラム内でインスタンスを繰り返し作成する問題を解決します。たとえば、ログ クラスが複数のプログラムでインスタンス化され、プログラム内で複数のクラス オブジェクトがプログラムのパフォーマンスに影響を与える可能性があります。シングルトン モードを回避できます。一般に、シングルトン モードを実装するには 2 つの方法があり、最初の方法は__new__
update メソッドを通じて実装されます。コード スニペットは次のとおりです。
# 创建单实例对象 Singleton
class Singleton():
def __new__(cls, *args, **kwargs):
if no hasattr(cls, '_instance'):
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
class A(Singlenton):
pass
>>> a = A()
>>> id(a)
1302990860592
>>> b = A()
>>> id(b)
1302990860592
>>> a==b
True
>>> a is b
True
デコレータを使用して、単一のインスタンス オブジェクトを完成させることもできます。デコレータを使用すると、元のコードを変更せずに関数関数を追加できます。一般に、関数の入力検査やロギングなどの関連関数を拡張するために使用されます。実装コードは次のとおりです:
def singelton(cls, *args, **kwargs):
instance = {
}
def _singelton(*args, **kwargs):
if cls not in instance:
instance[cls] = cls(*args, **kwargs)
return instance[cls]
return _singelton
@singleton
class MyClass3(object):
pass
Python 変数のスコープは何ですか? 行動範囲はどこですか
関数スコープは LEGB によって要約できます。
- L は関数 logcal の内部スコープを示します。これは、関数内の変数が最初に検索されることを意味します。
- 見つからない場合は、クエリ用の関数内で囲まれた入れ子関数に入ります。
- 再度見つからない場合は、グローバル スコープを入力して検索します。
- グローバル スコープでクエリできない場合は、Python に付属する組み込みスコープ ビルトインを入力してクエリを実行します。
Python での GIL ロック
スレッドの安全な操作を保証するために、スレッドの実行中にスレッドは自動的にロックされ、CPU は現在のスレッド内のタスクのみを実行します。Python のマルチスレッドには利点がありません。一般に、マルチプロセスとコルーチンは自身の処理速度を向上させるために使用されます。プロセス内には複数のスレッドが存在し、スレッドを切り替えることでプロセスタスクの実行が保証されますが、スレッドの切り替えにも時間がかかり、切り替え時間はシステム自体によって制御されるため、コルーチンの概念が提案され、どちらが適切であるかはユーザーが決定します。切り替えるには、コルーチンに基づいて歩留まりが提案されます。
Python のイテレータとジェネレータの違い
ジェネレーターは早くから Python2 から登場しており、プログラム実行中に yield キーワードによってブレークポイントが設定され、ブレークポイントで結果が返されます。プログラムは次回電源が切れるまで next() を通じてブレークポイントで実行され続けます。または、プログラム自体の戻り点は、反復子の簡易バージョンを実装することです。
ジェネレーターは、__iter__
メソッドや__next__
メソッドを手動で実装せずに、 yield を使用して結果を返す特別な反復子です。一方、反復子は、__iter__
反復子オブジェクト自体を返すメソッドを実装する必要があり、また、__next__
反復子の次の値を取得するメソッドも実装する必要があります。
Python はスレッド通信とプロセス通信をどのように実装しますか?
スレッドはキュー Queue を使用して通信し、プロデューサー/コンシューマー モードを採用してキューの内容を監視し、キューが空になると自動的にキューを終了します。プロセス間通信はマルチプロセッシングを使用できます。Manager、
開発パターンにおけるオブザーバーパターンとは何ですか?
オブジェクトが変更されると、そのオブジェクトに依存する他のオブジェクトに通知されます。目的は、オブジェクトの状態が変化したときに他のオブジェクトに通知する方法を解決し、オブジェクトが疎結合であることを確認することです。欠点は、オブジェクトに多くのオブザーバーがある場合、各オブザーバーに通知するのはリソースの無駄であることです。相互間に循環参照がある場合、クラッシュが発生する可能性があります。第 2 に、オブザーバー モードはオブジェクトの状態しか通知できません。変化し、変化の原因を検出できません。サンプルコードは次のとおりです。
# Observer Pattern
# create Observer
class Observer:
def update(self, temp, humidity, pressure):
pass
def display(self):
pass
# create Subject
class Subject:
def register_observer(self, observer):
return
def remove_observer(self, observer):
return
def notify_observer(self):
return
class WeatherData(Subject):
def __init__(self):
# use to save observer
self.observer = []
self.temperature = 0.0
self.humidity = 0.0
self.pressure = 0.0
return
def register_observer(self, observer):
self.observer.append(observer)
return
def remove_observer(self, observer):
self.observer.remove(observer)
return
def get_Humidity(self):
return self.humidity
def get_temperature(self):
return self.temperature
def get_pressure(self):
return self.pressure
def measurements_changed(self):
self.notify_observer()
return
def set_measuerment(self, temp, humidity, pressure):
self.temperature = temp
self.humidity = humidity
self.pressure = pressure
self.measurements_changed()
return
def notify_observer(self):
for item in self.observer:
item.update(self.temperature, self.humidity, self.pressure)
return
class CurrentConditionDisplay(Observer):
def __init__(self, weatherData):
self.weather_data = weatherData
self.temperature = 0.0
self.humidity = 0.0
self.pressure = 0.0
weatherData.register_observer(self)
return
def update(self, temp, humidity, pressure):
self.temperature = temp
self.humidity = humidity
self.pressure = pressure
self.display()
return
def display(self):
print("temprature = %f, humidity = %f" % (self.temperature, self.humidity))
return
class StatiticDisplay(Observer):
def __init__(self, WeatherData):
self.weather_data = WeatherData
self.temperature = 0.0
self.humidity = 0.0
self.pressure = 0.0
WeatherData.register_observer(self)
return
def update(self, temp, humidity, pressure):
self.temperature = temp
self.humidity = humidity
self.pressure = pressure
self.display()
return
def display(self):
print("Statictic = %f, pressuer = %f" % (self.temperature, self.pressure))
return
if __name__ == '__main__':
weather = WeatherData()
display = CurrentConditionDisplay(weather)
weather.set_measuerment(2.0, 3.0, 4.0)
display = StatiticDisplay(weather)
weather.set_measuerment(3.0, 4.0, 5.0)
優れた Python 開発パターンとはどのようなものでしょうか?
コーディング スタイルは PEP8 に準拠しています。コードの機能を示すために、主要なステートメントと関数の定義の下にコメントが使用されています。ログを出力し、例外を処理して、異常なプログラムの実行を継続し、サイトを保存できるようにする機能があります。データ内容はログまたはローカライズされたデータの形式で保存され、追跡調査が容易になります
フロントエンドとバックエンド間のデータの不一致をトラブルシューティングするにはどうすればよいですか?
ログ ファイルとローカル キャッシュ ファイルを監視して、データの不整合が発生している場所を特定します。たとえば、フロントエンド コンソールでネットワークの応答を確認し、バックエンドのデータに問題がないかを確認し、問題がない場合はバックエンドを確認し、ブレークポイントとログからデータの不整合の問題を特定します。 。フロントエンドに問題がある場合は、フロントエンドのスクリプト ファイルを入力してトラブルシューティングを行います。
git-flow とは何ですか?
git-flowは開発プロセスをスクリプトで標準化するツールで、master-developの2つのブランチにより本番環境と開発環境の分離を実現し、テストに合格するとリリースを通じて自動的にバージョンがリリースされ、ホットフィックス ブランチはホット リペア用に提供されています。
プロセス、スレッド、コルーチンの違いは何ですか? 基礎となる実装ロジックは?
-
プロセスとは、プログラムを実行する CPU の単位です。1 つの CPU 上で同時に実行できるプロセスは 1 つだけです。マルチプロセスの本質は、複数のプロセスが一定の規則に従って順番に実行されることです。プロセスはメモリで構成されます。スペース (スペースにはコード、データ、プロセス スペース、開いているファイルが含まれます) と 1 つ以上のスレッド。
-
プロセス内には複数のスレッドがあり、複数のスレッドが相互に切り替わります。標準スレッドは、スレッド ID、現在の命令ポインタ (PC)、レジスタ、スタックで構成されます。
プロセスはオペレーティング システムが CPU に割り当てることができる最小単位であり、スレッドはプログラム自体が制御できる最小単位です。スレッド切り替えのオーバーヘッドは、プロセス切り替えのオーバーヘッドよりもはるかに小さくなります。プロセスは互いに独立しており、同じプロセス内の異なるスレッドがプロセス空間を共有できます。
ガベージコレクションのメカニズムとは何ですか?
Python では主にガベージ コレクションに参照カウントが使用され、メモリ アドレスが参照されるたびに参照カウントが増加し、参照カウントが 0 になるとメモリが回収されます。
参照カウントには循環参照の問題があるため、これを支援するために世代別コレクションとガベージ コレクションのメカニズムが追加されています。ユーザーがオブジェクトを作成すると、新しいリンク リストが配置されます。ユーザーが作成したオブジェクトが最初のリンク リストを満たすと、リンク リストはガベージ コレクション メカニズムによってチェックされ、リンク リスト上の最も古いオブジェクトが次の場所に移動されます。世代別リサイクル機構を実現するには、このようなリンク リストが 3 つあります。
ガベージ コレクション メカニズムは、プログラム内の到達不能なオブジェクトを排除するために、Pyhton が提供する gc モジュールに依存しています。
循環参照の問題を解決するにはどうすればよいですか?
Python でパッケージが参照されるとき、そのパッケージが初めて参照されると__init__.py
、そのパッケージ内のコードが実行され、インポートされたモジュールのトップレベル コード (グローバル変数、インポートなど) が実行されます。この部分では循環参照の問題がよく発生します。
解決:
- モジュールを直接インポートし、
module.function
次の形式で関数を呼び出します。 - 遅延インポートを使用し、関数内または下部でインポートします。
- コード構造を再設計し、統合されたエントリを使用してモジュールをインポートおよび参照します
Python の内省/反省とは何ですか?
コーディングの際、一部のプロパティの名前をユーザーが決定する必要がある場合や、インスタンス化するときに決定する必要がある場合があります。文字列を介してインスタンス化されたオブジェクトにプロパティとメソッドを追加できます。この動作はイントロスペクション/リフレクションと呼ばれます。
リフレクションとは、文字列を介してクラス内の関数を直接操作する動作です。プログラムでは、関数名を直接呼び出して関数を呼び出します。ユーザーが文字列を入力すると、その関数を使用してクラス内の関数を呼び出すことができます。getattr(classers, function_name)
. 検索、戻り値はこのクラスの関数であり、直接使用できます。使用前に、hasattr(classes, function_name)
クラス内に対応する名前のメソッドがあるかどうかを協力して判断できます。
データベース
データベースの最適化方法にはどのようなものがありますか?
-
検索にはサブクエリの代わりに結合を使用します。結合は、2 つのテーブルのデカルト積と特定の列の値を通じて 2 つのテーブルのデータを接続します。一般的なクエリ アルゴリズムには、内部結合、左外部結合、右外部結合などがあります。
ネストループ結合は最も原始的なクエリ方法です。少数のテーブルをメモリにキャッシュし、外部テーブルのデータの各行をクエリし、クエリ条件を満たした後に入力します。一般に効率が最も低くなるのは、数が少ない場合です。テーブルの数が少ない場合、または結合条件に等価性が含まれない場合に使用されます。
ハッシュ結合は一般的なクエリ方法です。小さなテーブルのすべてのデータを取得し、ハッシュ テーブルに書き込みます。外部テーブルのデータの各行を走査し、同等の条件 JOIN KEY を使用してハッシュ テーブルでクエリを実行し、取得します。 0-N の一致するデータ行、結果行を構築した後、クエリ条件と比較し、結果を出力します。
ルックアップ結合は、別の同等の JOIN アルゴリズムであり、番号に従って小さなテーブルを走査します。
SQL クエリ時間と特定のクエリ プロセスを表示するにはどうすればよいですか?
EXPLAIN を使用してこの SQL クエリのプロセスと時間をクエリするには、ROWS と一時テーブルの作成 (クエリされる行の数と作成される一時テーブルの数) に注意を払い、クエリされる行の数と作成される一時テーブルの数を最小限に抑える必要があります。作成された一時テーブルの数。
フィールド名 | 使いやすさ |
---|---|
テーブル | 表示されているデータはどのテーブルですか |
タイプ | 重要な列と型 (良いものから悪いものまで const、eq_reg、ref、range、indexhe、all) |
possible_keys | テーブルに適用できるインデックス。空の場合、使用可能なインデックスはありません。 |
鍵 | 実際に使用されるインデックス |
key_len | 使用するインデックスの長さは短いほど良い |
参照 | インデックスのどの列が使用されているかを表示する |
行 | このクエリで検査する必要がある行の数 |
追加 | このクエリに関する追加の操作情報 |
テーブル結合クエリの最適化方法にはどのようなものがありますか?
解決:
- インデックスの追加: 主キー インデックス、共通インデックス、一意のインデックス、フルテキスト インデックス、集約インデックス (複数列インデックス)
- サブクエリを避け、代わりに結合を使用してください
- where ステートメント内のフィールドに対して null 判定を行わないようにします。そうしないと、インデックスが破棄され、テーブル全体のスキャンが使用されます。
- in と not in の使用は避けてください。これら 2 つのキーワードもテーブル全体のスキャンを引き起こします。in の代わりに存在を使用できます。
- 文字の代わりに数字を使用してみてください
- あいまいなクエリを避ける
- または を結合条件として使用することは避けてください。代わりに Union all を使用できます。
運用中にデッドロックが発生し、データ全体がハングした場合はどうすればよいですか?
- サービスを再起動するかスタンバイデータベースを使用して、本番運用の再開を優先します。
- ログからデッドロックの原因を確認する
- デッドロックサイトでブレークポイントデバッグを実行し、トリガーコードを確認します
トークンとセッションの長所と短所は何ですか?
トークンは、HTTP プロトコルのステートレス ログインを補うために使用されるメソッドです。ユーザーがログインした後、サーバーはそのキーを使用して JSON 文字列を暗号化し、署名します。ユーザーはリクエストを送信するときに文字列を一緒に送信し、サーバーはログイン状態を直接判定することで、ユーザーが異なるドメイン名でドメインをまたいでログインする問題を解決できます。利点は、トークン情報がクライアントに保存されるため、サーバーのリソースを節約できることです。
セッションは、HTTP プロトコルのステートレス ログイン メソッドを補うためにも使用され、ユーザーがログインすると、ユーザーの関連情報がサーバー側に保存されてセッション ライブラリに入力され、対応するセッション ID が返されます。ユーザーがコンテンツにアクセスすると、サーバーはセッション ID を取得してユーザーの身元を確認します。
クライアント側で関連データを分析する人によってトークンがだまされる可能性がありますが、セッションはこの問題を回避します。
異なる Web サイトへの直接ログインを実現するにはどうすればよいですか? Aさんはログイン後、Bさんに直接ログインします。
JWT を使用して、自己署名メソッドを使用してユーザーのログイン情報が有効かどうかを検証します。
数千万のテーブルを最適化するにはどうすればよいでしょうか?
まず、数千万のテーブル内のデータがどの種類のデータに属しているかを判断します。
- 取引フロー、決済フローなどのフロー型データの挿入が主な業務内容です。分散ストレージへの事業分割
- ステータス系データは、ビジネスにおける問い合わせや変更が主な用途であり、残高やステータスなどデータの正確性に対する要件があります。水平方向に分割したり拡張したりしないようにしてください
- システム構成、パス、権限ポイントなどの構成データ。
ビジネス シナリオに合わせて最適化し、混合ビジネスを独立したビジネスに分割し、ステータス データと履歴データを分割します。データは日付、パーティションなどに従って分割し、テーブル名の形式で名前を変更できます。
読み取りが多く書き込みが少ないシナリオの場合は、キャッシュとメモリ内データベースを使用してデータベースの負荷を軽減できます。読み取りが少なく書き込みが多いシナリオの場合は、非同期送信やキュー書き込みなどの方法を使用して書き込み頻度を減らすことができます。ミドルウェア、読み取り/書き込み分離、負荷分散、その他の方法を追加して、水平拡張時のデータベースの可用性を向上させます。
コード内でのトランザクションの使用を標準化して悪用を回避し、SQL クエリ ステートメントを最適化してクエリ効率を向上させ、インデックスを増やします。
運用保守面では、データを定期的にクリーンアップし、ホットデータとコールドデータを分離します。
データベースの同時実行性をテストするにはどうすればよいですか?
Redis における HGET、GET、HSET、SET の違いと使用シナリオは何ですか? 読み取りと書き込みの効率は?
Reids は、共通データとして 5 種類のデータを提供します。
- 文字列文字列
- ハッシュ ハッシュ。通常はキーと値のペアの情報を保存するために使用されます。
- リスト list 文字列を格納でき、繰り返し挿入可能、最大 2^32-1 まで挿入可能、リストの先頭または末尾に追加可能
- セット セット、セットは順序付けされておらず、ハッシュ マッピング テーブルによって実現され、追加、削除、変更、チェックの時間計算量は O(1) です。
- 順序付きセット set、文字列要素のコレクション。各要素は double 型のスコアに関連付けられ、スコアは繰り返しが許可され、このスコアによって並べ替えられます。
- ビットマップ ビットマップは、マップのような構造を通じて 0 または 1 を値として保存し、通常は統計ステータスに使用されます。
- カーディナリティ統計 HyperLogLogs。複数の要素を入力として受け入れ、要素のカーディナリティを計算します。
これらのデータ型の保存と読み取りにはさまざまな操作があります
データの種類 | 読み取り操作 | 書き込み操作 |
---|---|---|
弦 | フーを取得します | set foo 「これは簡単です」 |
文字列(バッチ操作) | Mget foo foo1 | foo “1” foo1 “2” と出会う |
ハッシュ | hget dict:1 | 辞書を設定:1 “123” |
ハッシュ(バッチ操作) | Hgetall ユーザー:1 | Hmset ユーザー:1 「23」「45」 |
リスト | LRANGE ユーザー 0 1 | LPUSH ユーザーのトム |
設定 | SMEMBERS ユーザー | SADDユーザーのトム |
チェック | zrange ユーザー 0 10 | zadd ユーザー 0 トム |
ビットマップ | SETBIT ユーザー:0001 10003 1 | |
ハイパーログログ | PFADD ユーザーのトム |
ハッシュ可能な値とは何ですか?
文字列やタプルなどの不変のデータ構造は、大量のデータをより小さなデータに変換できるため、一定の複雑さの下でクエリを実行するのに便利です。
バイナリセキュリティとは何ですか?
文字列を格納する際にはバイナリストレージがよく使われますが、言語によっては文字列の終わりか始まりを判断する必要があり、文字列を入力すると期待と異なる結果が返される場合があります。バイナリ セキュリティの場合、入力文字列データに特別な処理を行う必要はなく、文字列の長さは既知であり、他のターミネータの影響を受けません。
時系列データとは
時系列データは、時間によってインデックス付けされたデータです。安定した継続的な書き込み、高い同時実行性、および高いスループットの特性があります。より多くの書き込みとより少ない読み取りが行われます。ほとんどの場合、データのみが書き込まれますが、手動で変更されることはまれです。 。同時に、時系列データのホット データとコールド データには大きな違いがあり、ほとんどの人は最近の期間の時系列データに関心があり、初期のデータを読み書きすることはほとんどありません。時間間隔が長いほど、生成されるデータの量が増加します。
一般的に使用される時系列データ データベース
時系列データベース自体は、高同時実行性と高スループットの書き込みをサポートできる必要があり、同時にテラバイト レベルまたはさらに高いレベルのデータ ボリュームで対話型クエリをサポートし、このボリュームのデータ ストレージをサポートできなければなりません。 。通常、LSM ツリーに格納された NoSQL データベース (HBase、Cassandra、TableStore など) が使用されます。
一般的なツリー構造とその長所と短所は?
ツリーの次数は最もリンクされたノードを持つノードの数によって決まり、深さはルート ノードから最も遠いリーフ ノードまでのツリー内の層の数を指します。左右のノードを交換できる木を無順序木といい、その逆のノードの次数が 2 の木を二分木といいます。
線形構造は挿入と読み取りに多くの時間を消費します。一般に、ツリー構造はストレージに使用されます。現在、主流の動的検索ツリーには、二分探索ツリー、バランス二分ツリー、赤黒ツリー、B ツリー、および B+ ツリーが含まれます。最初の 3 つのツリーのクエリの複雑さはツリーの深さに関連しており、後の 2 つは通常、バランスの取れた多方向検索ツリーとして使用されます。
二分探索木の特徴:
- ツリーの左側のサブツリーが空でない場合、左側のサブツリー上のすべてのノードの値はそのルート ノードよりも小さくなります
- ツリーの右側のサブツリーが空でない場合、右側のサブツリー上のすべてのノードの値はそのルート ノードより大きくなります
- ツリーの左側と右側のサブツリーも二分探索ツリーです
バイナリ ツリー ノードの命名:
- 親のないノードはルート ノードと呼ばれ、バイナリ ツリーにはルート ノードが 1 つだけあります。
- 親ノードを持つノードは子ノードと呼ばれ、共通の親ノードを持つ子ノードは兄弟ノードと呼ばれます
- 子ノードのないものはリーフ ノードと呼ばれ、バイナリ ツリーは複数のリーフ ノードを持つことができます。
二分木の数学的性質:
- バイナリ ツリーの i 番目の層には最大 2 (i-1) 個のノードがあり、深さが k のバイナリ ツリーには最大 2 k-1 個のノードがあります。
- 二分木では、葉ノードの数が n0 で、次数 2 のノードの数が n2 の場合、n0=n2+1 となります。
データベースで外部キーの使用が推奨されないのはなぜですか
外部キーは、データベース テーブル間の関係を制約および確認するために使用されます。データを挿入する場合、外部キーで接続されているテーブルがチェックされ、ダーティなデータが挿入されないことが確認されます。削除する場合は、カスケード削除も使用して無効なデータを削除します。データの信頼性と正確性を確保できます。
これらの機能は実稼働環境で何らかの問題を引き起こす可能性があります。
- データを挿入するたびに他のテーブルをチェックする必要があり、効率に影響します
- データが削除されるたびに、他のデータ削除がトリガーされ、データ量により大量のデータ削除が発生し、クラッシュが発生する可能性があります。
- データを挿入すると、対応する外部キー テーブルの行がロックされ、他の業務操作に影響します。
- データベースの構造が制限されており、データベースとテーブルを分割することが困難
enum の代わりに tinyint を使用することが推奨される理由
tinyint は内容を数値で表すことができ、列挙値としての enum は値または列挙値のインデックスによってクエリできます。次に例を示します。
enum = {
'a','b','c'}
select * from tbl_name whre enum = 2
select * from tbl_name where enum = 'b'
両者は同等であり、insert into を使って挿入する場合、enmu が数値として設計されている場合、本来は数値を挿入したいインデックスが列挙値を挿入するためのインデックスになってしまう可能性があります。 enum の enumeration value, if 最後に追加せず、どちらかに追加すると、他の場所のレコードが混乱する可能性があります 最後に、enmu は MySQL の特徴的なフィールドであり、他のデータベースではサポートされていませんが、これはデータのインポートとエクスポートに影響します。
プレフィックスインデックスとは何ですか
テキストおよび文字列タイプに対してプレフィックス インデックス作成を実行し、プレフィックスの違いが大きいテキストに適し、インデックスの長さを短縮します。
ALTER TABLE table_name ADD KEY(column_name(prefix_length))
実践的な質問
学生の平均成績と受講したコースの数を確認します
[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-wy8GYap8-1666748452406)(/Users/tomjerry/Library/Application%20Support/typora-ユーザーイメージ/イメージ- 20221022215437619.png)]
既知: S は学生番号、sc テーブルは各科目の学生の記録です。
質問 1: SQL ステートメントを作成して、生徒番号と各生徒の平均成績を調べ、平均成績が 90 以上のレコードを表示します。
select S, avg(score)
from sc
group by S
having avg(score) > 90
質問 2: 学生の学生番号、名前、コース数、および合計成績を調べる SQL ステートメントを作成してください。
select t1.S, t1.Sname, count(t2.C), sum(t2.score)
from student t1
inner join sc t2
on t1.S = t2.S
group by t1.S
バックエンド関連
クローラーの一般的なバイパス方法?
登山防止対策 | 解決 |
---|---|
IPソースの検出 | IPプロキシを使用する |
検証コード | 画像認識・コーディングプラットフォーム |
暗号化パラメータ | JSリバースエンジニアリング |
ブラウザヘッダーの検証 | ユーザーエージェントマスカレード |
ソースの検証 | 参照ヘッダーを追加する |
ログインして表示 | 模擬ログイン、Cookie 偽装 |
個々のユーザーの訪問を制限する | マルチスレッド化 |
JS アンチデバッグ | ブレークポイントのバイパス |
ヘッダーと Cookie にフィールドを配置することの違いは何ですか?
Cookie は、同じドメイン名にアクセスする場合にのみリクエスト ヘッダーに追加され、ヘッダーにはすべてのドメイン名のリクエストでこのフィールドが含まれます。
同一生成元ポリシーとは何ですか?
同じプロトコル、同じ IP、同じポートの要件に従ってアクセスすると、他のページは現在のページのリソースにアクセスできません。
Flask はマルチスレッドですか、それともマルチプロセスですか? Flask でスレッドとコルーチンの間の競合を解決するにはどうすればよいですか?
デフォルトの開発 Web サーバーはカスタマイズできます。デフォルトは単一プロセスおよび単一スレッドです。マルチスレッドを有効にする場合は threadad = True、マルチプロセスを有効にする場合は process=2 です。
スレッド内のコルーチンはスレッド リソースを共有するため、変更する必要があります
コンテナ化された
1. Dockerと仮想システムの違い
仮想システムは、ホスト マシン上に仮想レイヤーを作成し、仮想化されたオペレーティング システムを通じてアプリケーションをインストールします。Docker を使用する場合、ホスト システムを通じて Docker エンジンが作成され、これに基づいてアプリケーションがインストールされます。したがって、第 2 レベルの起動、より少ないリソース占有を実現し、Dockerfile を通じて構成ファイルを作成して自動作成とデプロイを実現できます。
コンテナ内の名前空間を介して、さまざまなコンテナを直接分離します。