Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
技術的ミスと深堀り
Search
Recruit
PRO
March 03, 2025
Technology
310
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
技術的ミスと深堀り
2025/2/19に開催したRecruit Tech Conference 2025の雫石の資料です
Recruit
PRO
March 03, 2025
More Decks by Recruit
See All by Recruit
局所最適は悪ではない。壊れているのは指標です。量と質を同時に見る先行指標の設計
recruitengineers
PRO
3
1.4k
実体験から学ぶ分析エージェントの開発と運⽤
recruitengineers
PRO
9
2.7k
大規模フロントエンド開発におけるmonorepoという選択肢
recruitengineers
PRO
2
130
自律型 AI をセキュアに実装!Gemini と MIG で作る動的コード実行環境
recruitengineers
PRO
1
340
Google Cloud Next Tokyo 26登壇時のスクリプト
recruitengineers
PRO
0
360
つくって納得、つかって実感! 大規模言語モデルことはじめ ver2.0
recruitengineers
PRO
6
3.1k
ブラウザ研修 2026
recruitengineers
PRO
8
2.2k
事業価値と Engineering 2026年度版
recruitengineers
PRO
60
31k
トヨタ⽣産⽅式(TPS)⼊⾨
recruitengineers
PRO
3
1.6k
Other Decks in Technology
See All in Technology
分析作業をどこまで任せるか自分で決められる AIネイティブBI『Golden Analytics』が 良さげな話 /golden-analytics-is-ai-native-bi
shinyaa31
0
110
AIに任せられるFlutterコードベースを作る 〜仕様をコードで表し、ハーネスで守る〜
myohei
1
630
20261031_IoTLT_vol140_kitazaki_v1.pdf
kitazaki
0
170
自律的なチームを作るためにTechPMがやらないこと
ny7760
1
510
デザインレビューは自動化できるのか?─ Flutter × Figma で UI 品質保証を考える
techiro
2
790
AIがGISを代替する日:〜すべてをAIが創る時代に、私たちがFOSS4Gに関わる意味〜
lehupa
1
210
AIエージェントの監視、思考を見るか行動を見るか / Monitoring AI Agents: Thoughts or Actions
yusukeshimizu
1
120
Patterns in AI Driven Software Development
akosma
PRO
0
480
【Oracle AI SPOTLIGHT ウェビナー】事例から見る!なぜOCIが選ばれたのか ― AI時代のクラウド戦略を紐解く ―
oracle4engineer
PRO
2
150
20261016_Nagoya Tech Talk #4 データ活用のリアル AIも人も間違える
bessaralink55
0
160
AWS構成から考えるWebセキュリティ ― WordPressの構築経験から考える公開範囲と更新運用【JAWS FESTA 2026 in AKITA】
cscengineer
PRO
1
130
Don't write the architecture only in the prompt.
neohsu
0
310
Featured
See All Featured
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Into the Great Unknown - MozCon
thekraken
41
2.8k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.4k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
We Have a Design System, Now What?
morganepeng
55
8.4k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.7k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.6k
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
2
1.2k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
1
660
[RailsConf 2023] Rails as a piece of cake
palkan
59
7.1k
Transcript
技術的ミスと深堀り RECRUIT TECH CONFERENCE 2025 フロントエンドエンジニアが挑むプロダクト価値向上 雫石 卓耶 株式会社リクルート プロダクトディベロップメント室
雫石 卓耶 経歴 / Career 2021年に、リクルートへ新卒入社。社会人4年目。 HR系領域のWebフロントエンド / バックエンドエンジニア 現在は、『リクルートダイレクトスカウト』の開発メンバー
プログラミング。最近は、それ以外の趣味がないのが悩み 趣味 / Hobbies プロダクトディベロップメント室 アプリケーションソリューションユニット 横断エンジニアリング部 アプリケーションソリューショングループ
リクルートダイレクトスカウト • 転職スカウトサービス • 登録しプロフィールを入力すると、 企業 / エージェントからスカウトが届く • スカウトを受諾すると、企業
/ エージェント との、右のようなチャット画面が開く
開発メンバーの一員として • 普段から、技術的なミスをしてしまわないように注意している ◦ ミスが、求職者や企業 / エージェントの、利益や人生に影響して しまうかもしれず、それが怖いから
開発メンバーの一員として • 普段から、技術的なミスをしてしまわないように注意している ◦ ミスが、求職者や企業 / エージェントの、利益や人生に影響して しまうかもしれず、それが怖いから • しかし、システムからミスを完全に無くすのは難しいのも事実
Agenda 明らかになったミスに対して、私は深堀りを行うことがあります。どのような深 堀りを行ったのかについて、3つの事例をご紹介します。 • 事例1:データベースとnull文字 • 事例2:WebSocketとHTTP • 事例3:WebSocketのクローズ忘れ •
まとめ
事例1
事例1:データベースとnull文字 • 事例 ◦ チャット画面に入力されたメッセージをデータ ベースに挿入する際、null文字が含まれていて 失敗した • 補足 ◦
エラーの発生件数は1件だけ ◦ ユーザーへの直接の不利益は無し(メッセージ は通常通り見られる) • 対応 ◦ 入力内容からnull文字を排除する処理を追加
事例1の深堀り • 今回の件を単純化すると、反省点は「DBのvarchar(1)にどのような文字を挿 入できるか」がわかっていなかったこと • そもそも、「文字」はどのように表される? • DBの文字コード(charset)はUTF-8を使用
Unicodeと文字数 a U+61 コードポイント 各文字に一意なコードポイントが 割り振られている
Unicodeと文字数 a U+61 61 UTF-8 コードポイント バイト列 コードポイントをエンコードしてバイト列を得る。 バイト列は、ファイルへの読み書きや、通信などで使用される
Unicodeと文字数 a U+61 61 UTF-8 コードポイント バイト列 仮説1:バイト数を文字数としている?
複数のバイトにエンコードされる文字もある a U+61 61 UTF-8 コードポイント バイト列 あ U+3042 E3
81 82 UTF-8 1バイトに収まらない 複数バイトにエンコード
複数のバイトにエンコードされる文字もある a U+61 61 UTF-8 コードポイント バイト列 あ U+3042 E3
81 82 UTF-8 バイト数を数えると 「あ」は3文字になる
複数のバイトにエンコードされる文字もある a U+61 61 UTF-8 コードポイント バイト列 あ U+3042 E3
81 82 UTF-8 仮説2:コードポイント数を 文字数としている?
複数のコードポイントで表現される文字もある 文字画像の出典: https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:U845b-k.svg https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:U845b.svg 「かつしかく」 の1文字目 「かつらぎし」 の1文字目 U+845B U+E0101
U+845B U+E0100
複数のコードポイントで表現される文字もある 文字画像の出典: https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:U845b-k.svg https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:U845b.svg 「かつしかく」 の1文字目 「かつらぎし」 の1文字目 U+845B U+E0101
U+845B U+E0100 基底文字としては区別されない
コードポイントは、文字の同一性ごとに割り当てられる • Unicodeは、文字の形の詳細に立ち入らない ◦ 文字の形はフォントが決める • いろいろな「a」があるが、抽象的には同一の文字 • 同一の文字なので、おなじコードポイントが割り当てられている 表の出典:
Unicode® Technical Report #17: Unicode Character Encoding Model, https://www.unicode.org/reports/tr17/
複数のコードポイントで表現される文字もある 文字画像の出典: https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:U845b-k.svg https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:U845b.svg 「かつしかく」 の1文字目 「かつらぎし」 の1文字目 U+845B U+E0101
U+845B U+E0100 異体字: 見た目は異なるが意味は同じ文字 →同一な文字とみなされて同じコードポ イントが割り当てられた →賛否両論あったらしい
複数のコードポイントで表現される文字もある 文字画像の出典: https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:U845b-k.svg https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:U845b.svg 「かつしかく」 の1文字目 「かつらぎし」 の1文字目 U+845B U+E0101
U+845B U+E0100 異体字セレクタによって指定できる
複数のコードポイントで表現される文字もある a U+61 61 UTF-8 コードポイント バイト列 あ U+3042 E3
81 82 UTF-8 U+845B U+E0100 E8 91 9B F3 A0 84 80 UTF-8 コードポイント数を数えると は2文字になる
複数のコードポイントで表現される文字もある a U+61 61 UTF-8 コードポイント バイト列 あ U+3042 E3
81 82 UTF-8 U+845B U+E0100 E8 91 9B F3 A0 84 80 UTF-8 書記素クラスタを使うと、 「ユーザが認識する『文字』の境界」 を決定できる。 仮説3:書記素クラスタ数を 文字数としている?
どの仮説が正しい? • 仮説1:バイト数? • 仮説2:コードポイント数? • 仮説3:書記素クラスタ数?
実験してみた • 使用しているDBMSはPostgreSQL • varchar(1)の列を定義し、いろいろな文字を挿入してみた ◦ a(U+0061):挿入可 ◦ あ(U+3042):挿入可 ◦
(U+845B U+E0100):挿入不可 • →文字数は、コードポイント数でカウントされるようだ(仮説2が正しそう) • →varchar(1)には「コードポイント1つ分」が挿入できそうだ
すべてのコードポイントが挿入可能なのか? null文字(0x0000)以外のすべてのコードポイントを挿入するプログラムを作成 してみた Unicodeコードポイント(約110万個) 0 0x10ffff
すべてのコードポイントが挿入可能なのか? null文字(0x0000)以外のすべてのコードポイントを挿入するプログラムを作成 してみた →一部の範囲のコードポイントが挿入できなかった Unicodeコードポイント(約110万個) 0 0x10ffff
すべてのコードポイントが挿入可能なのか? Unicodeコードポイント(約110万個) 0 0x10ffff UTF-16のサロゲートペアに使用される領域。 単独では文字を表さない
すべてのコードポイントが挿入可能なのか? Unicodeスカラ値(USV) 0 0x10ffff
すべてのコードポイントが挿入可能なのか? Unicodeスカラ値(USV) 0 0x10ffff varchar(1)にどのような文字を挿入できるか? →USV - {0}の任意の値1つ(PostgreSQLでは)
追加の調査 • フロントエンドやバックエンドでは、バリデーション処理で文字数を数えて いる。このカウント方法はコードポイント数によるか? そうでない場合、 DBのカウント方式と差異があるが、おかしな挙動にならないか? • サロゲートペアが単独で入力されることはないか? された場合、DBではエ ラーになるが、システム全体としてはどうなる? →深堀りを行うことで、新しい観点が得られ、横展開調査ができた →結果としては問題なかった
事例2
事例2:WebSocketとHTTP • 背景 ◦ チャット機能では、メッセージサーバーとの通 信をWebSocketで実現している • 事例 ◦ リリース前試験において、リクルート社内の一
部のセキュリティが厳しい環境で、チャット機 能が使えない • 補足 ◦ その環境では、ファイアウォールにより、あら かじめ許可された種類の通信しかできない
チャット機能の通信を許可してもらうことに ファイアウォール担当「WebSocket通信を利用したいのですね。であれば、 HTTPの許可は不要ですかね? TCPポートだけ許可すれば良いですか?」
チャット機能の通信を許可してもらうことに ファイアウォール担当「WebSocket通信を利用したいのですね。であれば、 HTTPの許可は不要ですかね? TCPポートだけ許可すれば良いですか?」 私「はい……おそらくHTTPの許可は必要ないと思います……? TCPポートは 443番を使用しているようなので、許可していただけますか……?」
チャット機能の通信を許可してもらうことに ファイアウォール担当「WebSocket通信を利用したいのですね。であれば、 HTTPの許可は不要ですかね? TCPポートだけ許可すれば良いですか?」 私「はい……おそらくHTTPの許可は必要ないと思います……? TCPポートは 443番を使用しているようなので、許可していただけますか……?」 →TCPだけ許可してもチャット機能は使えず
チャット機能の通信を許可してもらうことに ファイアウォール担当「WebSocket通信を利用したいのですね。であれば、 HTTPの許可は不要ですかね? TCPポートだけ許可すれば良いですか?」 私「はい……おそらくHTTPの許可は必要ないと思います……? TCPポートは 443番を使用しているようなので、許可していただけますか……?」 →TCPだけ許可してもチャット機能は使えず 私「あっ、やっぱりHTTPも関係するみたいなので許可をお願いします……」 →ようやくチャット機能が利用可能に
私は、WebSocketのことを 何もわかっていない……
私の趣味 • プロトコルスタックの自作 ◦ イーサネット〜TCPまでの、C言語での簡易的な自作実装はすでにあっ た • イーサネット〜WebSocketまでを(簡易的にでも)全部実装すれば、理解を 深められるかもと思った •
送ったデータをそのまま返す、WebSocket Echoサーバーを実装してみる
実装したWebSocket Echoサーバーの動作
TCP接続をパッシブオープン • クライアントからのWebSocketリクエストを待ち受け
クライアントからの最初のリクエスト • GET / HTTP/1.1 • Host: xxx • Upgrade:
websocket ◦ WebSocket通信にアップグレードしたいと言っている • Connection: Upgrade • Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== ◦ 次に応答を返すために必要 • Sec-WebSocket-Version: 13
サーバーからのレスポンス • HTTP/1.1 101 Switching Protocols • Upgrade: websocket •
Connection: Upgrade • Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= ◦ 先ほどのSec-WebSocket-Keyに、仕様で決まっているマジックナンバーを追 加し、sha1をとって更にbase64エンコードしたもの ◦ 正しい手順でWebSocket要求が受け入れられたことをクライアントに示す →WebSocket接続完了 →先ほどのファイアウォール問題で、TCPだけでなくHTTPも許可する必要があった理由
ここから先はバイナリで通信する • 以下のような形式のバイナリデータがTCPソケットで送られてくる • 仕様通りにフラグやマスキングの処理を行うと、ペイロードが得られる • 同じようにして、ペイロードをそのまま返却すると…… 出典:FETTE, Ian; MELNIKOV,
Alexey. Rfc 6455: The websocket protocol. 2011.
動作した! →うれしい
事例3
事例3:WebSocketのクローズ忘れ • 事例 ◦ チャット画面を閉じた後も、WebSocketの接続が残り続けてしまう場合 がある ▪ システムに余分な負荷がかかってしまう • 原因
◦ WebSocketのクローズ処理の実装漏れ • 対策 ◦ クローズ処理を追加する
チャット画面を開閉してChrome DevToolsの表示を確認 クローズ処理の追加前後で、通信状況を比較してテスト クローズ処理追加前 クローズ処理追加後 →この表示だけを証拠に「接続が閉じた」と判断するのは心もとなかった
WebSocketについて学んだ今なら • 「WebSocketの通信=TCPソケット」とわかっている ◦ →OSのTCPスタックに問い合わせれば状況がわかる ◦ ESTAB状態のソケット数の増減を調べることで、確実にWebSocketがク ローズされていることを確認して、修正をリリースできた • 学んでいなかった以前の私なら「そもそもWebSocketの『接続』とは何だろ
う……?」となっていた気がする
まとめ • どの事例も、修正自体は軽微なもの
まとめ • どの事例も、修正自体は軽微なもの • しかし、そこから深堀りすると、物事の仕組みがわかって楽しい ◦ →私の楽しみ
まとめ • どの事例も、修正自体は軽微なもの • しかし、そこから深堀りすると、物事の仕組みがわかって楽しい ◦ →私の楽しみ • それが、類似の問題を防いだり、確実に解決したりすることにつながる ◦
→サービスの利用者、求職者や企業 / エージェントのため
まとめ • どの事例も、修正自体は軽微なもの • しかし、そこから深堀りすると、物事の仕組みがわかって楽しい ◦ →私の楽しみ • それが、類似の問題を防いだり、確実に解決したりすることにつながる ◦
→サービスの利用者、求職者や企業 / エージェントのため • 「私の楽しみ」と「サービス利用者のため」を両立させていきたい