C++のためのAPIデザイン1章(1)

C++のためのAPIデザインを読んで,自分なりにまとめ,
学んだこと・思ったことなどを書いていく.

1日1章が目標だけど,今日は1章の半分だけ.

APIとは】
特定のサービスを他のソフトウェアに提供する入念に定義されたインターフェースである.

APIは仕事の請負人であり,利用者は請負人が持っている専門知識を必要としない.
利用者はやりたいことを決めて複数の下請けに仕事を回すことにより,目的のものを完成させることができればそれで良い.

API設計の特殊性】
APIは開発者向けのインタフェースであり,
公開されたインタフェースはどのような使い方をされるかはわからない.
利用者が多ければ,おそらく自分の想定をはるかに
超えた使われ方をされるのは間違いないだろう.
多様なユースケースを想定し,入念に設計されたAPIは優秀な財産となるが,
お粗末なAPIは延々とバグ修正に追われることとなるので,
設計をしっかりと行わなければならない.

APIは多くのソフトウェアに組み込まれるため,後方互換性が大切となる.
例えば,あるAPIが更新されたことにより,今までそのAPIを使用していた
コードのコンパイルが通らなくなった場合,
そのAPIを利用しているソフトウェア全てのコードに修正が必要となる.
また,挙動が変わることによって多くの混乱を招くのは言うまでもないだろう.

変更に際しては,APIの変更レビューが有効.
その変更が許容範囲内なのか,変更の理由が正当であるかどうか,
レビューが通らないかぎり変更ができないようにするプロセスを
用意することで,APIの品質を保証することができる.

APIの寿命は長く,保守にコストもかかる.
ドキュメントの整備,テストの自動化などによって
それらのコストを下げる努力が必要である.

と言った感じのことが書かれていた(自分が思ったことと,書かれてることを次回からは分けてかけるようになりたい).
この章の内容はまだC++専門って感じではなくて,あらゆる言語についても使えそうな
一般的な"API"についての解説が中心なようだ.

外部院進学について

こんにちは
FUN Advent Calendar2322日目の記事を担当しているみことです.
外部受験についてまとめているサイトはたくさんあるので,少しだけブラッシュアップした簡素な記事にしています(したつもりです).
FUNは院進学率が理系の中では低いんですよね.なので,少しでもFUNで院進学を考えている学生の情報源として,当時外部進学に向けていろいろと試行錯誤したことから何か重要そうなことを抽出して書きたいと思います.
以降,大学院を大学と表記することがありますが,指すものは同じものです.

院進学という決断

当時,就職と院進学の間で悩んだ学生,本学の場合は少なくないのではないでしょうか.残念ながら私はそういった悩みはありませんでした.やりたいことを実現するには時間は足りないし,この先40年以上働くくらいならモラトリアムを延長したいですよね.
基本給もあがりますし,経済的に借金をしてでも行くつもりでした.

外部院進学という決断

いろいろな動機があります.自分の意思,FUNの教員におすすめされたこと,など.
そういえば,学内の進学ガイダンスでは(外部進学を)あまり良い感じには捉えていないような印象を受けましたね.何故でしょうか.

FUNの学生で院進学を目指す・考えている人へ

誰にでもわかる簡単なメリット・デメリットを書いてみたいと思います.

【メリット】

  • モラトリアムが増える
  • 研究する時間が増える

【デメリット】

  • 経済的負担は増える
  • 研究が辛いならあまりおすすめできない

外部・内部問わずこんな感じでしょうか.
後,外部だと副作用的なメリットとして

  • 道外の大学の場合,交通手段が楽になる(ので就活が結構楽になったり,イベントへの参加がしやすくなったり.函館は交通の便が非常に悪いですよね)

逆にデメリットは

  • 内部進学以上に,初期費用が必要となるなど,経済的負担が増える.

などがあげられます.また,内部進学に比べて人間関係が良い意味でも悪い意味でもリセットされてしまうことは,メリット・デメリットの両方とみなせるのではないでしょうか.

