順次、選択、そして繰り返し

プログラミングのことやITのこと、たまに演劇のことも書きます。

転職して1ヶ月の所感

前職と変わったところ

  • タスクを自分で考えるところ
    • 前職ではタスクは降ってきて、それを細分化して取り組んでた
    • 今は「もっと使いやすくするには」みたいなざっくりとした指示を元に自分らで機能改善やタスクを作っていくイメージ
      • なので機能改善の他にも空いた時間で開発環境の改善ができるので楽しい
  • 説得がしやすくなった(新たな仕組みやツールを導入するとき)
    • 前職は元請けや自社の上司、チームメンバーなど説得する相手が多かった
    • 今は自社開発ということもあり説得する相手が少なくなったので実行に移しやすくなった
      • 基本、いいと思ったものは即実行しているイメージ(事前に上司に相談はするけど)
  • 福利厚生
    • 業務時間内での外部の勉強会参加
    • 飲み物やお菓子が食べ放題(軽食もあったはず)
    • 仮眠スペースがある(まだ使ったことないけど……)
    • 前職も福利厚生は色々あったが、業務時間内に使える福利厚生の方が自分には合ってると感じた
      • 特定のテーマパークが割引になる福利厚生もあったけど休みの日引きこもり気味の自分にとってはそこまで恩恵を受けられなかった……

良かったところ

  • フレックス制
    • コアタイムと1日の所定時間働けばOK
    • 満員電車を回避して出社できるのは精神衛生良いと感じた
  • 休憩時間が自由
    • 1時間どこかで休憩を取ればいい
    • 昼ご飯のピーク時を避けられるので良い
  • 基本的に使用するツールは自由
  • ユーザ目線のエンジニアが多い
    • 機能追加とか新サービスの提案が活発
      • 自分自身はこの提案が苦手(0から1を生み出す作業)なのでユーザ目線で提案できるように学んでいきたいと思う

改善していきたいところ

  • エンジニア目線で楽したいと考えるメンバーが少ない?
    • 作業効率化を提案するメンバーが少ないイメージ
      • メンバー自体が若いので効率化の経験が少ないのでそういう提案が少ないらしい
      • もうちょっと開発を楽したい(テスト自動化,CIなど)
    • この点は自分が得意な領域なのでどんどん提案していきたい(そしてチーム内の文化になればいいなと)
  • メンバー間のタスクがわからない
    • 各々タスクを考えて動いているため今後タスクの被りとか発生したら勿体無いなと思う(今の所発生してないけど)
    • リーダも進捗把握し難いと思う

初めての転職活動ついて

初めて転職活動をした時に発見や学びが色々あったのでメモ程度にまとめておく。

なぜ転職しようと決意したか

自分のやりたい事(軸)が変わった

自分がやってみたいことが新卒時と比較して変わったため。 また、やってみたいことが社内で叶えられるか考えた時に難しいと判断したため。

  • 新卒として就職活動していた時の軸
    • 独立系SIer(親会社がいないので使用するソフトウェアの制限がない)
    • 様々な業種のシステムの開発に携わりたい(業務知識を増やしていきたい)
    • 特に技術寄りとかマネジメント寄りとかは考えていなかった
  • 転職活動時の軸
    • 自社サービスを保有している
    • コードを書き続けていたい(マネジメントよりスペシャリスト方面になりたい)
    • エンジニアサイドに裁量権がある(使用するツールや言語など)
    • モダンなツールやフレームワーク、言語を使用した開発
    • 常に効率化を図ろうとしている雰囲気があるか(テスト自動化など)

使用したサイト

  • paiza転職(7社応募)
    • スキルチェックの評価によって書類選考をスキップして面談から始められる
    • 選考結果と一緒にフィードバック(採用・不採用になった理由が詳細に通知される)があったのは良かった
      • 次の選考に繋げられた
  • Green(1社応募)
    • エンジニア系に特化した転職サイト

結果

  • 2社内定をいただいた
  • 7月下旬から入社予定
  • 入社の決め手
    • 相手の意見に対して否定から入らない社風
      • 否定寄りの意見を出すときは必ず否定だけではなく、別の案を出す雰囲気
      • この雰囲気が良かった
    • R&Dに携われる
      • 短いサイクルで新サービスを出すみたいなので、新しい技術に触れる機会が増えそうだと思った

