IT業界のすみっこ暮らし

ふと気がついたときの記録

今後書きたい記事一覧

  • コードレビュー時の注意点&よくあるパターン
  • 若手指導について
  • もう若手じゃない!お荷物エンジニアについて
  • プログラミング学習日報
  • 開発におけるネガティブ思考のメリット
  • エンジニアの情報収集法

などを技術ネタとは別に書いてみたいです。

Bootstrap:カラーのカスタマイズができるサイト「1pxdeep」

kimikimi714.hatenablog.com

1pxdeep | A flat Bootstrap 3 theme that changes color

職場で見える化を提案したら批判されまくった件

1、職場に蔓延してる属人化&ドキュメント不在

今私が所属している組織は10年以上のレガシーが多数存在しており、ともかく属人化が酷く、文書化する習慣がありません。中途で入社してからまともなドキュメントが存在するシステムは数えるほどしか見たことがないです。

システムの各担当しか内容を把握しておらず、サーバーなどの環境周りの情報から詳しい仕様と内部事情までもが担当者以外は知ることが難しいのです。そして引き継ぎや担当替えのときも、大体は口頭の説明しかもらえないことが多いです。そして加速する属人化…

この頃、エンジニアの退職者が増えている中、これじゃヤバイよねと思う頻度が増えてきました。
blog.stm43.com

hr.wantedly.com

2、まずは自分のできることをやる

1、環境設定(サーバー&DBなどの情報)は必ず見つけやすいよう文書として残す
2、自分が把握した仕様については箇条書きレベルのメモでもいいので記録として残す
3、環境設定の手順や不具合対応手順など、箇条書きでは分かりづらい可能性があるものはキャプチャを添付した形でドキュメント化する
4、前任者から口頭で教えてもらう運用手順について、できる限り運用マニュアルとして文書化する
5、実装してるコードになるべく仕様に関するコメントを残す
6、文書にした内容が変更される場合(仕様変更、サーバー移行など)、必ず内容の更新を行う


以上の内容をなるべく守るよう業務の片手間で実践しています。
「文書化はちょっと大げさなくらいがちょうどいい」(これが大げさか?と突っ込まれるかもしれないけど、うちの職場では大げさな方なので許してください)と思うのは、自分も人間だから時間が経てば忘れる可能性があるし、自分が忙しいときでも「このドキュメントを読んでください」と伝えれば、一から自分が説明するより時間が節約されるからです。

5についてはコメントを嫌ってたり、コード見ればわかるじゃんー!と思う人もいると思いますが、自分だけがそのコードを見るとも限りませんし、コードを見ても分からない人もいる、またコードでロジックは分かるが、なんでこんな仕様になってんの!?と疑問符が飛ぶコードもザラなので、私個人としては適切なコメントは多い方が良い!と思う派です。

3、チームメンバーに見える化を提案

自分のできる範囲のことを頑張りつつ3年未満の若手の指導をしてる中で、チーム単位の属人化問題もいい加減解決しとかないと思うことになりました。

チームの特殊事情

  • チームで管理している細かいシステムがxx個くらい存在する
  • チームの人員不足も伴い、大体一つのシステムを一人が退職まで面倒を見る
  • 他チームとのやり取りのため、DB情報やサーバー情報をまとめるとき、システムごとに管理体制が違うため、各担当に一々聞かないとまとまらないし、時間が掛かる
  • そもそも、同じチームでもうちのチームが担当している全体のシステムの数や詳細が把握しづらい
  • でも同じチームである以上、急にAがBの担当したシステムを引き継ぐ可能性がある
  • Aが担当した複数のシステムをBが引き継ぐ→A退社、Bが文書化しないまま、運用業務がないのもあって放置して忘れる→CがBから引き継ぐ→Aの退社以降、触ってなかったシステムはBもサーバーがどこにあるのすら忘れてる→結局一々サーバー一覧を舐めながらコンテンツを探る必要が発生することも

ということで、まずは各自担当しているシステムの環境仕様周りの見える化を提案しました。

4、提案した結果

見事に批判&言い訳だらけでした。
以下、チームメンバーからの意見の一部です。

「複数リモート管理で十分じゃないですか?面倒くさい」
「既に担当のないシステム(運用中だけ特に問題なく動いているため、担当者が退職したあと、新しい担当がいない)も整理しないと見える化の意味がありません〜」
そもそもエクセルでまとめようとするから難しいんじゃないですか?」
「前は○人しかいなかったからそういう整理できてなくて〜(ズラズラと言い訳)」


おいコラ、誰一人過去の話と現状の話しかしてない!私はこれからの!未来の話をしてるんだよ!今までできなかったことは私も知ってるから未来の話しようぜ?

以下、意見に対する私の返事です。

「複数リモート管理で十分じゃないですか?面倒くさい」

  → 今回の見える化の詳細内容は各サーバー名だけじゃなく、DBサーバー、ログフォルダ、.NETのバージョン、Webサイトの場合、ドメイン情報までも網羅するものだけど、その方法でこの要件を満たすことはできますか?

