技術メモ

神奈川在住のITエンジニアの備忘録。おもにプログラミングやネットワーク技術について、学んだことを自分の中で整理するためにゆるゆると書いています。ちゃんと検証できていない部分もあるのでご参考程度となりますが、誰かのお役に立てれば幸いです。

Windows10環境における「コマンドウィンドウをここで開く」

Windows7環境で良く使っていた、

 

 エクスプローラー ⇒ シフト+右クリック ⇒ コマンドウィンドウをここで開く

 

がWindows10環境ではなくなっているので、ちょっと不便だなあと思って調べたところ、以下の記事を見つけた。

https://www.softantenna.com/wp/tips/windows-10-command-prompt-here/

 

これによると、Windows10ではエクスプローラーのロケーションバーに「cmd」と入力すれば同等のことができる。(試したところできた。)

また、レジストリを編集して、「コマンドウィンドウをここで開く」メニューを復活することもできるらしい。

Javascriptのpromiseパターン

JavaScript の promise パターンについて簡単に書く。promise パターンについては、以下のページに詳しく書かれている。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Using_promises

https://blogs.msdn.microsoft.com/ie_jp/2011/10/04/promise-javascript/

 

このパターンを使うと、Javascriptで非同期処理を書くときにコードがシンプルになる。仕組みをざっくり説明すると、非同期処理を行う関数を発行した際、その関数から受け取った戻り値(promise)に対して、任意のタイミングで then(成功時のコールバック関数, 失敗時のコールバック関数) 関数を実行し、その時点で非同期処理が終わっていればコールバック関数が実行され、終わっていなければそこでwaitするというもの。

 

非同期処理発行時の戻り値をあとでチェックするという方式は、JavaのFutureパターンに似ているなあ、と思った。

https://docs.oracle.com/javase/jp/8/docs/api/java/util/concurrent/Future.html

以下は、参考として、以前JavaのFutureパターンを使って書いたサンプルプログラム。

https://akrad.hatenablog.com/entry/2018/04/25/220836

完全コンストラクタパターン

オブジェクト指向の勉強をしていて、「完全コンストラクタパターン」というものが出てきた。これは、オブジェクト生成時にコンストラクタに必要な情報を全て渡して、後からそのオブジェクトの状態(フィールド変数)を変更しない設計方式。つまり、オブジェクトのもととなるクラスについては、setter は持たず、フィールド変数の定義に final が付くことになる。

このパターンのメリットは、オブジェクト生成時点からオブジェクトの状態が変更されない、つまりイミュータブルなオブジェクトになるので、どこかでそのオブジェクトが変更されている可能性を気にする必要がなくなるし、意図せずオブジェクトの状態が変更されているということも起きなくなる。

オブジェクト生成時点で必要な情報が全て揃う場合に有用だと思う。

JavaのInetAddressクラスのメソッドで名前解決(逆引き)する時は正引きも行われている。

JavaのInetAddressクラスのgetHostName()やgetCanonicalHostName()で、IPアドレスからホスト名への名前解決(逆引き)を実行すると、裏で正引き(ホスト名⇒IPアドレス)も行われるようだ。詳細は以下の通り。

InetAddressクラスのソースを確認すると、getHostName()とgetCanonicalHostName()は、その延長でInetAddress#getHostFromNameService()をコールする。このgetHostFromNameService()の実装は以下になっている。

    private static String getHostFromNameService(InetAddress addr, boolean check) {
        String host = null;
        for (NameService nameService : nameServices) {
            try {
                // first lookup the hostname
                host = nameService.getHostByAddr(addr.getAddress());

                /* check to see if calling code is allowed to know
                 * the hostname for this IP address, ie, connect to the host
                 */
                if (check) {
                    SecurityManager sec = System.getSecurityManager();
                    if (sec != null) {
                        sec.checkConnect(host, -1);
                    }
                }

                // ★★
                /* now get all the IP addresses for this hostname,
                 * and make sure one of them matches the original IP
                 * address. We do this to try and prevent spoofing.
                 */

                InetAddress[] arr = InetAddress.getAllByName0(host, check);
                boolean ok = false;

                if(arr != null) {
                    for(int i = 0; !ok && i < arr.length; i++) {
                        ok = addr.equals(arr[i]);
                    }
                }
                // ★★

                //XXX: if it looks a spoof just return the address?
                if (!ok) {
                    host = addr.getHostAddress();
                    return host;
                }

                break;

            } catch (SecurityException e) {
                host = addr.getHostAddress();
                break;
            } catch (UnknownHostException e) {
                host = addr.getHostAddress();
                // let next provider resolve the hostname
            }
        }

        return host;
    }

