kazurof weblog

技術ネタのメモなどを並べます

引き継ぎ作業の小ネタ

前置き

この4ヶ月半ほど、いわゆる情報システム部門に居ました。 そして人が交代することになり、仕事の引き継ぎをしました。 要は現在の仕事を次の人に説明するわけです。 それで、効率的な説明の方法が思いついたような気がしたのでここで晒します。

想定読者

  • 仕事の引き継ぎをする必要がある人。
    • 特にいわゆる情シスの人。
  • 仕事の全体像を把握する枠組みに興味がある人。

仕事の分類とその引継

ここでは、以下の様に仕事をグループ分けしたいと思います。

f:id:kazurof:20150528001648p:plain

言いたいことは大体この図で言えている気もしますが、個別の説明を続けます。

縦軸に作業が決まっているかいないか、横軸に周期的に発生するかしないかで分類します。 それぞれのエリアに名前を付けます。内容をイメージできるような名前がいいですね。

  • 定型・定期
    • 「刺身たんぽぽ」
  • 非定型・定期
    • 「年中行事」
  • 定型・臨時
    • 「早さ命」
  • 非定型・臨時
    • 「変化ヲ抱擁セヨ」
    • このサブエリアとして、「一期一会」「今そこにあるお仕事」。

「刺身たんぽぽ」エリア

一定の周期で、一定の作業を行う仕事です。 スケジューリングや作業見積もりが立てやすい比較的簡単な作業のエリアです。 環境が自動化を許せば人間がやらなくても良くなるかもしれません。 慣れてくれば退屈してしまうでしょう。長く続けても成長は望めない仕事のエリアです。

具体的には以下のとおりです。

  • システムデータのバックアップ
  • ログデータの処理
  • 月次、週次の事務手続き
  • 利用者部門にやってもらう定期的作業のリマインドのアナウンス

引き継ぎ方

単純にやり方を説明すればよいです。特に難しいことは無いでしょう。

「年中行事」エリア

いつやるべきかわかっているが、内容はその都度検討するエリアです。 スケジュールは立てやすいですが、予め作業内容や量を見積もるのはしにくいです。

情報システム部門というのは、管理部門に属することが多いと思いますが、 管理部門での作業(行事)の手伝いなどがこのエリアに入ります。

具体的には、週次会議、月例会議の手伝い。新人研修のテキスト執筆と講師。 上場企業なら株主総会、決算説明会など。 場合によっては懇親会とかBBQとかボウリング大会とか社内イベントの手伝いも入るかもしれません。

また、24/365な自社サービスをやっている場合は、システム保守作業を 定期的にやっているかもしれません。それもこのエリアに入ります。 いつやるかは予めスケジュールされますが、何をやるかはその都度計画する作業です。

引き継ぎ方

大スケジュール表を示して、何時どんな行事があるのか示せればよいです。 仕事内容についてはその都度検討するでしょう。あなたがその検討会議に入る必要はありません。 引継期間中にその行事があるのならば、一緒にやってもよいでしょう。

「早さ命」エリア

何をするかは既に定型化されているが、いつすべきかは予想がつかない作業のエリアです。 作業量はわかりますが、いつ必要が発生するかはわかりません。 「速さ」ではありません。「早さ」です。スピードが速いのではなく納期が早いことが価値です。

具体例についてです。情報システム部門は何らかの社内システムを管理していると思います。 そのユーザ登録管理がこのエリアに該当します。 人事異動・組織変更から発生することも多いでしょう。

また、利用者部門のPC管理もこのエリアに入るでしょう。 入社したので購入することや、退社したのでとりあえず情シスがプールしておいて必要時に利用してもらう、といった管理が考えられます。

引き継ぎ方

このエリアについてはも、それぞれ手順を教えれば良いです。 現在あなたが対応途中のものはあなたが実行し、新たに作業依頼が来るものについては次の人にやらせればよいです。

「変化ヲ抱擁セヨ」エリア

いつ何が来るかわからない作業のエリアです。 急に発生する課題・問題に対して、すぐその場で状況理解と優先度と重要度の判断をし、 必要ならば実行計画策定と実行が求められます。

事前に発生を想定して対応を考えることは却ってやらないほうが良い作業のエリアです。 そもそもできませんから。「こんな事もあろうかと」なんていうのは実際上は歩留まりが悪いものです。

