B-Teck!

お仕事からゲームまで幅広く

【PHP】PHPカンファレンス2019に参加したので感想などを書きました

f:id:beatdjam:20191208014411j:plain
2019/12/1に開催されたPHPカンファレンス2019に行ってきました。
2015年に開催されたもの以来の参加で、めっきりPHPを書いておらず不安だったのですが、
相変わらずとても楽しいイベントでした。

感想

個人的な衝撃としては、当時鳴り物入りで現れたPHP7が既にある程度一般化しており、
7.1がEOLになったというところが非常に大きかったです。
みんなのPHP 現場で役立つ最新ノウハウ! とか読んで最近のPHP知った方がいいのかな…

私は今Kotlinでサーバーサイドを書いているのですが、設計の話や並行並列プログラミングの話など、
言語を跨いでいても興味関心やアプローチが似通ってくるんだなぁというのも面白かったです。

参加したセッションと一言メモ

PHPの今とこれから2019

www.slideshare.net Typed Properties 2.0の話と、未だにPHPが高速化し続けているのがびっくりだった。
8.0で出るというJITに期待。

PHPにおける並列処理と非同期処理入門

speakerdeck.com 並行・並列の違いの資料が非常にわかりやすかった。
Swooleの導入についてSDに寄稿されているとのことなので、読もうと思う。

Chatworkのシステムから学ぶレガシーなPHPの限界とレガシーからの脱却

speakerdeck.com 機材トラブルで押していたため、セッションの合間で後半だけ聞けた。
一定程度までスケールしたモノリシックなシステムをPHPで維持していくのは厳しそうだなと思った。
ただ、後述するグラブルのセッションでかなりの規模のシステムを運用している事例も聞けたので、
当初からスケールできる作り方ができていればあるいは…?という感じ。
レガシーに立ち向かうための組織構造の話は非常に良かった。

PHPからgoへの移行で分かったこと

speakerdeck.com
松屋自販機がうちにもほしいなと思った。
マイクロサービスとして切り出せる状態じゃなく異なる言語で移行するの相当しんどいのでは…?
ガワはPHPのままでマイクロサービスとして切り出したgoのサービス呼んだほうが単純だったと思う。
こういった失敗事例は共有されること少ないので、登壇自体に大きい意味があった。

『グランブルーファンタジー』開発エンジニアの考え方~PHP7が『グラブル』にもたらしたブレイクスルーと考察~

(資料なし)
例年通りであればCygames Engineers' Blogにフォローアップ記事が出ると思うので期待。 サービスの規模の説明時点で桁違いのアクセス数、システム規模で驚かされた。
ユーザーとしてプレイしていたこともあるので、裏側の話が聞けたのは感慨深い。
移行の実例からどういった部分で高速化が行われたのか、コード例を交えて解説されていてわかりやすかった。

改善失敗から学ぶ、レガシープロダクトに立ち向かうチーム作り。

speakerdeck.com 残念な情報共有ずかんのイメージが強かったので、Garoonのプロダクトとしての長さにびっくり。
本当の改善に至るまで一つ一つ、失敗と、その失敗を踏まえた改善を行っていく過程がすごかった。
失敗から学ぶ姿勢、大事。

Webサービスのトラブルの現場 ~Webサービスの今と昔~

speakerdeck.com セッションでも語られていた通り、PHPに限った話はあまりなく、Webサービス全般におけるトラブルシューティングの話だった。
取り上げられる事例がどれも胃に痛みを感じるやつだったと同時に、どのようなアプローチが有効かがわかりやすくてよかった。
あと単純にそーだいさんの話がめちゃくちゃ面白かった。

オニギリペイのセキュリティ事故に学ぶ安全なサービスの構築法

www.slideshare.net 架空のPay系サービスを題材に、実例を元に数々の試練とその対処を学ぶセッション。
流石にありえないでしょ!というものから、実際にやってしまいかねない…といった内容まであって、
うっかりをなくさないようにするとか、発生しないようにするとか、そういう仕組み作らないとなんだなぁと。

LT

Laravel + Nuxt.js + FirebaseでDXと開発コストを意識したSPA開発

Laravel + Nuxt.js + FirebaseでDXと開発コストを意識したSPA開発 - Speaker Deck
会社と組織の枠の話がちょっと多くて、タイトルの部分の話が全然記憶に残っていない…

PHPでgRPCってどこまでいけるの?

PHPでgRPCって どこまでいけるの? - Speaker Deck
PHPでgRPCはまだ早かったらしい。
定期的に話題には出てるけど、世界が追いついていない感じ。

PHP-CS-FixerをIDEに取り込ませてPSRを強制する開発スタイル

PHP-CS-FixerをIDEに取り込ませてPSRを強制する開発スタイル
適用するべき規約があるなら一発で習慣的に適用できるのがやっぱりベストだなと。