(JDK 1.8 のInetAddressクラスのソースから抜粋)


上記の ★★ で囲んだ部分で、(名前解決の結果得た)ホスト名からIPアドレス群を取得し、取得したIPアドレス群の中に問い合わせの元となったIPアドレスが存在するか確認している。この処理は、ソースのコメントにもある通り、DNS spoofing対策のために入れらている。
つまり、Javaにおいて名前解決(逆引き)を行う時は正引きも実施され、逆引き・正引きの結果が不整合だと、名前解決に失敗するということになる。

JavaのURLの名前解決で、DNSの逆引きが発生しています。DNSの逆引きを抑止することはできますか?
という記事もあるし、Javaで名前解決処理を含むアプリケーションを動かす場合、正引きと逆引きの結果が一致する環境にした方がアプリケーションの動きは安定しそうな気がする。(まあ、Javaのアプリケーションに限らず、正引きと逆引きは一致させた方が予想外の挙動に悩まされなくて済みそう。)

J2EEのEntity Manager経由でDBから取得したオブジェクト

J2EEのEntity Manager経由でDBから取得したオブジェクトを、そのオブジェクトがEntity Managerの管理下にある状態の時に変更すると、それがDBに反映されるので注意が必要である。
例えば、

User user = entityManager.find(User.class, id);

として取得した user オブジェクトに対して、

user.setName("Taro");

とすると、この変更はトランザクション終了時などに自動的にDBに反映される。DBに反映されるタイミングについては、以下のページが分かりやすかった。
http://enterprisegeeks.hatenablog.com/entry/2015/01/19/142730
http://itref.fc2web.com/java/jpa/


上述のことを意識しておかないと、メモリ上のオブジェクトの情報を変更しただけのつもりで、実際にはその変更はDBにも反映されて「あれ?DBのデータは変更した覚えがないけど・・・」とかなってしまう。

HP-UXサーバ上のネットワーク・インターフェースの情報を確認する

HP-UXサーバ上で、当該サーバが持つネットワーク・インターフェースの情報を表示するには、

  netstat -in 

を実行する。

他の UNIX OS のように、

  ifconfig -a

を実行しても、ネットワーク・インターフェースの情報は表示されない (というかエラーになる)。

 

【参考】

https://community.hpe.com/t5/Networking/ifconfig-a-not-working-on-HP-UX-why/td-p/5956157#.XA_M1Gj7SUk

C言語を習い始めた頃に躓いたところ

最近、久々にC言語で書かれたプログラムのソース解析を行う機会があった。(普段はJavaperl がメイン。)

少し懐かしくなったので、主題の件についてちょっと書こうと思う。

 

  • static 修飾子の意味が使う場所によって変わる。

関数内で変数に対して使用すれば、関数が終わっても値を保持する変数となる。一方、関数外でグローバル変数に対して使用すれば、そのソースファイルからしか参照できない変数となる。

 

  • extern 修飾子は何者?

実体(定義)は他のソースファイルにあることを意味する。コンパイルの際は、1ファイルずつ処理されるので、他のソースファイルのグローバル変数を何も考えず参照すると、コンパイルエラーとなる。これに対して extern 修飾子を付けると、コンパイラは「他のソースファイルで定義されているから、ここは気にしない」としてエラーにならない。extern 変数はリンク時に解決される。

 

  • 関数内で変数定義する場合、普通に定義してスタック領域に確保すべきか、mallocしてヒープ領域に確保すべきか?

関数内で一時的に使用する変数の場合、スタック領域に確保する。関数が終わった後もしばらく使う場合は、ヒープ領域に確保する。なお、ヒープ領域に確保した場合、必要なくなった時に解放しないとメモリリークになるので要注意。

 

他にもいろいろ躓いたと思うのだが、もう十数年前なのでイマイチ思い出せない(苦笑) ちなみに、定番のはまりポイントと言われる「ポインタ」については、「実体へのメモリアドレスが入っている変数」くらいにシンプルに考えて、あまり躓かなかった。