具体的には以下の様な作業が入ります。

  • 即対応必要なセキュリティ対策作業。
  • PC利用トラブルのサポート。
    • ネットワークとかプリンタとか
  • 社内システム関連作業
    • トラブル対応
    • 設定の調査や変更依頼対応
    • 機能追加/拡張の依頼。機能作り込み依頼の対応。
  • 外部の急な意思決定変更。
  • 誰かが握りこんでいた納期間近の作業の対応。

また、以下の様な作業も入ります。

  • 現在あなたが進めている作業。
    • 作業の全容は発生時期含めて不明なはずです。
    • 「今ここにある作業」エリアとします。
  • 今後発生することは無いと考えられるような作業。
    • 一度しか起こらない作業です。定型とは言い難いです。
    • 「一期一会」エリアとします。

引き継ぎについて

まずは以下の3点です。

  • 過去の事例を軽く紹介。
  • 管理している社内システムついて必要な範囲で伝達。
  • 今後、どのような作業が発生しそうか軽く紹介。

内容の詳細について詳しく説明する必要は必ずしもありません。 また似たような作業は来るかもしれませんが、同じような作業が来るかはわからないのです。

「一期一会」エリアについては、作業の名前だけ紹介し、 事例として文書や資料や手順を残しておけば十分です。 発生しないと思ったけど実際は発生した時に役立てれば良いのです。

「今そこにあるお仕事」エリアは状況を見て考えなくてはなりません。 現在進行している作業は状況の変化もろとも引継ぐ必要があるのでその分大変になります。 状況が込み入っていて、あと少し完了させられるものはあえて引き継がずにあなたが完了させるのも手です。引き継ぐならば、進めながら引き継ぐ事になります。作業をある程度進めておいて、細かい状況を伝えなくても良いようにしておくと引継が楽になります。

まとめ

作業を4つのエリアに分けて、それぞれどうするかを述べました。 定型的作業をまず伝えて、状況を見ながら非定型作業を進めるのがよいでしょう。 何かのお役に立てばよいかと。

おまけの考察

いわゆる5W1Hのうち、What とWhen を軸としてまとめるかたちになりました。 そういう意味では

  • Who
    • 誰がやるか。平社員か、幹部社員か。
  • Why
    • どんな理由か。外部的な理由か、内部的な理由か。

なども軸として考えても良いかもしれません。一人情シスの場合、Who軸は無意味かもですが。 Where については、現場かリモートかで分けても良いかもしれません。

おまけの感想

これを考えている間、いわゆるアジャイル開発のことも考えていました。 リリースとフィードバックの速度を上げて、 状況や意思決定の変化に追随しながらシステムを開発するということで、 なかなかやはり高度で難しいのだなと思った次第です。

POH lite でリポビタンD100ml×50本のセットが当選してしまいました。

f:id:kazurof:20140912222332j:plain

タイトルの通りで他の参加された方には全く申し訳ないのですが、POH lite でリポビタンD100ml×50本のセットが当選してしまいました。おおおおおお。*1

f:id:kazurof:20140913215845j:plain

ステッカーもついてきました。むおおおおおお。

天才火消しエンジニア霧島「もしPMおじさんが丸投げを覚えたら」|paizaオンラインハッカソンLite

で、このまま何もしないのもどうかと思われたので、もう一つネタを振ってみたいと思います。もっと変わった面白い解き方はないものかと日頃考えているのであります。


POH lite ではいろいろな言語が使えます。Beta版も含めて20言語あってなかなかすごい感じですね。 私としてはここにない新しい言語で解いてみようと考えました。AWKです。

AWK - Wikipedia

言語には流行り廃りがありますのでご存知ない方もいらっしゃるかと思います。簡単に説明すると、「比較的言語仕様の小さなプログラミング言語の中でも、速攻性、柔軟性、機能性において最右翼に属する逸品」です。*2

プログラム

sample code for https://paiza.jp/poh/kirishima wit ...

実行結果

kazurofさんの採点結果[100点] 完璧ぃぃ!|paizaオンラインハッカソンLite

