JAVA共通のコード最適化技術---インタビューの概要

コードの最適化、非常に重要な問題。

  • コードの最適化は、建設中の建物のようなものです、あなたが使用量を完了するために、セメントの唯一の10トンを持っているでしょう、あなたが使用して、セメントの30トンを最適化するのが面倒です。これは、コンピュータ上のリソースの無駄である、故人間メンテナンスがより困難です。

  • コードの最適化の目的は、以下のとおりです。

  • 1、减小代码的体积

  • 2、提高代码运行的效率


あなたはいつも道路歩行プログラマの友人に行きたいと思った場合、あなたは「という本をお勧めします達人プログラマーを著者はプロジェクト開発における優れた実践の多くの側面を説明し、我々は思考の良い方法を持っている必要があり、」 、問題を説明するための楽観的な態度。私が手助けをしたいです。


  • 図1に示すように、可能な限り指定されたクラス、最終の改質方法
  • final修飾子クラスと派生されていません。JavaコアAPIでは、java.lang.Stringなど、最終的なアプリケーションの多くの例があり、クラス全体は、最終あります。クラスのための最終的な修飾子を指定したクラスは、最終的な修飾方法はオーバーライドできないようにする方法として指定し、継承することはできませんことができます。最終としてクラスならば、すべてのメソッドのクラスは最終的なものです。Java编译器会寻找机会内联所有的final方法,内联对于提升Java运行效率作用重大特定のJavaランタイムの最適化を参照してください。これは50%の平均によって性能を向上させることができます。

  • 2、オブジェクトを再利用しよう
  • これは、Stringオブジェクトは、文字列が接続されている場合は特にStringBuilderの/ StringBufferの場所を使用する必要があります。由于Java虚拟机不仅要花时间生成对象,以后可能还需要花时间对这些对象进行垃圾回收和处理そのため、プログラムのパフォーマンスに大きな影響をもたらすでしょう、あまりにも多くのオブジェクトを生成します。

  • 3、ローカル変数を使用するようにしてください
  • 调用方法时传递的参数以及在调用中创建的临时变量都保存在栈中速度较快などの静的変数、インスタンス変数、などの他の変数は、ヒープ、低速で作成されます。また、操作の方法で作成したスタック変数は、コンテンツがなくなって、追加のガベージコレクションを完了していません。

  • 図4に示すように、流れを閉じます
  • Java编程过程中,进行数据库连接、I/O流操作时务必小心,在使用完毕后,及时关闭以释放资源。これらの大きなオブジェクトの操作の大規模なオーバーヘッドシステムの原因となりますので、わずかなミスが重大な結果につながります。

  • 変数のダブルカウントを最小限にするために5、
  • 明確なコンセプト、メソッド呼び出しは、方法は一つだけの文章であっても、また方法、復旧サイト完成し、呼び出し元のメソッドを呼び出すときに、サイトを保護するために、スタックフレームの作成など、そこに消費されています。したがって、たとえば、次
    の操作:
for (int i = 0; i < list.size(); i++)

{...}
  • 推奨代替品:
for (int i = 0, int length = list.size(); i < length; i++)

{...}

  • 必要なときにのみ作成され、可能な限り6、遅延ロード戦略、
  • 例えば:
String str = "aaa";if (i == 1)
{
list.add(str);
}
  • 勧告を交換してください
