Mac Book Pro Retina購入メモ

さて、先日Mac Book Pro Retinaを購入したので記録的に自分用メモを。

以前から購入予定でしたが、OSアップデートのタイミングやプライベートのお金の都合やその他のタイミングもあって、やっと購入。
個人的にはLinuxあたりの*nix系が動けばなんでも良いのですが、ノートPCのLinuxは結構めんどくさいし、仕事も多少からんでいますがアプリ開発まで入れるとMac以外の選択肢はないですしね。


購入したのはRetinaSSD 256GB、メモリはフルの16GB。
一番心配していた重さですが会社で使用している旧MBPと比べると大分軽いですね。
さすがに11インチのMBAに比べたら重いですがメモリもあまり乗らない時点でさすがに無理ですし、13インチのMBAと比べても重さに関してはさほど遜色もないですし。


心配していたYosemiteですが、多少使った分では現状問題なさそうです。
というよりも、XCodeのインストール直後の起動がかなり早かったのが驚き。Mavericksだと何故かインストールもインストール直後の起動もがかなり遅くてストレスがひどかったので助かります。
Yosemiteに最適化されているんですかね?
ともかくこれで個人開発がはかどります。


あとRetinaですがグラフィックにはあまりこだわらない方ですが、自分はSteamでゲームをしているのですがこれがかなり綺麗で驚きました。
ということで、そろそろ年末ですし当分ゲームと開発を頑張ろうと思います。
今年は忙しすぎたので来年は時間が取れると嬉しいなぁ。

Cでのエラーハンドリング方法

かなり久しぶりの更新です。
仕事が忙しかったですし、そのあとはイベント続きや体調を崩したりで色々時間がなかったので...。
結局今年はプライベートで進めているプロジェクトをまだリリース出来ておらず、辛いです。


さて、この記事を読んでつらつらどうやっていたかを書こうかと思います。
Cのエラーハンドリングと例外設計、例外処理のメモ - 百日半狂乱


最近はCはさほど触らないのですが、これは難しい問題ですよね。
そももそも昔からCのコードのかなりの部分がエラーハンドリングのコードになるということは言われていて、コード量が増える原因の1つになってますね。

ラッパー関数

まずはラッパー関数を作成する方法です。
私がよく使うのはmalloc系のラッパーのxmallocです。
これは昔からよく使われるテクニックです。

void *xmalloc(size_t size)
{
    void *tmp;

    tmp = malloc(size);
    if (tmp == NULL) {
        fprintf("malloc(3) error");
        exit(1);
    }

    //例えば0クリアもしておく。callocは使いづらいので...
    memset(tmp, 0, size);
    return tmp;
}


状況にもよりますが、mallocに失敗するとexitしたり、さらに成功の場合はmemsetで0クリアをする場合もあります。
組み込みのファームですとexitするのはまずいので、こういうのはやりませんが。そもそも組み込みだとmalloc自体使えないこともありますけどね。


xreallocも作ります。
reallocの場合失敗するとNULLを返しますが、元のポインタ領域はそのままなので初心者だと変数をそのまま使うバグを作ることはよくありますね。
例えばこのように実装します。

void *xrealloc(void *ptr, size_t size)
{
    void *ret;
    ret = realloc(ptr, size);
    if (ret == NULL) {
        // 例えばバグ回避のためにptrを返す
        return ptr;

        //別の方法だと、ptrを開放しておいてNULLを返す
        free(ptr);
        return NULL;
    }
    return ret;
}


いくつか実装は考えられますが、このようにしておくとバグが防ぎやすくなります。
ラッパー関数は単にエラー処理の単純化だけでなく、よくセットで行う処理を同時に行ったりバグを防ぐ事を目的の場合に役に立ちます。

goto

次に悪名高きgotoです。Cの教科書だとよく機能としてはあるけどバグの原因なので本によっては使い方を書かないというのを見たこともあります(どの本かまでは覚えてませんが...)。


例えばこういうのが悪い使い方として紹介されていたりします。

TOP:
//なんか処理

if (x == hoge) {
    goto TOP;
}


言語に関係なく、基本的に処理は上から下へという前提があるので(ループとかもあるけど...)、いくらなんでもこういう方法を取ることはないでしょうが、下手な人が使うとバグの原因になり兼ねないのはわかります。
ただ、エラー処理においては非常に優秀でぜひ覚えるべきテクニックでしょう。

char *hoge() {
    int ret;
    char *tmp;

    tmp = xmalloc(1024);

    //なんか処理
    ret = func0(tmp);
    if (ret < 0) {
      goto ERROR;
    }

    //なんか処理2
    ret = func1(tmp);
    if (ret < 0) {
      goto ERROR;
    }

    //この後も処理は続く...

    //成功時
    return tmp;

ERROR:
  // エラー時
  free(tmp);
  return NULL;
}