実行時間は 0.08 秒から3.45 秒 の範囲です。Test case 7 以外ではJavaScript over Java(以前やったPOH lite を JavaScript (Nashone)でやってみた。 - kazurof weblog)よりも速いのが興味深いですね。合計時間ではAWKの方が速いということになります。

やってみた感想など

AWKはその標準入力の扱いに特徴がありますので、それを活かす方向にしてみました。具体的には以前のようにソースコード中に値を展開するのではなく、Javaが受け取った標準入力の内容をそのままAWKに渡す形です。言語ごとに特徴がありますのでそれを活かせたかなと。

あと、配列の扱いが微妙に癖があるので、(連想配列だったり長さを取れなかったり)そこもちょこちょこと修正しました。

paizaでコードを書いた人は今までにたくさんいると思いますが、AWKで書いた人は私が初めて(多分)ではないのかと一人自己満足に浸っております。えっへん。

同時に、AWKで書くとかこんな馬鹿馬鹿しいことをする人は私が最後なんじゃないかなあと思っています。寂しくなんてありません。ええちっともありませんとも。

でもこれ、本当はやばいのではないかとも思います。実行環境上のawkとか/bin/sh とか動いちゃうわけですよ。私は uname -a とか ls / とかやって怖くなってきたのでもうやめておきました。ファイルシステムを見に行ったら中を開けるかもしれないし、もしかしたら霧島京子壁紙の.aiファイルもあるかもしれない。本採用の候補となっていたファイルとか、絵師さんの習作で作ったあんな画像やこんな画像もあるかもしれない。

いやいやいやいや。やばいやばいやばい。

で、一応念のため運営事務局さんに確認したら、「ブログ投稿は問題ないが、今後は動作保証しかねる。」ということでした。今は動くかもしれませんが、そのうち動かなくなるかもしれません。

というわけで、今リポビタンDを美味しく頂いているところです。さすがに今後も当選するとは思えませんがまたチャンスがあったら参加してみようと思います。 私からは以上です。

f:id:kazurof:20140913233941j:plain

*1:箱が少し開いているのはうちの子(4歳女)が中を確認したいとわがままを言ったから私の帰宅を待たずに開けたんだそうです。ちなみに配達時は嫁の母もいたらしく、嫁「もらってけば?」嫁母「いーよいーよいーよ」という会話があったそうです。おとうさんが頑張って懸賞を当ててもところがどっこいこのような脅威に晒されるのが現実です・・!これが現実・・!

*2:ここから引用 

AWKを256倍使うための本 (Ascii 256倍)

AWKを256倍使うための本 (Ascii 256倍)

 

読書メモ「パブリックスピーカーの告白」

「パブリックスピーカーの告白」を読みました。 プレゼン発表をする人へのノウハウやガイドを提供する本です。 簡単に言うと小ネタの山といった印象です。

以下、超ざっくりとした概要を並べます。

1章

発表での細かいミスは気にしない。聴衆は細かいところまで気にしない。

2章

緊張を下げるためのいろんなアイデア。 人前で話すの怖いとか緊張するっていうのは自然なこと。

3章

私はそんなにたくさんお金稼いでいません。リスクもあります。発表準備もあります。だからいぢめないで。

4章

会場について。「会場をエネルギーで満たしたい。」 たとえ無駄でも聴衆のためのアクションは試みるだけでも有効。 聴衆にとって言ってほしいことを言う。聴衆が問題にすることを話す。

発表者と聴衆の関係。できるならよくしたい。限界もあるけれど。

5章

ちゃんと考えてスライドを準備しましょう。 「マイクを食べた」とは話す内容が発表者にとっても明確で無いと聴衆が気がつくこと。*1

良い準備をするために必要なこといくつか。 聴衆が求めているのは洞察。タイトルの付け方。内容練り上げ方。(こうすればマイクを食わずに住む)

アウトラインを押さえて論点を明確にしましょう。

6章

聴衆の注意を引くことについて。人間の注意は長く続かない。 聴衆を前にした時にするべきことと気をつけること。

7章

テレビでしゃべるということ。どんな偉い人でも小さな歯車扱い。 私達はいつも演技している。誰と会っていてもそれなりに演技している。プレゼンをすることが特別ではない。