外部院進学のやり方

以降,外部院進学を志している人向けに,私の体験談

やったこと

箇条書きにしていますが,一番重要なことは,"要領の良さ・計画性"でしょうか.するべき手続きは多い上,時間の流れは早く,締め切りは厳しいです.更に,複数の大学を受ける場合はスケジュールの都合がつけにくい場合があります.そういった諸々を要領よくこなしながら進学活動?をしていかなくてはなりません.がんばってください.

準備

TOEIC(TOEFL)の受験

大学では英語能力を測るためにTOEICのスコアを利用する場合があります.そのため,(どんな点数でもいいので)TOEICを最低一度は受験しておく必要があります.
TOEICの結果は届くまでに1ヶ月程かかりますので,手遅れになる前に,できれば3年生までの間に2回受けておくことが好ましいでしょう(テストの方式に慣れないと点数を取りにくいため).
尚,学内で受けたTOEIC Bridgeの結果を使用することはできませんので注意が必要です.

教員とコンタクトを取り,アポイントメントを取る

他大学はFUNと違い,システム的に担当予定教員との接触が絶対に必要というわけではありませんが,2年間お世話になる研究室ですので,訪問するべきです.
訪問時期は遅くとも4,5月中(6月以降は試験の公平性のため,院進学希望の学生
との個人面談を禁止している学校もあります),進学を早期から決めている場合は学部3年の間が良いでしょう.
また,こちらから時期を指定する場合は期間を広めに設定します.
教員の方は平素より多忙であることが多く,下手すると1ヶ月程海外に出張していて物理的に面談が困難なこともあります(経験談).

連絡手段はおそらくメールなどになるでしょう.
メールアドレスが公開されていない場合,秘書さんなどのメールアドレスが公開されている場合があります.

研究室訪問をする

アポイントメントを取った時間に伺いましょう.
訪問先の研究内容を調べておくことはもちろん(詳しい説明はしてもらえますが),自身の研究についても(話せる範囲で)話せるようにしておきます.
外部の人から見た自身の研究への客観的な意見を得られるチャンスでもあります,受験に関係なく,こういった機会はどんどん活かしていきましょう.

また,研究室の雰囲気を知る機会ですので,個人的にはこの時に自分に合うか合わないかを感じ取り,この研究室に来たいか来たくないかを見極めるのが良いと思います.

願書を入手する

研究室訪問を行った際はあわせて願書ももらってきましょう.後で取り寄せることが困難だったりします
(特に函館という土地柄上,そうやすやすと再訪問するのも難しい).

研究室の人と連絡先を交換する

これ,言葉にするとすごく打算的ですね.でも大事なので書きます.
もし仲良くなった訪問先の研究室の人がいたら,できれば連絡先を交換しておくと良いです.向こうが来年から研究室に来ることを歓迎している場合,過去問や試験範囲についての情報を教えてくださることもあります.

大学院入試

筆記試験

たぶん,外部生の人と内部生との間にカリキュラム的な有利不利はあります.がんばりましょう.

プログラミング

私が入った大学は入試科目を数学とプログラミングから選択することができました.
その際私はプログラミングを選択しました.その時の経験は少しユニークかもしれないので,少し中身を書いてみます
(重要ではないので読み飛ばしてOK).

【試験方法】

  • 問題を与えられてそれを解くプログラムを作成する.
  • OS,言語などは自由.
  • 自分で持ち込んだノートPCを用いて試験を受ける.
  • ノートPCはネットにさえつながなければ,どのようなソフト・ドキュメントを入れていても良い.また,印刷物を参照することも可.
  • 配布されたUSBメモリに入れて解答(コードとソース)を提出する.
  • 最後に各学生は一人ひとり呼ばれ,面接官の前でプレゼンを行う
    • プレゼンは基本,試験問題の解答(プログラムの挙動)を見せて,あっているかどうか確認するのみ.
    • アルゴリズムとかこだわりとかを聞かれるけど,特段それに点数がついているわけではなさそう.
    • 間違っていても仕様などを説明して途中まであってると,何か向こうは納得してくれたり(点数の付け方はその辺謎) .