「既に担当のないシステム(運用中だけ特に問題なく動いているため、担当者が退職したあと、新しい担当がいない)も整理しないと見える化の意味がありません〜」

  → それはこっちも知ってる。そして担当のないものは今すぐはまとめるのが難しいかもしれない。でも、だからと言って今担当が存在するシステムの見える化に意味がないとは思えない。そもそもそんなの気付くくらいなら自分が率先して担当がない分も意味があるようにまとめるのが正しいんじゃないですか?

そもそもエクセルでまとめようとするから難しいんじゃないですか?」

  → 今回持ち出したフォーマットは私が入社する前からこのチームでまとめようとしたけど、してこなかったファイルを修正したもの。正直私としては同じ内容の見える化さえできれば問題ないので、そんな生産的じゃない批判するくらいなら改善案を出してください。

「前は○人しかいなかったからそういう整理できてなくて〜(ズラズラと言い訳)」

  → この話には「じゃこれからでもやってくださいよ!」と返したけど、この人はチームで一番社歴が長い人で、この人の言ってる「○人しかいなかった」頃はもう4年以上前の話なんだけど、それを言い訳にするのが本当理解できなかった。もう過去は過去たから未来の話しようぜ?これから未来の話しようとしてるのになんでそんな昔の話を持ち出して言い訳してるの?普段から業務もロクに出来てないし、過去のままで成長が止まってるの自覚してる?

最後に

あー本当疲れた。おかげでちょっとヒートアップしました。
幸いチームのリーダーとは認識が合致したため、なんとか各自のタスクとすることができました。そんな大きな成果は目に見えないかも知れませんが、これで1%でもマシになれば良いなと思います。

最後に、疲れた心に少し癒された文章を引用して締めとします。
「仕事ができるやつ」への最短の道 | 安達裕哉


「安達さん、仕事で一番偉いのは誰だと思います?」

「はあ?…権限を持っている方でしょうか。」

「権限を持っていてもダメな奴はダメな奴です。どんな仕事でも、一番偉いのは「最初に案を出すやつ」なんですよ。批判なんてだれでもできる。でも、「最初に案を出す」のは勇気もいるし、なにより皆から馬鹿にされないように一生懸命勉強しなければいけない。だから、最初に案を出すやつを尊重するのは仕事では当たり前です。」


以上

ASP.NET:Urlにドット「.」を含む文字列を許容する

stackoverflow.com

Urlにドット「.」を含む文字列を許容する

<add name="ApiURIs-ISAPI-Integrated-4.0" path="*" verb="GET,POST" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

ASP.NET MVC:全ての例外をログに吐き出す

paulthecyclist.com

App_Start/FilterConfig.cs

using log4net;

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters, ILog logger)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new ExceptionLoggingFilter(logger));
    }
}

ExceptionLoggingFilter.cs

public class ExceptionLoggingFilter : IExceptionFilter
{
    private readonly ILog _logger;

    public ExceptionLoggingFilter(ILog logger)
    {
        _logger = logger;
    }

    public virtual void OnException(ExceptionContext filterContext)
    {
        _logger.Error(filterContext.Exception);
    }

    public interface IExceptionFilter
    {
        void OnException(ExceptionContext filterContext);
    }
}

Global.asax.cs

protected void Application_Start()
{
    XmlConfigurator.Configure();
    ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters, logger);

    // other registration
}

追記

エラー発生後の遷移先設定(Global.asax.cs)

protected void Application_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
    
    if (ex is HttpException)
    {
        // 404エラーの場合
    }
    else if (ex is InvalidOperationException)
    {
        // 無効な呼び出しの場合
    }
}

ASP.NET MVC:ModelStateからエラーメッセージを取得

pie001.hatenablog.com

前回上記の記事でも軽く書いたが、エラーメッセージ取得部だけをキーによる取得方法も加えてまとめてみた。

0、下記のようにModelStateにエラーを宣言し、エラーメッセージ(stringリスト)を取得する

ModelState.AddModelError("Parameter", "パラメーターが正しくありません。P1");
ModelState.AddModelError("Parameter", "パラメーターが正しくありません。P2");
ModelState.AddModelError("Parameter", "パラメーターが正しくありません。P3");
ModelState.AddModelError(string.Empty, "パラメーターが正しくありません。1");
ModelState.AddModelError(string.Empty, "パラメーターが正しくありません。2");
ModelState.AddModelError(string.Empty, "パラメーターが正しくありません。3");


1、ModelStateにある全てのエラーメッセージを取得

①SelectMany利用

var errormsgs = ViewData.ModelState.SelectMany(x => x.Value.Errors.Select(z => z.ErrorMessage)).ToList();

②foreach利用

var allErrorList = new List<string>();
foreach (ModelState modelState in ViewData.ModelState.Values)
{
    foreach (ModelError error in modelState.Errors)
    {
        allErrorList.Add(error.ErrorMessage);
    }
}

取得結果(List<string>の中身)

Index ErrorMessage
0 パラメーターが正しくありません。P1
1 パラメーターが正しくありません。P2
2 パラメーターが正しくありません。P3
3 パラメーターが正しくありません。1
4 パラメーターが正しくありません。2
5 パラメーターが正しくありません。3