if (i == 1)
{
String str = "aaa";
list.add(str);
}

  • 図7に示すように、異常な注意
  • パフォーマンスへの異常な有害。例外は、新しいオブジェクトを作成するために最初にスローされ、Throwableのコンストラクタ関数呼び出しインタフェース名にfillInStackTrace()ローカル同期方法にfillInStackTrace()メソッドは、収集情報コール追跡にスタックをチェックします。只要有异常被抛出,Java虚拟机就必须调整调用堆栈,因为在处理过程中创建了一个新的对象。例外は唯一のエラー処理のために使用することができ、プログラムの流れを制御するために使用すべきではありません。

  • 8.キャッチ...ループ内で使用しないでください...、あなたは最も外側の上に置く必要があります
  • 最後の場合を除きます。理由もなくそう書かれた場合は、限り、あなたはほとんどのシニアリーダーシップ、少し強迫性障害があるとして、おそらくあなたは、なぜ、このゴミコードが書き込み呪い

  • コンテンツの長さはアレイ状のボトムセットに追加されると推定される場合に、図9に示すように、ツールは、初期の長さを指定します
  • そのようなStringBuilderの例に、等のArrayList、LinkedLlist、のStringBuilder、StringBufferの、HashMapの、HashSetの、など。
  • 16文字の(1)のStringBuilder()//デフォルト・スペースの割り当て
  • (2)のStringBuilder(int型のサイズ)//デフォルトスペースの割り当てサイズの文字
  • (3)のStringBuilder(String str)文字16ワードの//デフォルトの割り当て+ str.length()文字スペース
  • これは、パフォーマンスを大幅に向上させることができ、初期容量のクラス(だけのStringBuilder以上のように本明細書で言及)によって設定することができます。例えばStringBuilderのバーの長さを保持することができ、現在のStringBuilder内の文字の数を示します。StringBuilderのが最大容量に達した時は、それ自体が2プラス2倍の電流容量を増加しますのでStringBuilderのが最大容量に達したときに、それは新しい文字配列し、古いキャラクターを作成する必要があります文字の新しい配列に配列の内容をコピーする - これは非常にコスト業績です。あなたは5000に最も近い2のべき乗の長さを指定せずに5000文字程度ストアへの文字配列にかかわらず、拡張プラス2の時、4096で見積もることができれば、その後、想像:
  • 4096、8194に基づき、(1)は、その後、文字配列のサイズを適用し、開始が2倍以上に節約、文字配列5000のサイズを指定することができれば、12290文字配列のサイズを提出したのと同等にまで追加スペースの
  • (2)このようにして、メモリ空間の無駄を行くと、コードの効率を低下させるために、文字の新しい配列にコピーし、元の4096の文字。合理的な初期容量を設定するためのツールのセットを達成するために、基になる配列が間違っていないとそう、それはすぐに結果をもたらすでしょう。しかし、HashMapのように、この配列は、セットリストを達成することをノートは+である、あなたがテーブルの上に接続オブジェクトの可能性はほぼゼロであるという理由だけで、のように、初期サイズとセットの大きさを推定します。2,000の要素が新しいHashMapの(128)、新しいハッシュマップ(256)を使用してもよい提供があると推定される場合、2の初期サイズN番目のパワーを設定することを推奨。

  • 10、System.arraycopyの()コマンドを使用して、大量のデータをコピーします

  • 乗算および除算を使用して11、シフト演算
    、例えば:
for (val = 0; val < 100000; val += 5)
{
a = val * 8;
b = val / 2;
}
  • コンピュータの底面には、動作位置が最も便利であるので、シフト操作が大幅にパフォーマンスを向上させることができ、最速は、それは次のように改正提案されています。
for (val = 0; val < 100000; val += 5)
{
a = val << 3;
b = val >> 1;
}
  • 移位操作虽然快,但是可能会使代码不太好理解,因此最好加上相应的注释。

  • 12、内側ループは、オブジェクト参照を作成し続けません
  • 例えば:
for (int i = 1; i <= count; i++)
  {
   Object obj = new Object();
     }
  • このような行為は、コピーObjectオブジェクトの参照カウントを持っているメモリにつながる多くを数えることができ、それはメモリのコストがあり、読むことをお勧めします。