レガシーコードでビジュアルリグレッションテストをやってみた

レガシーコードで ビジュアルリグレッションテスト をやってみた! - Speaker Deck
ビジュアルリグレッションテスト、思ってたよりは導入しやすいんだなと思った。
スライドが全体的にいい感じにかわいかった。

PHP on AWS Lambda!

PHP on AWS Lambda!
公式で対応してない言語でもカスタムランタイムでLambda使えるの知らなかった。
そういった言語でも想像以上に普通に動くんだなという感じ。

2年目エンジニアがスキルアップのためにPHPで競プロやってみた

(資料見つからず)
登壇中に資料のページが消えている?ようなことを言っていて大変そうだった。
普通に開発していると標準入出力なんて意識しないからむずいよね…わかるわかる…ってなった。
PaizaをひたすらPHPで解いてた時期があったので懐かしい

設計文化のないチームに文化を広めたが冴えない一手で混沌を招いた話を聞いてほしい

設計文化のないチームに文化を広めたが冴えない一手で混沌を招いた話を聞いてほしい.pdf - Speaker Deck
説明をサボると意図通り伝わらず、余計に混沌を生んでしまう。
新しい文化を伝えるときは、サボらず、しっかりと時間を取って認識をすり合わせないとやばい。

運用経験ばかりのメンバーと新規開発で初めてしっかりと設計から開発までを経験した話

運用経験ばかりのメンバーと新規開発で初めてしっかりと設計から開発までを経験した話 / PHP Conference Japan 2019 LT - Speaker Deck
クリーンアーキテクチャ導入。わからないところはわからない。原理主義的にならない。

エンジニアがブログや登壇で、アウトプットするとどうなる?

エンジニアが ブログや登壇で、アウトプットするとどうなる?in PHPcon - Google スライド
うゐろうさんのめちゃくちゃ熱いLT。
自信のなさを自覚した上で、2年毎日ブログを書くというアプローチで乗り越えたの、本当に尊敬する。

余裕を生み出すコードレビュー

余裕を生み出すコードレビュー 〜レビュイー編〜 / code-review-phpcon-2019 - Speaker Deck
わかりやすいプルリクの出し方。
コンテキストを一番理解しているレビュイーがわかりやすくプルリクをしっかり説明しようという話。
当然といえば当然だけど、めっちゃ大事。

社内最長老のシステムにPHPUnitで立ち向かう方法

社内最長老のシステムにPHPUnitで立ち向かう方法 - Speaker Deck
アンパンマンの作者みたいな名前、というツカミが強すぎる。
全機能テストと言う響きがつらすぎる…しっかりと戦略を立ててからの勢いがすごそうだった。

開発合宿のススメ!

【PHPCon2019】開発合宿のススメ! - Speaker Deck 開発合宿といいつつ、対話にパソコンは使わないというのが面白いなと思った。
実際の開発部分でどうしてるのか…?はよくわからなかった。

以上!2020も参加できたらいいなぁ。

【Android/Kotlin】ZXing Android Embeddedを用いて簡単にQRコードを扱う

Androidアプリの勉強のため、QRコードリーダーの開発を行っています。
とりあえずQRコードを読み取る・生成する部分については実装することができました。
せっかくなのでご紹介しようと思います。

記事内に登場するコードは、下記リポジトリにて記載されているものが殆どです。
動作しているものを確認したい場合はご覧ください。 github.com

また、本記事は下記のQiita記事を参考にKotlinで実装を行ったもの+αとなります。 QRコードの読取、生成をする [Android] - Qiita

もくじ

1. ライブラリ導入

github.com

app/build.gradle に下記の記述を追加して、ライブラリの導入を行います。
元記事ではminSdkVersionを15にしていましたが、最新のライブラリを利用するために24にしました。

android {
    compileSdkVersion 29
    defaultConfig {
        minSdkVersion 24
        targetSdkVersion 29
    }
}

執筆時点で最新のリリースバージョンは4.0.2なので、そちらを利用しています。

dependencies {
    ...
    implementation 'com.journeyapps:zxing-android-embedded:4.0.2'
}

2. QRコード読み込み

QRコード読み取り画面を起動

下記の処理を呼び出すことで、 QRコード読み取り画面を起動できます。

IntentIntegrator(this).initiateScan()

IntentIntegratorは、定義されているメソッドを通して各種設定値を変更することができます。
READMEに記載されているカスタマイズ例をKotlinで書くと下記のようになると思います。

IntentIntegrator(this).apply {
    desiredBarcodeFormats(IntentIntegrator.ONE_D_CODE_TYPES)
    prompt("Scan a barcode")
    cameraId(0) // Use a specific camera of the device
    beepEnabled(false)
    barcodeImageEnabled(true)
}.initiateScan()