2、ModelStateにある特定のキーのエラーメッセージだけを取得

var param = ViewData.ModelState["Parameter"];
var paramErrorList = new List<string>();

// ViewData.ModelState[key]に存在しないキーを指定した場合、nullを返す
if (param != null)
{
    paramErrorList = param.Errors.Select(x=>x.ErrorMessage).ToList();
}

取得結果(List<string>の中身)

Index ErrorMessage
0 パラメーターが正しくありません。P1
1 パラメーターが正しくありません。P2
2 パラメーターが正しくありません。P3

Deep Learning Lab コミュニティ キックオフに行ってきました

f:id:papamau:20170619092544j:plain

最近AIやDeepl Learningという言葉はよく耳にしているけど、今のところ職場で使いそうにないし、上の人たちもなんか興味なさそう…そもそもAIを使った開発なんてうちらとは別世界な気がする!?でも一応エンジニアとしてなんとかしないとな〜という軽い(?)気持ちでconnpassを検索してたら下記のイベントを見つけたので、今日参加して来ました。

dllab.connpass.com

あまり知識のない状態で一気に色々聞いてしまってもう目から鱗でして、今の職場環境に甘んじちゃダメだなと改めて自覚しました。世界は広い!未来は怖い!

タイムテーブル

時間 セッションテーマ 登壇者
9:00 開場
9:30 開演
9:30-10:00 Preferred Networks と Microsoft の業務提携が意味するもの 株式会社Preferred Networks 取締役 最高執行責任者 COO 長谷川順一
10:00-10:45 ディープラーニング技術の最新事例と導入の課題 株式会社Ridge-i 代表取締役社長 柳原尚史
10:45-11:05 DIMoの操作実演とSCSKが提供するプログラム SCSK株式会社 AIビジネス推進室 課長 島田源邦
11:05-11:20 トレーニング展開のご紹介 日本マイクロソフト株式会社 廣野淳平
11:20-11:30 Deep Learning Labのご紹介 日本マイクロソフト株式会社 新井浩之
11:30-12:30 懇親会

内容はどれもギュッと詰まっていて凄く濃い内容でした。
さまざまな実例と実際の活用について、また映像解析の操作実例など詳しく説明して頂いてとても良かったです。

ちょうど今どこから手を付ければいいか…と悩んでいるところだったので、一先ず今日のイベントで拾ったキーワードを調査&理解することから始めたいと思います。


一部の資料がイベントのあとにアップロードされていたのでご紹介します。

Preferred Networks と Microsoft の業務提携が意味するもの

www.slideshare.net

ディープラーニング技術の最新事例と導入の課題

www.slideshare.net

DIMoの操作実演とSCSKが提供するプログラム

www.slideshare.net

www.slideshare.net



次回は7月25日にあるようで、早速申し込みしました!
1ヶ月後のなので、その間に今日よりはマシになるよう少しは勉強しておきたいと思います。 dllab.connpass.com


追記

このイベントの参加者で、内容までも詳しく記事に書いた方を見つけたので紹介 tkat0.hateblo.jp

spark-notebookを触ってみた

まだApache SparkもSpark Notebookも勉強中なので詳しくは分からない状態だけど、軽く触ってみたのでその内容のメモ。

Apache Spark

オープンソースクラスタコンピューティングフレームワーク

Apache Spark™ is a fast and general engine for large-scale data processing.
Apache Spark™は、大規模なデータ処理のための高速かつ一般的なエンジンです。 spark.apache.org

Spark Notebook

Sparkを実行できるWebUI

Interactive and Reactive Data Science using Scala and Spark.
Spark Notebook

Spark Notebookを触ってみた

まだあまり理解が追いついていないが、エンジニア仲間のcrowdyさんが作った環境を一緒に触る機会があったので簡単に触ってみた。 f:id:papamau:20170618142502p:plain

サンプルなどを実行
f:id:papamau:20170618144603p:plain

※「Spark runs on Java 7+, Python 2.6+/3.4+ and R 3.1+. For the Scala API, Spark 2.1.1 uses Scala 2.11. You will need to use a compatible Scala version (2.11.x).」らしい。 spark.apache.org

f:id:papamau:20170618151436p:plain

f:id:papamau:20170618152424p:plain

f:id:papamau:20170618153312p:plain

f:id:papamau:20170618154229p:plain

f:id:papamau:20170618161455p:plain


今回触ったのは全てランダムでデータを生成して地図とかグラフとか一覧で表示してるんだけど、色んな種類が用意されていて触るだけでも面白い。

f:id:papamau:20170618155120p:plain


感想

まだデータ分析の方は基盤がないので???!!???の状態だったけど、良い刺激になった。Jupyter Notebookも含めデータ分析についてこれから勉強していきたいと思う。

jquery:階層要素のドラッグ&ドロップ関連ブクマ

jQuery Sortable

github.com

mjsarfatti.com

github.com

stackoverflow.com

jsfiddle.net