面談で聞かれたこと

  • なぜこの大学(専門学校)に進学しようと思ったか
    • 新卒時の就職活動ではよく聞かれたが、転職活動時にも聞かれるとは思ってなかった(職務経歴重視だと思ってた)
  • コードを書く時に気をつけていることは何ですか
    • 分かりやすい命名とかテスタブルなメソッドにするとか etc
  • 業務て失敗したことは何ですか(また、そこから学んだ事はは何か)
    • 新卒時の就職活動で似た質問を聞かれたことがある気がする。ただ失敗談を話すのではなく、そこから何を学んで活かしているのかを知りたいんだろうな
  • ○○のシステムを開発するとしたらどういうシステム設計にしますか。(紙に書いて説明)
    • これは何もできなかった
    • お題が「ライブコマースのシステム」と言われて、ライブコマース自体何かわからなかった。
    • 面談で「技術選定に携わりたいです」と言ってたから、本当に選定できるスキルがあるのか試したかったのかもしれない
      • でも何故かその企業からは内定をいただいた(今回は辞退させていただいた)

所感

  • 今まで経験したプロジェクトの棚卸しがキツかった
    • 日頃、棚卸しをしておいたほうがいいと感じた(特に面談でプロジェクトの説明をする時に必要)
      • どんなプロジェクトだったか
      • 自分はプロジェクト内でどんな立場だったか(メンバー、サブリーダーなど)
      • 使用した言語、フレームワーク
  • サービス志向が重要
    • 何社か面談をして落とされた時の理由が「サービス志向が足りない」だった
    • 要はユーザ目線でシステム開発をすることができるかってことらしい
    • 今まで設計書が出来上がっている状態でコードを書くことが多かったのでユーザ目線で物事を考えることが無いなと思った
      • ユーザが設計書をレビューしているのでどれだけ挙動がおかしくても覆そうとは思わなかったかも...

Smallchatを試してみる

Smallchatの始め方

small.chat

※事前にSlackの登録が必要

チャット用のチャンネルを作成する。 f:id:sndstudy:20180110204508p:plain

チャンネルを作成するとScriptタグが表示されるので、チャットを表示させたいHTMLに埋め込む。 f:id:sndstudy:20180110204623p:plain

Webページからメッセージを送信するとSlackにスレッド形式で送信される。 スレッド内で送信元にメッセージを返すことができる。 f:id:sndstudy:20180110205817p:plain

チャットのタイトルや文字色を変更することができる。 f:id:sndstudy:20180110204454p:plain

料金プラン

1年単位(月額)

  • Personal 無料
  • Growth 15.99ドル 自動メッセージが送れるようになる
  • Business 31.99ドル JavaScriptAPIの使用が可能

月単位

  • Personal 無料
  • Growth 19.99ドル
  • Business 39.99ドル

無料プランで設定できること

  • Brand color ヘッダーの色を変更
  • Text color ヘッダーの文字色を変更
  • Launcher type チャットのランチャーの形
  • Launcher position チャットのランチャーの表示位置
  • Launcher prompt チャットのランチャーの表示文字列
  • 名前とメールアドレスの取得 など

CI(メモ)

CIとは

  • 継続的インテグレーション(Continuous Integration)
  • アプリケーション作成時の品質改善や納期の短縮のための習慣のことである。
    • コードを修正する度にコンパイル、テスト、デプロイを行うこと。
なぜコードを修正するたびにコンパイル、テスト、デプロイをする必要があるか
  • 早期にバグの検知と原因箇所が発見しやすい
    • 10行コードを修正した後に発見するバグと100行コードを修正した後に発見するバグでは原因の範囲が異なる
    • 範囲が狭いほうがバグの場所がわかりやすい
しかし、手動でコンパイル、テスト、デプロイをするのは面倒
javac Test.java
java Test

そこでCIツールであるJenkins

Jenkinsのメリット
  • 繰り返し作業の自動化
    • 軽微なソースコードを修正したとしてもコンパイル、テスト、デプロイを自動化することで作業時間を短縮することができる
  • 属人化を防ぐ
    • コンパイルやデプロイといった作業をJenkinsに登録することでビルド・デプロイ手順を知らない人でもボタン1つで実行環境を更新することができる
  • プラグインによる機能拡張が豊富

数値リテラルについて

2進リテラル


Java7から先頭に0bを入れることで2進数として判定されるようになった。