その他のオプションや詳細については、下記のソースを確認してください。
zxing-android-embedded/IntentIntegrator.java at master · journeyapps/zxing-android-embedded · GitHub

読み取った結果の取得・表示

IntentIntegratorで起動したActivityから結果を受け取ります。
result.contentsで読み取った結果を文字列で取り出すことができます。
下記のコードでは読み取った文字列をトーストで表示しています。

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    val result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data)
    when {
        result != null -> Toast.makeText(this, result.contents, Toast.LENGTH_LONG).show()
        else -> super.onActivityResult(requestCode, resultCode, data)
    }
}

3.文字列からQRコード生成

事前準備

変換対象の文字列入力用EditTextと、結果表示用ImageViewを配置します。
(コードなし)

文字列をQRコードに変換して画面上にセットする

BarcodeEncoder().encodeBitmap()を用いて、文字列をQRコードに変換します。
sizeの500は適当な数値なので、用途に応じて変更してしまって大丈夫です。
EncodeHintType のMapを渡さずにマルチバイト文字をQRコードにすると、decode時に化けてしまうので注意。

private fun makeQRCode(contents: String) {
    val size = 500
    try {
        //QRコードをBitmapで作成(UTF-8を指定)
        val bitmap = BarcodeEncoder().encodeBitmap(
            contents,
            BarcodeFormat.QR_CODE,
            size,
            size,
            mapOf(EncodeHintType.CHARACTER_SET to "UTF-8")
        )
        //作成したQRコードを画面上に配置
        imageView.setImageBitmap(bitmap)
    } catch (e: WriterException) {
        throw AndroidRuntimeException("Barcode Error.", e)
    }
}

4.その他実装してみた機能

URLとして解釈できたらブラウザで起動

android.webkit.URLUtil.isValidUrl() で、文字列がURLとして解釈可能か判定できます。

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        val result = IntentIntegrator
            .parseActivityResult(requestCode, resultCode, data)
            ?.contents

        when {
            result.isNullOrEmpty() -> super.onActivityResult(requestCode, resultCode, data)
            URLUtil.isValidUrl(result) -> dialogAction(
                result,
                "読み取りURLをブラウザで開きますか?",
                "開く",
                ::openBrowser
            )
            else -> dialogAction(
                result,
                "読み取りテキストをクリップボードにコピーしますか?",
                "コピー",
                ::copyToClipBoard
            )
        }
    }

URLとして解釈できる場合に、URL型を渡して Intent.ACTION_VIEW を起動してやることで、
デフォルトに設定されているブラウザが立ち上がり、読み取ったURLを表示することができました。

private fun openBrowser(contents: String) =
    startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(contents)))

テキストをクリップボードにコピー

android.content.ClipboardManager を用いることで実現できます。
ClipData.newPlainText("", contents) の第一引数にはラベルを設定できるようですが、
ユーザーからはあまり参照されない部分なので、とりあえず空文字で埋めてます。

private fun copyToClipBoard(contents: String) {
    val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    val clip = ClipData.newPlainText("", contents)
    clipboard.setPrimaryClip(clip)
    Toast.makeText(this, "クリップボードにコピーしました", Toast.LENGTH_SHORT).show()
}

他のアプリからテキスト共有でインテント起動

他のアプリからのIntent起動を許容するため、下記の記述を追加します。 * app/src/main/AndroidManifest.xml

<intent-filter>
    <action android:name="android.intent.action.SEND" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="text/*" />
</intent-filter>

その上で、渡ってきたintentに対して下記のように記述してやると値を取り出すことができます。
intent.dataString で取れるよ、みたいなのを見たんですが、どうにもうまく取れなかったので、
実際は intent.getStringExtra(Intent.EXTRA_TEXT) にて取り出しています。

val intentString = intent.dataString ?: intent.getStringExtra(Intent.EXTRA_TEXT)

取り出した文字列をEditTextにセットして、QRコード生成処理を呼び出すことで、
他のアプリから共有された文字列からQRコード生成を行うような実装ができました。

// 外部から起動されて文字列が渡ってきていたらQR生成
val intentString = intent.dataString ?: intent.getStringExtra(Intent.EXTRA_TEXT)
if (!intentString.isNullOrEmpty()) {
    editText.setText(intentString)
    makeQRCode(editText.text.toString())
}

【Rust】Rust.Tokyo 2019に参加しました!#rust_tokyo

f:id:beatdjam:20191026195135j:plain

感想

10/26 に開催された、Rust.Tokyo 2019に参加してきました!
Rust.Tokyoは今回初開催で、参加する側としてもドキドキしながらだったのですが、
熱量の高いカンファレンスで、初心者の自分にも大きな学びのある時間でした。
キーノートの講演の段階ででWi-Fiが利用できなくなってしまったのと、
野良APをなるべく出さないようにという事だったのが大変でしたが、
たまたまUSBテザリングできる状態だったので、Twitter上での実況にも参加し、
たくさんのRustaceanの方と交流させていただきました!
参加者・登壇者・運営の皆様、素敵なイベントを本当にありがとうございました!