私はプログラミングが好きなので結構面白い試験でした.

面接

された質問

  • 志望理由
  • 現在の研究内容
  • 入学後にやりたいこと
  • 試験の手応え
  • 大受けてんの?*1
  • その他試験など

志望理由はどの大学でも聞かれます.ましてや内部から上がるわけではなく外部から
わざわざ選択して受けているわけですから,かなり鋭い質問が来る場合もあります.*2

外部に進学してみて

これは本当に良かったと思います.
みなさん研究に熱心で,議論などを通じて切磋琢磨しあい,いろんな刺激を得られたと思います).

最後に

何だか長々と記事を書いていたら23日も終わりそうです.締め切りについて述べたのだから,この記事の締め切りも守らなくてはなりません.*3 *4というわけで,無理やりですがこの辺で終わりにしたいと思います.以上,FUN Advent Calendarの記事でした.*5

*1:AA略

*2:訪問時にどれだけ詰めて話せているかによって,担当予定教員から助け舟が来たり来なかったり

*3:だんだん面倒くさくなってきた←

*4:22日締め切りだということを記事を投稿してから気づいた

*5:詳しい話や相談に乗って欲しい人は関東に来た時に声をかけてください.ご飯か飲みにでも行きましょう

Windows10でOpen-SSH

MSが公式でOpen-SSHをサポートすると発表されてからしばらくたちますが,なかなか実装されませんでした.
が,とりあえずgithubにあるOpen-SSHはMSが開発している様子であり,少し使ってみました.

クライアントとしてubuntuサーバに接続してみるwith秘密鍵

Windows側をホストにして接続する記事はよく見かけるのですが,意外とクライアント側になる例は見ないのでいろいろ試してみました(まぁ,sshクライアントがサードパーティで存在するので,やる意味はあまりないかもです.power-shell,コマンドプロンプトsshクライアントにできるのはありがたいですね).

ドキュメントを参考にしてやってみましょう.

暗号鍵を用意して(hoge.keyとする)以下のコマンドを叩きます

ssh [username]@[hostname] -i hoge.key

この際,パスフレーズが必要な場合,聞かれるので,パスフレーズの入力を行います.

結果



接続できました.やったね.

apache2のproxy設定

ubuntuサーバのapache2でproxyの設定をしたのでそのメモ.
検索してもapache2の設定ファイルはhttpd.confだ(しかもパスが違う)という
サイトが多いので,その意味でもメモしておきます
(ただし,その情報が間違いである,という意味ではないです.あしからず).

やったこと・覚えておきたいこと

  • apache2の設定ファイルはhttpd.confではなくapache2.conf.パスは/etc/apache2
  • proxyのモジュールがインストールされているかどうかは/usr/lib/apache2/modulesの中を見ればわかる.ファイル名は*.so.これがない場合はインストールしなければならない(あるいはソースからコンパイルしてsoファイルを作る)
  • proxyのモジュールはapache2をインストールする際に自動で入るらしいが,無い,且つインストールを希望の場合はapt-get install apache2-devを行うといいらしい(yumのほうが確かもっとピンポイントにインストールできる,といった記事も見つけた).
  • proxyの設定ファイルは/etc/apache2/mods-enabledに追加すると,apachectl restart後に有効になった.設定ファイルを書き換えた際ももちろん再起動すること
  • 記述は調べればでてくるので割愛する.
LoadModule proxy_module  /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module  /usr/lib/apache2/modules/mod_proxy_http.so
ProxyPass /***(http://***/←/最後の以降の記述を書く) ****(httpから記述)

上記のように書く.

  • 当然だがポートの指定も可能.また,転送後のポートは開放されていなければもちろん使えない

RUNDECKを使ってみる

こんばんは.
最近涼しくなってきましたね.日が沈むのも早くなり,夜が長くなってきました.個人的には活動時間が増えて嬉しい限りです.