テレビの場合聴衆は眼前に居ない。そこをなんとかするのは能力。なんとかするのはとても大変。めちゃくちゃ大変。プロンプターで自然にしゃべるのもまた大変。

8章

フィードバックについて。 有益なフィードバックはなかなかもらえない。ヘボいプレゼンでも儀礼的にやり過ごされる。 教える力を上げるために聴衆を楽しませるということ。本題から外れたとしても。

受講アンケートの良くないところと本当のフィードバックをもらうコツ。 聴衆の興味があることを言わなくてはならない。

フィードバックとして自分のプレゼンを撮影して見ること*2

9章

教えることについて。教えることはほとんど不可能。そもそも難しい。 1対1なら有効。3個の要点。

  1. 活発で面白いものとする。
  2. 生徒の興味を掻き立てる洞察を示す。
  3. 生徒の1と2の反応に対応する。

つまり、 1. 手を動かしてもらう。演習  2. 興味を持たせる。 3. フィードバックをもらって学ぶ。その場ででも改善する。

10章

段落毎小見出し付きの小ネタ集。散文のような形で多種多様なネタを流していく。まとまりや掴みどころはなさげ。

バックステージノート

実際的な小ネタを多数並べられている。話が具体的なのでとっつきやすい。

感想など

私のようなたまにプレゼンをやるようなエンジニアには内容は充実しすぎかも知れません。予備知識として持つには十分すぎるほどです。 *3

プレゼン発表を頻繁にする人にとっては有益で参考になる情報がたくさんあります。 プレゼンすることが専門・仕事みたいな人には良いと思います。ただ、余計な無駄話もそれなりに入っているのでその分は読みにくいかもしれません。 *4

私個人的にはプレゼンは演って面白いものと捉えています。観るものではなく演るものです。ネタと発表機会があったらどんどん演りたい。 プレゼンのプロであってもなくてもそういう人には副読本的におすすめできると思います。


パブリックスピーカーの告白 ―効果的な講演、プレゼンテーション、講義への心構えと話し方

パブリックスピーカーの告白 ―効果的な講演、プレゼンテーション、講義への心構えと話し方

*1:でいいと思う。多分

*2:これは福原も自分で思いついて実践してたぞ。えっへん。

*3:直接的な興味が続かなくて、読むのに半年ぐらいかかりました。積ん読をぎりぎり捌くことができたというか。(苦笑)

*4:おそらく著者は口頭での発表のつもりで本を書いてしまっているのかもしれません。著者の本業はおそらくしゃべることです。

POH lite を JavaScript (Nashone)でやってみた。

天才火消しエンジニア霧島「もしPMおじさんが丸投げを覚えたら」|paizaオンラインハッカソンLite を、 JavaScript over Java でやってみました。 Nashone と言ったほうが通りが良いかもしれません。

プログラム

sample code for https://paiza.jp/poh/kirishima

実行結果

kazurofさんの採点結果[100点] 完璧ぃぃ!|paizaオンラインハッカソンLite

実行時間は 1.57 秒から3.19 秒 の範囲です。また一段と遅くなりました。 そんなものといえばそんなものでしょうか。

感想というか手応え感というか

特に難しいことはなく、ScriptEngine 云々を使ってやってみました。 配列の扱いがJavaと微妙に異なるのでそこだけ直してできあがり。

前回までで、Java8 のStreamとか、JavaScript over Javaでやってみましたが、 もっと変わった解き方はないかなあ、とおもっています。

POH lite をfor文無しでやってみた。

天才火消しエンジニア霧島「もしPMおじさんが丸投げを覚えたら」|paizaオンラインハッカソンLite について、for文の代わりにStreamを使ってやってみました。 前々回の焼き直しです。 POH lite 天才火消しエンジニア霧島をやってみた。 - kazurof weblog

プログラム

sample code for https://paiza.jp/poh/kirishima

実行結果

kazurofさんの採点結果[100点] 完璧ぃぃ!|paizaオンラインハッカソンLite

実行時間は 0.22 秒から0.36 秒の範囲です。前々回より遅くなっています。 stream導入だけでなく、クラスを増やしたのも原因かもしれません。

stream導入について簡単なコメント

一番簡単なのは、75行目かと。0から配列の長さまで NOT_ASSIGNED を代入するだけです。