エラーの場合、その場でreturnを行う方法もありますが上記のように失敗時にfreeが必要となるとエラー時に毎回freeを書く必要があります。
gotoを使うだけで、エラー処理が1つになり、また関数の出口も1箇所に集まるため処理が非常に楽になりバグが少なくなります。
プログラミングにおいて楽をするのは正義です。下手くそなエンジニアが書くとどんな言語でも無理に頑張って根性で乗り切る人がいますがそれは間違いです。
楽をしてバグを少なくしましょう。そもそも楽をするためにコンピュータを使っているのに、めんどくさくしてバグを増やすなんてもってのほかです。


setjmpなどのテクニックもありますが、これは使いドコロが難しいですね。
今では古くなったサイトですがせめてこのあたりの知識くらいは身につけましょう。
Super Technique 講座〜目次
(コ)の業界のオキテ
Cプログラミング診断室

多分、万年カレンダープログラムはプログラマへの第一歩だった

ここ半年ほど半端ではない忙しさでして...、GWは無い、土日もほぼ出社な状態で、久しぶりの投稿です。
管理が出来ず、管理について勉強しようとしない管理者は本当になんとかして欲しい。


いろんなプログラミング言語で1582年10月5日を扱ってみる| mwSoft を見てふと懐かしくなったので、懐かしみつつ書いてみます。


そもそも万年カレンダープログラムって自分の若い時には入門者が初めてある程度まともに調べて仕様というかアルゴリズムを考えながら作るプログラムだったりしました。
とは言っても基本的には未来に向けて万年カレンダーなのですが。


はじめは単純で年、月、日が表示出来れば良くてあと頑張れば曜日の表示程度です。
でもこれのほほんと生きてきた人間には結構難しくて、うるう年のルールをきちんと知らなくて4で割れたらうるう年と考えて、授業で出したらダメ出しを食らうというのが定番でした。
そして、うるう年を調べて、へーっとなって修正してOKもらって授業は先に進む程度なんですけど、多少でもプログラムを頑張る人は過去もチェックしだして、西暦1年をcalコマンドでチェックしてズレを発見して絶望を覚えるわけですね。


さてこのズレを調べると、1582年に行き当たってあーと思い出すのです。
歴史好きなのでこれ結構すぐにはっとして納得するのですが、こうなると色々頭をよぎるのです。
ロジャー・ベーコンだったり、日本でも明治に導入して混乱があったなぁとか、和暦対応も頑張りたいなぁと思っていた矢先でそういや和暦ってどうなのとか、それこそ無限に。


ということでいくつかややこしい話を上げていこうかと。


まず、明治の件。
日本におけるグレゴリオ暦導入に日本にグレゴリオ暦が入ってきた経緯があります。西暦と同じく一部日付の欠落が発生して対応が必要になります。当時ふと思い出して調べてふざけるなと思った記憶があります。


和暦のめんどくささ。
元号一覧 (日本) - Wikipediaを見ると分かるのですが、元号が無い時代があったり、南北朝時代には同じ年なのに年号が複数あったり。
多分真面目に作るとなると、和暦のデータをテーブルとかDBに保存しておいて、それで変換するとかになるのでしょうね。やってられない。


そもそもユリウス暦の前は?
さて、和暦を諦めたとして、グレゴリオ暦の前はユリウス暦なのですが、その前ってどうなっているかとかを考えるとこれまたややこしいのです。
ユリウス暦 - Wikipedia
ローマ暦、エジプト暦とか色々名前が出てくる。そしてさらにはユリウス暦も現在一部では使われているとか、さらにややこしい話が。
そういえば今でも旧暦とか時々使いますよね。


そして、グレゴリオ暦のみの世界に。
結局、calコマンドはグレゴリオ暦を全体を通して使っていてそれに合わすのが結局無難なわけです。
仮に頑張るにしても、DBを使わざるを得なくて、いろんなプログラミング言語で1582年10月5日を扱ってみる| mwSoft にもあるけどDB側の影響も結構大きい。


頑張るんであれば、過去はcalコマンドに準拠で、曜日とか六曜とかそういう方向が多分ベスト。
と多分誰もが通る道を通るわけです。


で、今思うとカレンダープログラムを初心者の頃に作るのに良いことってこんな所でしょうか。

  • アルゴリズムと現実の結びつきがリアルに感じられる
  • プログラミングって大きく言えば工学の1分野なのですが、工学は実社会で役立つ事が前提です。でも実社会との大きな隔たりがやっぱりあって、そこを肌で感じれる初めての機会だと思うわけです。もうちょっと言えば現実と以下に折り合いをつけるかを学ぶ機会でした
  • それでも改良を頑張れる余地があって、頑張れるチャンスです。そしてこれがプログラミングの面白さでもあり、コードを綺麗に保つなどの大変さを知る機会でした。