さて,本日pyconのライブ放送を見ていて,rundedckというものが紹介されていたので,表題の通り導入してみました.
使用した理由というのはただ単に興味本位というだけなのですが,最近鯖を自宅に構築したので,鯖をいじるのが楽しくて仕方がない,というのもあると思います.

RUNDECKとは

公式サイトを御覧ください.
ジョブスケジューラ,というイメージです.ブラウザから操作できます(便利!!).
私が書いても恐らく情報量0 + 誤情報を発信してしまいそうですし.

使用用途

どうやらcrontabの代わりに使用できるようですので,随時リプレースしていきたいと思います.
まずはDDNSのアップデートを行うスクリプトをcrontabからrundeckに移行してみます.

インストール時のメモ

インストール方法はググればいくらでも出てくるので個人的にやったことや思ったことなど.

  • open-jdk7 をインストール
  • apt-get install rundeckで導入
  • ポートは4440番
  • 設定ファイルの中身を変えたら service rundeckd restart しよう
  • /etc/rundeck/rundeck-config.propertiesにある graiils.serverURLはデフォルトだとlocalhostなので他のマシンからアクセスする時はこの部分をhostnameにするなど変更を加える.これをやっておかないとブラウザで操作する際にいきなりlocalhost.../login.htmlとかに飛ばされてぽしゃる.
  • しかし,ローカルからと外部アクセスとではURLが異なる(外部からではマシン名から引けないし,内部からだと(我が家では)URLで引けない)場合はどうすれば良いのだろう?(エイリアスみたいな設定できないのかな??)

使ってみる

今回はDDNSをアップデートするスクリプトをcrontabから移行してみました.

やったこと

  • ログインして-プロジェクトを作る(名前などを入力するだけ)
  • create jobでジョブを追加する.
  • ジョブ編集画面にてworkflowの下からcommandを選択.wget -q -O /dev/null http://**********@www.mydns.jp/login.htm を記述
  • Schedule to run repeatedly? をYesにし,スケジュールの記載方法をcronに設定してcrontabで使用していた記述をコピペする
  • ジョブをSaveしたらRun Job Nowをクリックして実行してみる

気になったこと(今後調査)

  • 権限操作
  • スケジュールの設定でcrontabの記述が使えるのだけれども,crontabと違いyearまで記述しないといけない.途中叱られてDay of weekは?を記述した.

最後に

Run Job nowは成功してるのでしばらくこれで様子見をしてみたいと思います.
良さそうなら今後は他のジョブもcrontabから随時移行していきたいですね.
タイムアウト設定やリトライ設定,成功失敗のログなども見れますし,とてもパワフルなcrontabとして使えそうで移行するのが楽しみです.

BoostLogでtrivialなログを外部ファイルに出力する際にSeverityを追加する

プログラミング中にリソースの確保,処理の成否判定などを後から確認するためにログを出力したくなったため,Boost.Logを使いはじめることにしました.
とりあえずシンプルなものから触ってみようと思ったためまずはtrivialなlogを吐くことのできるBOOST_LOG_TRIVIALから使い始めることにしました.

使ってみて

サンプルコードをちょろちょろ書いてみてコンソール出力してみる

#include <iostream>
#include <string>


#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/trivial.hpp>


int main()
{
	BOOST_LOG_TRIVIAL( trace ) << "A trace severity message";
	BOOST_LOG_TRIVIAL( debug ) << "A debug severity message";
	BOOST_LOG_TRIVIAL( info ) << "An informational severity message";
	BOOST_LOG_TRIVIAL( warning ) << "A warning severity message";
	BOOST_LOG_TRIVIAL( error ) << "An error severity message";
	BOOST_LOG_TRIVIAL( fatal ) << "A fatal severity message";

	return 0;
}

出力