35行目は以前はtry節のループを内の処理でした。company.membersの総和を取る処理なのでこれだけを抜出してstreamで処理しました。

31行目は元々の IntStream を、List へと変換するような処理です。mapToObj を使います。(このメソッドを見つけ出すのに時間がかかった。とほほ。) 変数 i が、未使用であると、NetBeansに警告出されているのですが、解消の仕方がわかりません。(とほほ2)これは追々調べるとして。

40行目から50行目は、mapとforEachとありますが、一緒にしてしまっても良いのでは?とも思っています。(この修正はNetBeansが提示してきた。)小さい処理に分割するのが良いことなのかもしれません。

この中の41行目でもstreamを使っています。IntStream を降順にするため、map(i -> numOfMemberIfUseAll - i + company.members - 1) などと小細工しています。標準機能にないかな。

105行目はnumOfMember以降での -1 以外の最小値を取る処理です。修正前はfor文の外のローカル変数に代入する処理でしたが、min()メソッドで streamから直接算出するようになりました。以前よりも処理が簡素になったと思います。

まとめ

for文をstreamに入れ替えて、全体的にソースが簡素になったような気がします。配列を処理するケースが多かったので、 IntStream s = IntStream.range(start , end); の、パラメータの与え方がキモだった感じです。 stream は慣れというか初期学習コストが必要なのは否めませんが、できるようになったらコードが綺麗に書けるかもです。普及が進めば否応なしに読み書きせざるを得なくなるでしょう。 速度については、paizaの範囲では期待できないかも知れません。

(ネタ)火村氏についての考察

https://paiza.jp/poh/kirishima

ここの、火村氏のコードがヘボいのは言うまでもないと思います。

が、彼が書いたJavaのコードでは java.io.BufferedReaderではなく、java.util.Scannerが使われててこれは意外とすごい?ような気がしました。 

火村氏は42歳。java.util.ScannerはJDK5で登場してて、リリース日は 2004年9月30日 概ね10年前。 彼は32歳。確か、Java 1.4 とJDK5の差は大きく、実環境投入がスムーズにやれたかとは限らないと思います。コンテナが対応してないとか。

それでも java.io.BufferedReader よりも java.util.Scannerを使うほうが書きやすいとわかってるからこそ書いたはずで、その点は火村氏は(少なくともその頃は)ちゃんとキャッチアップしてたんだなと思われるわけです。

他にも、いろいろな言語でサンプルコードを書けていて(ヘボいですが)、ゼネラリストっぽいなーという感じです。COBOL VB Objective-Cを知らないのは、オンラインハッカソンとしての都合でしょうね。きっと。

色々書きましたが、値出力のサンプルコードhttp://paiza.jp/guide/samplecode よりも新しいAPIで、火村氏にコードを書かせた運営さんの意図が気になります。何かの演出上の意図があった?特に何もなくて僕が勝手に深読みしすぎているだけ?

そういうのがもうちょっと整理してあったらもっと楽しく遊べたかもしれません。 私からは以上です。

POH lite 天才火消しエンジニア霧島をやってみた。

https://paiza.jp/poh/kirishima をやってみました。

自分の理解のため、解法の説明をしながらコードを晒します。

アルゴリズム概要

簡単に言えば、ナップサック問題の変形を動的計画法で解くアルゴリズムです。

処理を進めるにあたり、下請け会社の組み合わせで取りうる合計人数とその場合の合計コストを算出します。 その情報を costByNumOfMember なる配列(ソース10行目)に保存します。 配列添字が合計人数です。値がコストです。

そして、それぞれの下請け会社毎にこの配列の情報を更新します。 つまり、ある下請け会社についてこれを使ったほうが安くなるような組み合わせ(=合計人数)があるならば その下請け会社で更新します。

すべての下請け会社をチェックした後、必要な人数以上の範囲でコストの最小値を求めます。 それが本問の回答です。

プログラム

gist4865fa5ab62c8aae09af

プログラムの解説

30行目から38行目は入力データの読み込みです。 同時に全ての会社を選択した場合の人数も足し上げて保存しています。

40行目から43行目は costByNumOfMember の生成と初期化です。 合計人数は1始まりなので、この配列もそのように使うべく長さを +1 しています。 添字0番目は使っていません。