Object obj = null;
for (int i = 0; i <= count; i++) { 

obj = new Object();

 }
  • この場合、唯一のメモリオブジェクトのオブジェクト参照、各新しい新しい
    オブジェクト()場合、メモリ空間の割引大幅に異なるオブジェクトの何も、だけメモリへのオブジェクトのオブジェクトの基準点。

  • 唯一の13は、効率性と型チェックの考慮事項に基づいて、配列は、可能な限り使用されなければならない、我々はArrayListのを使って配列のサイズを決定することはできません

  • 14、スレッドのセキュリティニーズがない限りはHashMap、ArrayListを、StringBuilderを、を利用する、またはパフォーマンス上のオーバーヘッドの使用につながった3つの同期メカニズムの後にハッシュテーブル、ベクトル、StringBufferのを、使用することはお勧めしません。

  • 15、公共の静的な決勝として配列を宣言しません

  • これは無意味であるため、それだけで、最終的な静的ための基準を定義し、またはアレイの内容を自由に変更することができ、アレイは、アレイは、外部クラスにより変更することができることを意味する公共セキュリティの脆弱性、として宣言され


  • 16、可能な限り適切な実施形態の場合には単一と
  • シングルトンは、負荷の負担を軽減負荷までの時間を短縮し、負荷の効率を改善するが、すべての場所が単一の場合に適していないことができ、簡単な言葉で、一つのケースは、主に以下の三つの側面に適用されます。
  • (1)リソースの使用を制御するには、スレッドによって制御されるリソースへの同時アクセスを同期させます
  • (2)リソースを節約するために、制御インスタンスを生成します
  • (3)制御は、複数のプロセスまたはスレッド無関係通信の間達成するように、直接的な関連で、データを共有しました

  • 17、スタティック・ランダム変数を使用して回避しよう
  • オブジェクトへの参照を静的変数として定義されているときには、知っている、そしてGC通常、ヒープメモリのようなオブジェクトによって占有され再利用されていません。
public class A{
private static B b = new B();
}
  • アンインストールされていない場合、プログラムが終了するまで、同じクラスAのライフサイクルのこの静的変数bでは、クラスAは、次いで、B物体基準点Bは、永久的なメモリであろう

  • 18は、タイムリーな除去セッションはもはや必要ではありません
  • セッションがあるが、もはやアクティブクリアするには、多くのアプリケーションサーバは、デフォルトのセッションタイムアウト時間、通常は30分を持っていません。より多くの会話を維持する場合は、アプリケーションサーバーの必要性、メモリ不足、オペレーティングシステムは、ディスクへのデータの一部を譲渡する場合、アプリケーションサーバは、MRUに基づくことができる(最近最も頻繁に使用される)アルゴリズムは、非アクティブなセッションの一部がディスクにダンプですさらにはメモリ例外を投げすることができます。セッションをディスクにダンプする場合、それは最初に直列化されなければならない、大規模なクラスタ、オブジェクトをシリアル化され、コストは非常に高価です。セッションが不要になったときしたがって、それは速やかに明確な会話にHttpSessionの無効()メソッドを呼び出してはなりません。

  • 19、インターフェイスのセットを使用すると、反復する代わりに、foreachループのループのための最も一般的に使用する必要があり、そのようなArrayListのようランダム・を達成するために
  • これは、JDKは、ユーザーにお勧めです。解釈RandomAccessインタフェース用JDKのAPIです:彼らは高速なランダムアクセスをサポートすることを示すために使用されるRandomAccessインタフェースを実現するために、このインタフェースの主な目的は、一般的なアルゴリズムはランダムまたはシーケンシャルアクセスリストに適用するために、自分の行動を変えることができるようにすることです良いを提供することができますパフォーマンス。実際の経験が示すよう、クラスのインスタンスRandomAccessインタフェースのために、假如是随机访问的,使用普通for循环效率将高于使用foreach循环;反过来,如果是顺序访问的,则使用Iterator会效率更高。
  • 次のようなコードを決定することができます。