ソースコード
int val1 = 20;
int val2 = 024;
int val3 = 0x14;
int val4 = 0b10100;

System.out.println("10進数:" + val1);
System.out.println("8進数:" + val2);
System.out.println("16進数:" + val3);
System.out.println("2進数:" + val4);
実行結果
10進数:20
8進数:20
16進数:20
2進数:20

アンダースコアがある数値リテラル


Java7から数値リテラルを扱うときに数字の途中に「_」を使用できるようになった。 桁数の大きな数値リテラルの可読性を高めるときに使用する。

ソースコード
int val5 = 2_0;
int val6 = 02_4;
int val7 = 0x1_4;
int val8 = 0b1_0_1_0_0;

System.out.println("10進数:" + val5);
System.out.println("8進数:" + val6);
System.out.println("16進数:" + val7);
System.out.println("2進数:" + val8);
実行結果
10進数:20
8進数:20
16進数:20
2進数:20

数値リテラルの中に「_」を使用する場合、以下の場所には使用できない。

  • リテラルの先頭、末尾は使用できない
  • 浮動小数リテラルにある小数点の前後には使用できない
  • float値やlong値を表すfやLなどの前には使用できない
  • 16進数で使用する0xや2進数の0bの途中及び前後には使用できない

NIO.2について

NIO.2(New I/O 2)とはJava7から登場した新しいファイルシステムインターフェースのこと。

Java6まではファイルの属性の取得・設定やディレクトリの監視をすることができなかったため、それらの処理ができるインターフェースをNIO.2として用意された。

NIO.2の関連パッケージ


java.nio.file

ファイル、ファイル属性及びファイルシステムにアクセスするためのインターフェースとクラスが提供されている。

Class or Interface 名前 説明
Interface Path ファイルシステム内のファイルを特定するために使用するシステムに依存するファイルパスを表す
Class Paths パス文字列パス文字列またはURIを変換してPathオブジェクトを返すstaticメソッドを提供
Class FileSystems ファイルシステム用のファクトリクラス。
Class FileSystem ファイルシステムへのインタフェースを提供し、ファイルシステム内のファイルやその他のオブジェクトにアクセスするための手段を提供する

Pathインタフェース

Paths.get()の挙動
//Paths.get()では環境に応じたパスを持ったPathオブジェクトを返す
//path1ではファイルセパレータが"/"から"\"に変換されている
Path path1 = Paths.get("test/hoge.txt");
Path path2 = Paths.get("F:\\GitRepository");
Path path3 = Paths.get("F:","GitRepository");

System.out.println("path1:" + path1);
System.out.println("path2:" + path2);
System.out.println("path3:" + path3);
Paths.get()実行結果
path1:test\hoge.txt
path2:F:\GitRepository
path3:F:\GitRepository
Pathインタフェースの主なメソッド
Path path4 = Paths.get("F:\\GitRepository\\hoge.txt");

//パスの文字列表現を返す
System.out.println("toString:" + path4.toString());

//名前要素シーケンスの最後を返す
System.out.println("getFileName:" + path4.getFileName());

//指定したインデックスに対するパス要素を返す。0番目はルートに最も近い要素
System.out.println("getName(0):" + path4.getName(0));

//パス内の要素数を返す
System.out.println("getNameCount:" + path4.getNameCount());

//パスのルートを返す
System.out.println("getRoot:" + path4.getRoot());

//親ディレクトリのパスを返す
System.out.println("getParent:" + path4.getParent());

//開始インデックスから終了インデックス-1の要素を取得
System.out.println("subpath0-2:" + path4.subpath(0, 2));
System.out.println("subpath1-2:" + path4.subpath(1, 2));

Path path5 = Paths.get("./hoge.txt");

//冗長な名前要素を削除したパスを返す
System.out.println("normalize:" + path5.normalize());

//パスを表すURIを返す
System.out.println("toUri:" + path5.toUri());

//絶対パスか判定絶対パスの場合はTrue
System.out.println("isAbsolute:" + path5.isAbsolute());

//絶対パスを返す
System.out.println("toAbsolutePath:" + path5.toAbsolutePath());

//既存ファイルの実際のパスを返す
try {

    //既存ファイルの実際のパスを返す
    System.out.println("toRealPath:" + path5.toRealPath());
} catch (IOException e) {

    e.printStackTrace();
}