45行目は、会社のリストでループを回します。 この内部は会社ごとの処理です。

46行目のループは、costByNumOfMemberについて特定した会社を考慮する時の処理です。 配列costByNumOfMemberのそれぞれの要素(=取りうる人数とコスト)について、 特定した会社(変数名 company)を含めた組み合わせのほうがコストが安い場合これを更新します。

ループについて、開始は「全ての会社を選択した場合の人数」です。 終了は「特定した会社の人数」です。大きい方から小さい方へ処理している理由は後述します。 ループ変数は i です。

このループ内部では、costByNumOfMember[i] を特定した会社の情報で更新できるならしたいです。 どうやってやりましょうか?どんな条件で?どんな値で?

実は、costByNumOfMember[i]を更新してよいかの判定には、 costByNumOfMember[i - company.members]を検査することが必要になります。

もしも、costByNumOfMember[i - company.members]に何らかの値が設定されていたら、 そのような下請け会社の組み合わせが存在することになります。 この値にcompanyを加味して新たな組み合わせを検討してみましょう。

0 < costByNumOfMember[i - company.members] であるならば、以前のループの処理で 組み合わせとコストが確定していた事になります。 この値と company.cost の和は costByNumOfMember[i]の候補になります。

未設定ならば新規に値を設定するべきです、 未設定でなくても現在のcostByNumOfMember[i]よりも少ないならばやはり更新するべきです。 新たな組み合わせがあり得てしかも安いということですから。 この処理は、updateCostByNumOfMemberメソッドに切り出してあります。

ループを大きい方から小さい方へ処理している理由は、costByNumOfMember[i - company.members] の値をもって costByNumOfMember[i]を更新しているからです。若い方の値から古い方を更新しています。 もしループを小さい方へ大きい方へ回したら、同じ company で以前処理した costByNumOfMember[i - company.members]の 値をもって、costByNumOfMember[i]を更新することになります。companyを2重に評価することになります。

また、内部のループでの処理に加え、companyだけを選択した場合についても 考慮する必要があります。同様に updateCostByNumOfMemberを実行する。(53行目の処理)

56行目からの処理は requiedNumOfMember 以上の範囲で一番安いコストを検索する処理です。 端から走査するだけですね。

取得した結果を表示して終わりです。

実行結果

http://paiza.jp/poh/kirishima/result/2bbd184057c0ee7da43c9d0f4384eb9c

100 点はとれてますが実行時間は 0.11 秒から0.18 秒の範囲です。 当然ながら最速のコードよりは大きく離れていますね。 

その他雑駁な話

言い訳

このコードはしえるさんのコードをコピペして、自分がわかりやすいように 直して(でもアルゴリズムの本質は変えていない)記事にしているものです。 http://qiita.com/cielavenir/items/d07e62d1dc61c2915003

他人の褌で相撲を取っているようなもので、申し訳ありません。 しえるさん。もしこの記事に問題ありましたらどうぞお知らせください。 削除する準備はいつでも出来ています。

感想など

競技プログラミングということを考えたら、しえるさんが書いたような方向になるべきでしょうね。

実行速度が全てに優先する。余計なことはしない。それが標準APIであったとしても。 使いまわせる変数は使いまわす。読みやすさ、アルゴリズムのわかりやすさは目指さない。

ですので競技プログラミングの目指すところはいわゆるシステム開発とは異なるものであるなと。

ただ、アルゴリズムがわからないのではコードに責任が持てないので、 勉強よろしく書き直しながらやってみました。下請け会社の組み合わせについての情報は全く捨てるというのが ちょっと新鮮でした。学部の頃やっていたような気もするのですが、思い出しながらということで。

さらなる修正について。

costByNumOfMember は今のところ int[] ですが、 これをクラスにする方向もあって良いかなと思いました。今回のプログラムはcostByNumOfMemberに対する処理が そこかしこに散在しています。mainメソッドの一部として置くよりもオブジェクト指向プログラミング的には そのほうが適切かもしれません。もっとプログラムが大規模になって処理の散在具合が大きくなったら 実施すべきかと思います。

変数名の長さ加減でいかにもおっさんが書きそうなJavaコードっぽさが演出されたかもしれません。 今のデザインでは横幅制限が厳しいので次回できれば改善したいと思います。