if (list instanceof RandomAccess)
{
 for (int i = 0; i < list.size(); i++){}
  }
  else{
       Iterator<?> iterator = list.iterable();
          while (iterator.hasNext())
       {
         iterator.next()
          }
       }
  • foreachのループ変数の長さのパラメータと原則:foreachループのイテレータにイテレータの基礎となる原理は、Javaのシンタックスシュガー1を参照してください。だから、言葉の後に反復するためのforeachループを使用して、クラスのインスタンスを順次アクセスすることを意味「逆に、それがシーケンシャルアクセスの場合、イテレータは高効率になります使用します」。

  • 20、同期コードブロックを使用して別の同期方法
  • それは、そうでない場合は、同期ブロックを利用して、全体の方法を同期させるために必要な決定同期コードを必要としないものを避けることができない限り、テキストブロック方式では、マルチスレッドのモジュールでこの同期ロックは、非常に明確にされていますまた、コード実行の効率に影響を与え、同期。

  • 21、定数は、静的最終として宣言され、大文字で指定されています
  • したがって、コンパイル時に、あなたは運転中に一定の計算値の生成を回避するために、一定のプールにコンテンツを置くことができます。加えて、将常量的名字以大写命名也可以方便区分出常量与变量

  • 22は、使用していないいくつかのオブジェクトを作成していない、いくつかのクラスをインポートしていない使用しないでください
  • 、「輸入java.utilのは、使用されることはありません」「私が使用されていないローカル変数の値」のコードが表示されますが、不要なコンテンツを削除してください場合、これは、無意味です。

  • 23、プログラムは、リフレクションを使用しないように実行されています
  • 反射是Java提供给用户一个很强大的功能,功能强大往往意味着效率不高メソッドInvoke特に方法、特にプログラムにおける反射の頻繁な使用が実行され、推奨されません、実際に必要な暗示的なアプローチがある場合は、これらのクラスは、インスタンスを反映して、プロジェクトの開始時にロードする必要が反映されていますオブジェクトの、メモリに置かれ - それは、プロジェクトの終了に時間を過ごすために始めたどのくらいのユーザーが唯一気にしない、ケアとの対話を終了する最速の応答時間を取得します。

  • データベース接続プーリングとスレッドプールを使用して24、
  • 両方のプールは、前者が作成したスレッドを破壊し、頻繁に回避することができ、頻繁な開閉の接続を、避けることができ、再利用のためのオブジェクトであります

  • 25、バッファ入力と出力を使用してIO操作ストリーム
  • 緩衝入出力ストリーム、大幅IOの効率を向上させることができる、すなわちBufferedReaderの、BufferedWriterの、BufferedInputStreamを、なBufferedOutputStream、

  • 26、挿入の順序とのArrayListを使用して、より多くのランダムアクセスシナリオであり、中間要素を削除するには、LinkedListのを使用して、より多くのシーンを挿入しました
  • ArrayListのとLinkedListのノウハウの原則を理解します

  • 27は、パブリックプロセスがあまりにも多くのパラメータを持っていることはできません。

  • メソッドこれらのメソッドにあまりにも多くのパラメータは、2つの主な欠点がある場合は、外部から提供されるパブリックメソッド:

  • 1、オブジェクト指向プログラミングの考え方に違反し、Javaやストレス、すべてがあまりにも多くの仮パラメータ、およびオブジェクト指向プログラミングのアイデアは適合しません、オブジェクトであります

  • 2、あまりにも多くのパラメータは、必然的に誤り確率メソッド呼び出しの増加につながる
    番号、3,4バーを指し、「あまり」について。例えば、我々は、JDBCの方法を用いてinsertStudentInfoを書き込み、学生情報学生テーブルとして挿入される10個のフィールドがあり、これら10個のパラメータは、挿入形状パラメータの方法としては、エンティティ・クラス内にカプセル化することができます


  • 28、文字列変数と文字列定数は、時定数文字列EDITORIALに等しいです
  • これは、比較的一般的なヒントで、次のコードが存在する場合:
String str = "123";if (str.equals("123")) {
...
}
  • 提案された変更