以下は、記憶が薄くならないうちに参加したセッションの簡単なメモなど。
覚えきれていないもの、抜け・漏れ・勘違いなどあるかもしれませんがご容赦ください。
資料は現時点で見つかったものだけ貼ります。

参加セッション

Rustで安全に実装するための心得

Osuke (@zoom_zoomzo) | Twitter speakerdeck.com

  • Rustは基本的には安全にかける言語だが、unsafeを用いるなどしてその制限を超えることができる
    • Rustが検知できる範囲を超えたときに起こりうる脆弱性の一部について紹介
      • 脆弱性自体の紹介となぜそれが起こるのか
      • 脆弱性を回避するための手法・ツール

エッジMLシステムをC/C++からRustへ移行した事例

tkato (@tkato) | Twitter docs.google.com

  • Deep Learningを含むシステムのアルゴリズム群をC++からRustに移行した話
    • 移行の背景とその手法
      • R&DをPythonで行っていたが、C++への移植が辛い
      • Rustは高速で安全なため、品質を向上させることができる
      • エコシステムが快適
      • 他の言語と結合しやすい口がある

Rustによる数値計算の現状と課題

てらモス♋ (@termoshtt) | Twitter docs.google.com

  • C++ Fortran MATLABなどが多い数値計算の世界でRustを使った話
    • LLVMによる高速化や、Traitなどの言語仕様によって、扱う土壌はできている
    • 公式のツールセットが充実しており、扱いやすい
    • 数値計算の分野での利用事例が少ないためライブラリが少ない
    • GPU・アクセラレータに対応していなくて辛い…

Web-based Data Visualization with Rust and WebAssembly

Yosuke Onoue (@_likr) | Twitter speakerdeck.com

  • Web上のデータビジュアライゼーションにWASMを利用した話
    • WebのUI・UXは研究者にも馴染みやすいので、Web上でGUIを構築している
    • Vue.js/WebGL/WASM(Rust)の構成
    • WASMの得意な大きい仕事はRustで、それ以外はJSの棲み分け
      • JSもきっちり書いたら早い
      • WASM呼び出しのコストがあるので、頻繁に呼び出すと遅い
      • 現状はJSよりもWASMの方がCPUのリソースを使えるので、そういうケースに良い
        • WASMからjsを吐かせることもできる

(ここから先、資料見つからなかったので言及少なめです)

いつの間にか社の中核製品にRustが使われていた件について

あずんひ | さいとう | ひーろー (@aznhe21) | Twitter

  • 会社の様々なRust採用事例について紹介
    • Rustのプロダクト採用理由は「趣味」
    • 依存ライブラリが多岐に渡る
    • OPTiMはブログやTwitterで様々な技術情報を発信しているので見てほしい

Rustを採用したサービス開発事例について

CADDi 高藤 謙佑さん(Twitter見つからなかったので会社サイトリンク貼ります)
CADDi Rust Engineering

  • Rustを採用した事例と教育、設計などについて
    • 採用する理由は安全性、パフォーマンス、エコシステム
    • 教育
      • まずはThe Book読んでもらう
      • 社内にTIPSやコードスニペットを蓄積、共有している
    • 設計
      • どういうときにどういう型を作るか、どうやって作るかなど
    • 会社のドメインに .rs をつけたかったのでつけた
      • セルビアドメイン

Holochain ~真の分散型P2PアプリをRustで作ろう!~

Tatsuya sato (@_tatsuyasato) | Twitter www.canva.com

  • Holochainのアーキテクチャとアプリケーションの作り方
    • Holochainとは?
      • ブロックチェーンとは異なる新しい分散型ネットワークのプロトコル
      • P2Pネットワーク上に構築され、中央サーバーを介さずに運用できる
    • アプリの使い方についてサンプルコードを見ながら解説
      • 前半の説明についていけない&後ろの席でコードが読み取れず理解できなかった…
      • 冊子をもらえたので家で読み直したい

Contributing to Rust

Florian Gilcher ∠(・.-)―〉 →◎ (@Argorak) | Twitter

  • Rustのコミュニティに参加してContributeしよう!という話
    • 「RustにContributeする」というのはコードを書くだけじゃない
      • 様々な役割があり、それぞれやることも、必要な時間も異なる
      • それぞれのポストについて、簡単な例を見せながら参加する例を紹介
    • コミュニティに参加するのも、抜けるのも簡単
    • Rustを広めることだってContribution!

というわけで、ざっくりですが参加したセッションのまとめでした!
改めて、みなさまお疲れさまでした。
次回も参加できることを願っています!ありがとうございました!