[2015-06-14 16:00:00.234050] [0x00000092] [trace]   A trace severity message
[2015-06-14 16:00:00.235050] [0x00000092] [debug]   A debug severity message
[2015-06-14 16:00:00.235050] [0x00000092] [info]    An informational severity me
ssage
[2015-06-14 16:00:00.235050] [0x00000092] [warning] A warning severity message
[2015-06-14 16:00:00.235050] [0x00000092] [error]   An error severity message
[2015-06-14 16:00:00.235050] [0x00000092] [fatal]   A fatal severity message

良いですね.とりあえずデフォルトのseverityだけであってもerrorやwarning,fatal,debugなどでフィルタできそうです(ちなみに出力際のフィルタもコード上で書けます).

コンソール出力を使用できない環境

しかし,このコードはコンソール出力が使えることを前提としているため,現在私はWin32ウインドウアプリケーションを作成しており,コンソールをそのまま見ることはできません.なので,後から見返す用にファイル出力してみます.

ファイル出力するコード

ファイル出力するにはboost::log::add_file_logを使用します(boost/log/utility/setup/file.hppがのインクルードが必要).

int main()
{
	boost::log::add_common_attributes();
	boost::log::add_file_log( "test.log" );

	
	BOOST_LOG_TRIVIAL( trace ) << "A trace severity message";
	BOOST_LOG_TRIVIAL( debug ) << "A debug severity message";
	BOOST_LOG_TRIVIAL( info ) << "An informational severity message";
	BOOST_LOG_TRIVIAL( warning ) << "A warning severity message";
	BOOST_LOG_TRIVIAL( error ) << "An error severity message";
	BOOST_LOG_TRIVIAL( fatal ) << "A fatal severity message";

	return 0;
}

このコードによりtest.logというファイルが出力されます.
出力

A trace severity message
A debug severity message
An informational severity message
A warning severity message
An error severity message
A fatal severity message

出力が違う

出力が違いますね.少なくともsevirityは欲しいところです.そこでboost::log::register_simple_formatter_factoryの出番です.これを使うことで出力にSeverityを登録することができます.

ファイルにもSeverityを出力したい

#include <iostream>
#include <string>

#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp> //add_common_attributesに使用.必須ではない
#include <boost/log/trivial.hpp>


int main()
{
	boost::log::register_simple_formatter_factory< boost::log::trivial::severity_level, char >( "Severity" );
	boost::log::add_common_attributes();//TimeStampを使うために追加
	boost::log::add_file_log( "test.log",
		boost::log::keywords::format = "[%TimeStamp%][%Severity%]: %Message%" );

	
	BOOST_LOG_TRIVIAL( trace ) << "A trace severity message";
	BOOST_LOG_TRIVIAL( debug ) << "A debug severity message";
	BOOST_LOG_TRIVIAL( info ) << "An informational severity message";
	BOOST_LOG_TRIVIAL( warning ) << "A warning severity message";
	BOOST_LOG_TRIVIAL( error ) << "An error severity message";
	BOOST_LOG_TRIVIAL( fatal ) << "A fatal severity message";

	return 0;
}

出力

[2015-Jun-14 16:13:30.993423][trace]: A trace severity message
[2015-Jun-14 16:13:30.995423][debug]: A debug severity message
[2015-Jun-14 16:13:30.995423][info]: An informational severity message
[2015-Jun-14 16:13:30.995423][warning]: A warning severity message
[2015-Jun-14 16:13:30.996423][error]: An error severity message
[2015-Jun-14 16:13:30.996423][fatal]: A fatal severity message

Sevirityが追加されました.これでSevirityによるフィルタを後から適当にすることも可能になりますし,目でも追いやすくなります.

補足

上記のコード,出力の中でTimeStampも出力しています.これを使うにはboost/log/utility/setup/common_attributes.hppをインクルードし,boost::log::add_common_attributesを呼びださなければなりません.これを使うことにより,他にもプロセスのIDやスレッドのIDなどを出力できるようになります.適宜formatを編集するとよいでしょう.

以上,BoostLogでtrivialなログにSeverityを追加する方法でした.