String str = "123";if ("123".equals(str))
{
...
}
  • 这么做主要是可以避免空指针异常

  • 29、Javaでそれを知っていれば(I == 1)としてください(1 == i)がそこには違いはありませんが、あれば前者がと話すの読書習慣、

  • 30.アレイののtoString()メソッドを使用しないでください
  • toStringを使って配列が()プリントアウト何を見ては、次のとおりです。
public static void main(String[] args)
   { 
     int[] is = new int[]{1, 2, 3};
     System.out.println(is.toString());
 }
  • 値出力
[I@18a992f
  • 意図は、配列参照をヌル・ポインタ例外によって引き起こされるので、空があるかもしれない、配列の内容を印刷することです。しかし、()は、配列のtoStringのために意味がありませんが、コレクションのtoString()は、コレクションの内部の内容をプリントアウトすることができますがあるため、書き換えのtoStringオブジェクト()メソッドの親AbstractCollectionsコレクション。

  • 31は、基本的なデータが範囲外タイプキャストを下にしないでください
  • これは、望ましい結果を得ることはありません。
public static void main(String[] args){
    long l = 12345678901234int i = (int)
    System.out.println(i);
  }
  • 私たちはそれらのいくつかを期待するかもしれないが、結果は次のとおりです。
1942892530

説明してください。:Javaはそう、64ビットで8バイト長であるべきであるコンピュータで12345678901234である
0000 0000 0000 0000 0,000,101,100,111,010 0,111,001,111,001,110 0,010,111,111,110,010
INTデータ4は、32ビットバイト、前者32からバイナリデータの上位列の除去は低い:0,111,001,111,001,110 0,010,111,111,110,010

バイナリ文字列は小数点1942892530として表される
ので、コンテンツは、米国以上のコンソールに出力されます。


  • 33、(.toString基本データ型の列に基本データ型)が最速の方法は、String.valueOf(データ)は、「最も遅いデータ+」が続きます
  • 1、String.valueOf()メソッドは、基礎となる持つInteger.toString()メソッドが、所定のショートコールを呼び出し
  • 2、持つInteger.toString()メソッドが言うことではなく、ダイレクトコール
  • 3、I +「」底のStringBuilderは、縫合することにより、第1追記方法を使用して実装し、その後、toString()メソッドは、文字列を取り

  • 地図を横断する最も効率的な方法を使用して34、
  • 地図を通過する多くの方法がありますが、通常我々が必要とするシーンが地図キーと値を通過することです、それは使用することをお勧めし、最も効率的な方法は次のとおりです。
    public static void main(String[] args)
    {
        HashMap<String, String> hm = new HashMap<String, String>();
        hm.put("111", "222");
        Set<Map.Entry<String, String>> entrySet =   hm.entrySet();
        Iterator<Map.Entry<String, String>> iter =  entrySet.iterator();
        while (iter.hasNext())
        {
            Map.Entry<String, String> entry = iter.next();
            System.out.println(entry.getKey() + "\t" +entry.getValue());
        }
    }

  • 推奨され35、リソースを閉じる()が別々に操作しました
try{
        XXX.close();
        YYY.close();
    }catch (Exception e)
    {
...
    }
  • 提案された変更
try{ XXX.close(); }catch (Exception e) { ... }try{
        YYY.close(); }catch (Exception e) { ... }
  • いくつかのトラブルが、彼は、リソースリークを避けることができました。例外をスロー)(ケースXXX.closeには、コードを変更しない場合、我々は、希望、そしてカテーテル検査中のブロックに入った、YYY.close()が実行されません、YYYこのリソースはまで回復することはありませんそのようなAコードで占められては、複数ある原因のリソースハンドルリークに思われます。しかし、以下の文言を変更することが後に、どのような場合にはXXXとYYY近いうちされることを保証します。

あなたは若いしながら、自分自身に投資することを選択できます。私たちの夢は、できるだけ早く叶うことが
ここに画像を挿入説明
2020年3月4日

公開された20元の記事 ウォン称賛23 ビュー10000 +

おすすめ

転載: blog.csdn.net/weixin_45393094/article/details/104637809