現実的なプログラミングの大変さや何が必要かとかを知る良い機会でした。

Mac Book Proのスリープ時の運用方法

さて、最近Mac Book Proが壊れてしまいました。
運良く修理は終わったのですが表に出てきた症状の1つにスリープ時からの復帰が異常に遅いということ。
いつも作業途中の状態のまま蓋を占めてスリープさせるのですが、修理が終わった後もこの復帰が異常に遅い。

スリープ時に注意すること

色々試行錯誤していたのですがどうもSkypeとかWebブラウザとかを起動したままにするのが問題な気がしてきました。
どうも動作を見ていると、アプリケーションはスリープから復帰すると復帰処理を色々行っているように見えます。
特にネットワークを使うアプリケーションは色々重くなりがちな印象を受けます。
また、メモリを多く使いがちなアプリケーションも復帰処理が重いようです。
アプリケーションが1,2つ程度ならこれでも許せますが、ある程度多くのアプリケーションを起動したままスリープからの復帰を行うと、この復帰処理が重くなる原因のようです。


結局ターミナル以外のアプリケーションはターミナル以外は全て終了させてスリープさせるようにした所、復帰が快適になりました。
私はエンジニアですので最悪ターミナルさえ元のままであれば良いのです。screen使いなので最悪ターミナルが落ちても問題はないのですがw


ただこれだけだと復帰が軽くなっただけで結局元の作業状態に戻すのは結局重いのです。
例えば、Webブラウザの復帰処理。FirefoxGoogle Chromeあたりをメインに使っていますが、タブを復帰してくれるのは当たり前。
でもタブを多く開いているとタブを全部読み込むのが重い。FirefoxにはBarTabという使っていないタブを裏で読み込ませないというaddonがあった。
今はデフォルトでこの機能が備わっています。
で、Chromeにはこの機能がないようなので、Chrome版BartabのFooTabを入れています。これでWebブラウザの起動が重いという問題は解決。

重いプロセスの停止

次に、Macのデフォルトで裏で動くプロセスです。
大体ハードウェア、特にHDDにアクセスしているっぽいです。

mdworker

私はVimmerなのですが、Vimを使っている程度で急に重くなる現象があります。
Vim程度で重くなるはずがなく(よほど重いファイルを開いているとかでも無い限りですが...)、調た結果、原因はVimではなくSpotlightの検索用インデックスを作るプロセスが重いようです。


Spotlightなんて自分は使いませんので(find,grepで十分です)、以下のコマンドでまず停止します。

$ sudo mdutil -i off /


さらにこれをしても再起動を行うと起動するようです。ですので起動そのものを停止してやります。

$ sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.index.plist
$ sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist
$ sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.scan.plist
$ sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.spindump.plist

systemstats

どうやら、システムの状況を知るコマンドらしいのですが、使っていないのにいつの間にか起動していてすごく重い。
今から考えると、HDDとか一部のハードウェアが壊れたために暴走していたのかも知れませんが、とにかく重い。


まずはプロセスをkillします。

$ sudo pkill -kill systemstats


そして起動も抑止。

$ sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.systemstats.analysis.plist
$ sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.systemstats.daily.plist
$ sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.systemstatsd.plist

Linuxでもlocateの為に動くプロセスとかありますが、ここまで酷くはなりません。何より夜中に起動してさほど長くは動きませんし、ましてや暴走なんか見たことないです。
Macは正真正銘のUNIXですが、どうもLinuxに比べて動きが良く分からない所がありますね。

わたしの個人的なパスワード管理方法

最良のパスワード管理ソフトを求めて - WSJ.com を読んで。
こいうったアプリを使って管理するのは悪いとは言わないけど、アプリが公開終了したりすると目が当てられない。
あと、アプリが実際何をしているかもよくわからないし、古いエンジニアとしては中身も知っておきたい。特にこういう大事なデータを管理するものだと。


いまだとこういうアプリもありだけど、現実問題として一昔前にはこんなのないから結構考えた。
SQLiteのようなDBで管理するとかも考えたけどUnixエンジニアとしてはテキストファイルも怖い。いやかなり昔はテキストファイルで管理もしていたんですが、時間が経つにつれ怖くなってくる。
セキュリティは別にしてもテキストだと昔は良いフォーマットがなく、適当に書いていって後で分からなくなる。