//パスの結合(引数が絶対パスの場合は引数の値が返ってくる)
Path path6 = Paths.get("hogehoge");
Path path7 = Paths.get("test");
System.out.println("resolve:" + path6.resolve(path7));

//指定されたパス間の相対パスを返す
System.out.println("relativize:" + path6.relativize(path7));
実行結果
toString:F:\GitRepository\hoge.txt
getFileName:hoge.txt
getName(0):GitRepository
getNameCount:2
getRoot:F:\
getParent:F:\GitRepository
subpath0-2:GitRepository\hoge.txt
subpath1-2:hoge.txt
normalize:hoge.txt
toUri:file:///F:/GitRepository/AppRepository/workspace/JavaWork/./hoge.txt
isAbsolute:false
toAbsolutePath:F:\GitRepository\AppRepository\workspace\JavaWork\.\hoge.txt
toRealPath:F:\GitRepository\AppRepository\workspace\JavaWork\hoge.txt
resolve:hogehoge\test
relativize:..\test

Filesクラス

ファイル、ディレクトリなどを操作するクラス staticメソッドだけで構成されている

Filesクラスの主なメソッド
Path path1 = Paths.get("hogeDir");
Path path2 = Paths.get("F:\\GitRepository\\AppRepository\\workspace\\JavaWork\\hogeDir");
Path path3 = Paths.get("hoge.txt");

//ファイルの存在確認
System.out.println("exists:" + Files.exists(path1));

try {
    //2つのパスが同じファイルを検出するかテストする
    System.out.println("isSameFile:" + Files.isSameFile(path1, path2));
} catch (IOException e) {

    e.printStackTrace();
}

//このパスがディレクトリかテストする
System.out.println("isDirectory:" + Files.isDirectory(path1));

//通常ファイルかテストする
System.out.println("isRegularFile:" + Files.isRegularFile(path1));

//読み取り可能かテストする
System.out.println("isReadable:" + Files.isReadable(path3));

//実行可能かテストする
System.out.println("isExecutable:" + Files.isExecutable(path2));

Path path4 = Paths.get("hogeDir2");

try {
    //ディレクトリの作成
    Files.createDirectory(path4);

    //ディレクトリの削除
    Files.delete(path4);

    //ディレクトリが存在した場合は削除する
    System.out.println("deleteExists:" + Files.deleteIfExists(path4));

} catch (IOException e) {

    e.printStackTrace();
}

Path path5 = Paths.get("hoge2.txt");
Path path6 = Paths.get("hoge2copy.txt");

try {

    //コピーする
    Files.copy(path5, path6, StandardCopyOption.REPLACE_EXISTING);

    //移動またはリネームする
    Files.move(path6, path5, StandardCopyOption.REPLACE_EXISTING);


    //ファイルデータの読み込み
    List<String> list = Files.readAllLines(path3);

    for(String str : list) {
        System.out.println("読み込み行:" + str);
    }


} catch (IOException e) {

    e.printStackTrace();
}
実行結果
exists:true
isSameFile:true
isDirectory:true
isRegularFile:false
isReadable:true
isExecutable:true
deleteExists:false
読み込み行:ほげほげほげ
読み込み行:ホゲホゲホゲ

java.nio.file.attribute

ファイル及びファイルシステム属性にアクセスするためのインターフェースとクラスが提供されている

Class or Interface 名前 説明
Class FileTime ファイルのタイムスタンプ属性の値を表す
Interface FileAttribute 新しいファイル・ディレクトリを作成するときに自動的に設定できるファイル属性を表すオブジェクト
Interface BasicFileAttributes すべてのファイルシステム実装で必要となる基本的な属性を表すオブジェクト
Interface DosFileAttributes DOS属性をサポートするファイルシステムで使用される属性が追加されている
Interface PosixFileAttributes POSIX標準ファミリをサポートするファイルシステムで使用される属性が追加されている
Files.geAttribute()の挙動
Path path1 = Paths.get("hoge.txt");

try {

    //作成日
    Object obj1 = Files.getAttribute(path1, "creationTime");

    //最終更新日
    Object obj2 = Files.getAttribute(path1, "lastModifiedTime");

    //サイズ
    Object obj3 = Files.getAttribute(path1, "size");

    System.out.println("creationTime:" + obj1);
    System.out.println("lastModifiedTime:" + obj2);
    System.out.println("size:" + obj3);

} catch (IOException e) {
    
    e.printStackTrace();
}
Files.geAttribute()実行結果
creationTime:2017-07-26T12:38:49.578851Z
lastModifiedTime:2017-07-26T14:55:17.263971Z
size:38
BasicFileAttributesの挙動
Path path1 = Paths.get("hoge.txt");