結局グダグダになるのがいつものオチだったのですが、結局落ち着いた方法は

  • テキストファイルで書いていく
  • フォーマットはcsvjsonとかもありますがオーバスペックですし、csvなら1行1アカウントで分かりやすい
  • GPGで暗号化して管理。暗号前ファイルは当然削除しておく
  • パスワードはpwgenコマンドで作成

変にセキュリティを自前で考えたり、高度な事を考えても切りがないのでこのあたりで落ち着いています。
これならば、暗号化したパスワードファイルは持ち運べますので便利です。
スターパスワードがバレれば終わりですが、それはどのアプリを使っても同じなので考えても仕方ないです。

隙もありますが(暗号化解除したファイル見られたら終わりとか)、ほどほどの労力でそれなりのセキュリティが保てておすすめです。

クラウドソーシングは使わなくても面白い

久しぶりの記事です。
仕事が半端無く忙しい。そもそもあの部分がああだからとか色々毒を溜め込んでいます。
世の中の皆さんはGW楽しんでください。


さて話題のクラウドソーシングサイト、個人的には登録はしていますが、特に使ってません。
使っていない理由はいくつかあります。
普通に会社に雇われの身だということ、副業している暇がない、話題になったように内容が結構アレなこと。


多少なりとも仕事を経験して地雷を踏んだりすると(地雷しか無い気もするけど...)、色々勘というのが身につきます。
自分は特にこのあたりの勘を説明できる力が無いのですが、でもなんとなく分かる。
そして、そんな目で見ると結構アレなのは分かる。というか普通に考えてリアルを優先するはずなので訳あり案件が圧倒的に多いのが想像できます。
まあ、中にはプログラムを教えてくださいとか、作りたいものがあるけど経験ないし知り合いもいないとか、人が集まらなそうな組み込み系で真面目に募集していたり(そう見えるだけですが)、裏事情が面白そうな案件もあるけどね。


でも時間のある時は見ていて面白い。
何が面白いというと、地雷だからこそそこに一般的に解決できていないけど要望がある案件があるわけです。
ですので、市場の本当の要望(妄想かもですが)だったり、困っている特定の業界だったりがわかります。
自分で会社作ったり、フリーランスの人だったり、プライベートプロジェクトを作りたい的な人達は見ておいて損は無いと、自分は勝手に思っている。
ここからアイディアのきっかけになったりしないかなぁとかも思っています。
ですので、自分はうまく行けばこれだけで生きていけないかなぁという妄想を抱きつつ見ているわけです。
さらにはある程度知識があると、裏の事情も見えてきそうでそういうのも楽しい。多少不謹慎とか言われるかもですがw


特に落ちはありませんがこういう楽しみ方もあるよというお話でした。

今の時代に新人エンジニアは何を勉強すればいいのか?

特にこれと言った正解はないのですが、つらつら書いてみましょう。


弊社にも新人が入ってきたのですが、自分の時を思うと周辺技術がすごい違う。
自分がいる業界が自分の新人の頃と違うというのも原因ですが、大学で勉強するメインの言語ですら自分の時代はC、今はRubyなんて大学もあるようで大分違います。


そんな新人にCや下回りのマニアックな部分を勉強しろ、自分達年寄りがたどった道を歩け、とはとても言えない。
けれどImmutable InfrastructurとかDockerとかばかり触たり知っていても、いざという時は下側の知識が必要になってきます。
こんな知識多分99%以上は役に立たないけど、やっぱり必要だし知っていれば知らないよりよほどいい。


パターン1:それでもやっぱり勉強しろ
業界によっては勉強せざるを得ないという場合はあります。
それ以外でも勉強できるなら、したほうがよいです。やっぱりエンジニアの基礎知識ですし、かならず土台になって今後のエンジニア人生においてとても役に立つはず。
でも、めっちゃ大変だよ。ほとんど使う機会もないし。応用がすごく出来るのがいいところ。


パターン2:軽く抑えておく
情報処理だとかLinuxの教科書的な本を手に入れて軽く抑えておく。真面目に勉強しなくてもいいけど単語だけも頭の片隅にあれば何とかなりそう。
きちんと分かってなくても必要になればググればいいしね。遅延処理大事だよね。
あ、資格自体は無駄なので当然無視ですよ。
多分これのあたりが現実的かなぁ。Wikipedia眺めるだけでも面白いですよ。


パターン3:無視
多分これが現実で取られる対策だと思います。でも知識が穴だらけになるので、応用効かない気がする。


結局、このあたり楽しみながら要領よく乗り切るかどうかで淘汰されるかどうかに影響与えそうだなぁと感じます。
でも自然淘汰される人は少なくなってほしいなぁと思う