try {

    //BasicFileAttributesでメタデータを取得するパターン
    BasicFileAttributes attr = Files.readAttributes(path1, BasicFileAttributes.class);

    System.out.println("creationTime:" + attr.creationTime());
    System.out.println("lastModifiedTime:" + attr.lastModifiedTime());
    System.out.println("size:" + attr.size());


} catch (IOException e) {
    
    e.printStackTrace();
}
BasicFileAttributes実行結果
creationTime:2017-07-26T12:38:49.578851Z
lastModifiedTime:2017-07-26T14:55:17.263971Z
size:38
DosFileAttributesの挙動
Path path1 = Paths.get("hoge.txt");

try {

    //DosFileAttributesでメタデータを取得するパターン
    DosFileAttributes dosAttr = Files.readAttributes(path1, DosFileAttributes.class);

    //アーカイブ属性の値を返す
    System.out.println("isArchive:" + dosAttr.isArchive());

    //隠し属性の値を返す
    System.out.println("isHidden:" + dosAttr.isHidden());

    //読み取り専用属性の値を返す
    System.out.println("isReadOnly:" + dosAttr.isReadOnly());

    //システムの属性の値を返す
    System.out.println("isSystem:" + dosAttr.isSystem());


} catch (IOException e) {
    
    e.printStackTrace();
}
DosFileAttributes実行結果
isArchive:true
isHidden:false
isReadOnly:false
isSystem:false

ディレクトリアクセス関連メソッドの挙動

ディレクトリ・ファイルの配置状態

f:id:sndstudy:20170727234940p:plain

FileSystem fs = FileSystems.getDefault();

//ルートディレクトリを取得する
Iterable<Path> dirs = fs.getRootDirectories();

for(Path name: dirs) {

    System.out.println("RootDir:" + name);

}

Path path1 = Paths.get("hogeDir");

try {

    System.out.println();

    //ディレクトリ内を探索する(サブディレクトリ含む)
    Files.walk(path1).forEach(System.out::println);

    System.out.println();

    //ディレクトリ内を探索する(サブディレクトリは含まない)
    Files.list(path1).forEach(System.out::println);

} catch (IOException e) {

    e.printStackTrace();
}

try {

    System.out.println();

    //パスに対して条件を指定して合ったパスのみで構成されるストリームを返す
    Files.find(path1, 2, (path, attr) -> path.toString().startsWith("hogeDir\\hogehoge1")).forEach(System.out::println);;

} catch (IOException e) {
    e.printStackTrace();
}

Path path2 = Paths.get("hoge.txt");

try {

    //ファイル内のすべての行を読み取る
    System.out.println("line():" + Files.lines(path2).map(word -> word.length()).collect(Collectors.toList()));
} catch (IOException e) {
    e.printStackTrace();
}
ディレクトリアクセス関連メソッドの実行結果
RootDir:C:\
RootDir:D:\
RootDir:E:\
RootDir:F:\

hogeDir
hogeDir\hogehoge1.txt
hogeDir\hogehoge2.txt
hogeDir\hogehoge3.txt
hogeDir\hogehogeDir
hogeDir\hogehogeDir\hogehoge4.txt

hogeDir\hogehoge1.txt
hogeDir\hogehoge2.txt
hogeDir\hogehoge3.txt
hogeDir\hogehogeDir

hogeDir\hogehoge1.txt
line():[6, 6]

自作PCについて(メモ)

やりたいこと
  • マルチディスプレイ(ゆくゆくは3画面4画面にしたい)
  • プログラミングするには不自由ないスペック
  • 仮想環境立てても支障がないスペック
パーツ
パーツ 製品名 値段(ざっくり) 備考
OS Windows10 Home 64bit 15,000円 DSP
マザーボード - 15,000円 PCI Express x16スロットが複数あれば良
CPU Intel Core i5 7400 23,000円 -
メモリ CMK16GX4M2A2666C16 15,000円 16GB(8GB*2)
SSD - 10,000円 256GB
HDD - 7,000円 1TB
グラフィックボード - 10,000円 -
PCケース K282 RC-K282-KWN1-JP 7,000円 -