Menu

はてなのサマーインターンシップが最高だった

Published:
🏷️
Internship k8s gRPC
技術のシャワーと絶品うな重。僕のエンジニア観をぶっ壊した、はてなサマーインターンが最高すぎたのでその経験を共有したいと思います。
目次
  1. 概要
  2. 対象読者
  3. 講義
    1. WebAPI
    2. フロントエンド
    3. RDBMS
    4. AIエージェント
    5. コンテナ・コンテナオーケストレーション
    6. クラウドと運用
    7. チーム開発
    8. プロダクトマネジメント
    9. セキュリティ
    10. ライティング
  4. 課題
    1. markdownパーサの実装
    2. 要約サービスの実装
  5. おいしいご飯
  6. オフィスの雰囲気 (一番大事)
  7. 感想

概要

はてなのサマーインターンシップ2025に参加してきました。

このインターンシップは、前半と後半に分かれており、前半は京都オフィスでの講義、後半はオンラインで実際に動いているプロダクトの開発を行うという形式でした。

後半の方も参加したかったのですが、予定が合わず、今回は前半の講義のみの参加となりました。ですが、1週間とは思えないほど内容が濃く、 非常に充実した時間を過ごすことができたので、その内容を共有したいと思います。

対象読者

  • はてなのサマーインターンに応募しようか迷っている人
  • はてなのサマーインターンの前半講義だけに参加するかどうか迷っている人
  • はてなという企業がどんな企業なのか気になっている人

講義

前半パートでは、講義と、講義で学んだことを活かした課題に取り組むという2つのパートに分かれていました。

まずは、それぞれの講義内容について簡単に振り返ってみようと思います。

WebAPI

この講義では、Webに関する基礎的な知識を学びました。特に、HTTP/URLといったプロトコルについて、ヘッダーやボディ、クッキー、キャッシュなど 普段なんとなく使っているものの、詳細に理解できていなかった部分をしっかりと学ぶことができました。

その後、HTTP/2、HTTP/3についての説明があり、HTTP/1.1の問題点と、それをどのように解決しているかを学びました。

最後に、APIについての説明があり、REST API、gRPC、GraphQLのそれぞれの特徴と、基本的な使い方を学びました。

1つ目の講義から内容が盛りだくさんで、HTTPについては今まで使っていた技術を深く知る良い機会になり、後半のgRPCやGraphQLの講義では 知らないことがとても多く、RESTでは簡単に実現できない色々な機能があり、今後の開発に活かしていきたいなと感じました。

フロントエンド

この講義では、JavaScriptとTypeScript、Reactの基本的な文法と、ビルドツールについての紹介、フロントエンド開発における心構えについて学びました。

普段よく書いているJavaScriptやTypeScriptですが、意外と知らないことが多かったです。

割と場当たり的に適当にフロントエンドのコードを書いていた節があったので、これを機にしっかりと学び直して、 保守性・柔軟性のあるより良いコードを書けるようになりたいと思いました。

RDBMS

この講義では、RDBMSの基本的な概念と、SQLの基本的な文法、テーブル設計、トランザクション、パフォーマンス(インデックス)を学びました。

この分野は割と経験があったので、基本的な部分は理解できているつもりでしたが、特にトランザクションでは4つの分離レベルと 発生してしまう問題(ダーティリード、ノンリピーダブルリード、ファントムリード、書き込みスキュー)については全く知らなくて、 実装するアプリケーションの仕様と、パフォーマンス要求に応じて適切な分離レベルを選択することが重要だなぁと思いました。

AIエージェント

この講義を題材に選ぶのは非常にセンスが良いなぁと思いながら受講しました。(偉そう)

講師の方は、よくブログを拝見させていただいているazukiazusaさんで、cloudflare tech talksでも見たvibe codingを再度見ることができました。 具体的なvibe codingのtips等もあり、ドキュメントを育てていくというのは重要だなぁと思いました。

どこかのツイートにありましたが、1つのリポジトリにプロダクト開発のコンテキスト全てがある状態が今後は望ましいなぁと思いました。

個人的には、vibe codingすげぇ〜、っていって、本当に何も考えずコーディングをすることには両手を挙げて大賛成というわけではなく、 どちらかというと慎重派で、コードの責任は人間が取るべきだと思っていました。

本講義も、そこに触れられており、妄信的にAIに頼るのではなく、批判的にAIの出力を見ることの重要性についても述べられていて、 普段自分が感じている危機感について、自分の中で整理することができ、とても良かったです。

また、AIの登場により、今後エンジニアがどのような役割を担っていくかについても触れられていて、「コードを書く」から「タスク管理」にシフトしていくということを 示しつつも、コードを書く手段が変わっただけで、本質的に設計や技術の選定などのエンジニアリングは変わらないということ述べられていてとても納得感がありました。

コンテナ・コンテナオーケストレーション

この講義は、自分が一番楽しみにしていた講義でした。

なんとなくk8sやってみたいなぁ、自宅サーバー始めてみたいなぁと思いつつ手を出せていなかった領域だったので、とても勉強になりました。

コンテナの方では、コンテナの基本的な概念について学び、Namespaceやcgroup、whiteout、高・低レベルランタイムなど、普段Dockerfileを使って 適当にECSやLambdaにデプロイしていた自分にとっては、全然知らないことばかりでした。

また、Dockerfileの構築についてのプラクティスの説明もあり、今後の開発にも活かしていこうと思いました。

k8sの方では、k8sが実現する機能(セルフヒーリング、オートスケーリング、負荷分散)を学んだ後、cluster、control plane、node、pod、 service、ingressなど、基本的なモジュールについて学びました。マニフェストの書き方についての説明はなかったですが、本講義の内容を 理解できていればなんとなく読めるようになっていると思います。

最後のハンズオンでは、後半の課題で使うk8s環境の立ち上げを行いました。 Deployment、Service、kustomizeを書いたらシュッとpodが立ち上がって通信できるようになるのは感動しました。

クラウドと運用

この講義では、現代では主流になっているクラウドインフラの運用・アーキテクチャについて学びました。

特に、高可用性を実現するための分散アーキテクチャをどのように実現していくかをWebアプリケーションの3層構造を例に、 ステップバイステップで説明されていて、とてもわかりやすかったです。

特にDBがボトルネックになるというのは普段の開発から実体験として感じており、スケールアップ以外の方法でも負荷分散ができるんだなぁ(レプリケーション)というのが 面白かったです。CQRSとかやってみたいですね。

また、後半ではIaCによるインフラ構築の自動化とモニタリング・オブザーバビリティ、DevOps、SREについて学び、機能面以外にも、サービスを リリースした後にどのように運用していくかについても学ぶことができました。

チーム開発

この講義では、普段なかなかフォーカスすることのないチーム開発を円滑に行うための技術について学びました。

講義というよりもインタラクティブに、scrapboxにコメントを書き込みながら進めていく形式でした。 特に、紹介された書籍やリンクがとても良質で、今後エンジニアリングを仕事として、ソフトスキルは重要だと思うので、 ぼちぼち読んでいこうと思います。

後半は、紙とはさみだけを使ってできるだけ高く積み上げるという課題を、実際のアジャイルの手法に則って、 目標値と実際の値の割合を出したり、振り返りをしながらゲームをしました。楽しかったです。

プロダクトマネジメント

この講義では「プロダクトマネジメント」とは何たるか??ということを学びました。

特に印象に残ったのは「物事を正しく行うよりも、正しいことを行う方が重要」という言葉でした。 冒頭で、プロダクトとは、個人や団体に価値を提供するものであり、その手法の清濁よりも、ユーザーに価値を届けることが 最重要であるということを再確認できました。

プロダクトマネジメントは、エンジニアの自分からすると、キャリアパス上でもまだ遠い未来の話かなぁと思っていましたが、 AIエージェントの講義でもありましたが、今後はAIをマネジメントしたり、技術的な知見を持ったビジネスパーソンが 求められるようになると個人的に感じています。

そのために、講義の中であった課題の見つけ方、MVPを用いた解決策の実現方法などをしっかりと実行していけるように、 今後のキャリアに活かしていきたいと思いました。

セキュリティ

この講義も楽しみにしていた講義の1つで、最近色々なメディアでAIコーディングの文脈でセキュリティの話題が上がることがよくあり、 セキュリティを学び直さないとなぁと思っていました。

講義は、色々なセキュリティ脆弱性・攻撃を例として挙げていきながら、それぞれの脅威をどのように防ぐかという形式で進んでいきました。 かなり自分の作っているプロダクトの中でも危ないなと思う部分が多くあり、特にフォームは脆弱性の塊だなぁと思い、このサイトのフォームも CSRFトークンなりを使ってちゃんとセキュリティ対策を行わなきゃなぁと感じました。

また、iframeやXSSなどの話題もあり、最近話題になっていたユーザーが書いたコードを実行するようなアプリケーションで 注意すべき点についても学ぶことができました。

ライティング

最後に、はてなのインターンシップでユニークなライティングの講義がありました。

この講義では、ブログの書き方や、読み手を意識した文章の書き方について学びました。

エンジニアの仕事をしていく上で、インプットを増やすためにもアウトプットをする習慣をつけていくことが重要だなと感じました。

課題

後半では、前半の講義でやったことを活かして、ミニマムで動いているブログサイトに機能追加を行いました。

必須課題と発展課題に分かれていて、必須課題ではmarkdownのパーサの実装(見出し記法、リンク記法、リスト記法)を行い、 発展課題では、自由に機能追加を行えるのですが、自分はせっかくならk8sやgRPCを使ってみたいと思い、要約サービスの追加を行いました。

はてなサマーインターンシップのk8sアーキテクチャ

markdownパーサの実装

まずは最初に、必須課題のmarkdownパーサの実装を行いました。

この課題は、既存のパーサライブラリを使っても自前で実装しても良いのですが、言語処理が好きな自分は自前で実装することにしました。 大体、半分強くらいの人がライブラリを使っていて、残りの人も、大体は正規表現で抜き出すという手法を採用していましたが、自分は 字句解析からASTを構築して、HTMLを生成するという手法を取りました。

求められている機能に対して、少しオーバーな実装になってしまいましたが、言語処理を復習する良い機会になりました。 実装にあたっては、昔読んだ以下の書籍の自分の実装を参考にしました。

また、発展課題の例として、独自記法を追加するというのもあり、せっかくlexerから書いたので何かしら実装したいと思い、xで囲まれた部分がXっぽいUIでレンダリングされる記法を追加しました。 締め切り最後に急いで作ったので少し微妙ですが、面白い機能を実装できて良かったかなと思っています。

できたら時間表示は逐次取得したり、ユーザー名の部分はgRPCでサーバーから取得とかができたら良かったなぁと思います。

  • 入力
# This is twitter test
x
# this is twitter code
- list
- nested
- list
[Google](https://google.com)
x
# this is second tweet
x
ついったーぽい
## 文章を
- ここで書ける
- 嬉しいな
- 嬉しいな
x
  • 出力
はてなサマーインターンシップのXブロックレンダリング

要約サービスの実装

次に、発展課題で、要約サービスの実装を行いました。

設計

要件としては以下の通りです。

  • ブログが投稿されたら要約文を生成する
    • gRPCを用いてブログサービスから要約サービスに要約をリクエストする
  • 要約はGemini APIを用いて生成する
  • 要約は非同期で行う

かなり大きめの実装を行わないといけなかったため、メンターさんと設計について相談しながら進めました。 k8sもgRPCも触ったことがなかったのでなかなか大変でした。

ちなみに、要約を格納するテーブルスキーマを以下のように定義したのですが、メンターさんから鋭いコメントがついていました。

CREATE TABLE `summaries` (
`id` BIGINT UNSIGNED NOT NULL,
`entry_id` BIGINT UNSIGNED NOT NULL,
`summary` TEXT NOT NULL,
`status` ENUM('processing', 'fail', 'success') NOT NULL DEFAULT 'processing',
`created_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
`updated_at` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY (`id`),
UNIQUE KEY (`entry_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

enumを処理中・完了・失敗の3パターンで持っていたのですが、処理前を加えるともっと柔軟でスケールできるサービスになるという アドバイスをいただきました。

自分のコメントにもありますが、スパイクしないように処理数をコントロールできるという観点で、処理前のステータスを持たせたらもっと 違う実装になってたかなと思いました。

カラム1つ、enumの要素1つで一気に柔軟性が増すのは面白いなぁと思いつつ、メンターさんはすごいなぁと思いました。

はてなサマーインターンシップのGitHubコメント

要約サービスの実装

まず、gRPCのスキーマを定義して、コードを自動生成しました。

syntax = "proto3";
option go_package = "github.com/hatena/Hatena-Intern-2025/pb/go/summarizer"; // fake
package summarizer;
service Summarizer {
rpc Summarize(SummerizeRequest) returns (SummarizeReply);
}
message SummerizeRequest {
// markdown形式のテキスト
string src = 1;
// 生成する要約のエントリID
uint64 entry_id = 2;
}
message SummarizeReply {
// ワーカーのレスポンス(要約タスク自体はワーカー内で非同期で実行される)
string response = 1;
}

せっかくなので、gRPCの良さを活かして、要約サービスはPythonで実装しました。 Gemini APIを用いた実装はかなり慣れていたので、手早くささっと実装しました。

ここで、工夫として、多くのリクエストに耐えるために、grpc.aioを用いて非同期でリクエストを捌きました。 このサービスはGemini APIへのリクエスト・DBへの書き込みなど、ほとんどがI/Oバウンドな処理なので、そこそこなリクエストが来ても耐えられると思います。

k8sでのデプロイ

次に、k8sでこのサービスをデプロイしました。わかりやすいマニフェストがすでにあったので、それを参考にしながら Deployment、Service、kustomizeを作成しました。環境変数の管理については、ConfigMapGeneratorを使って、ファイルからAPIキーを読み取る形式をとり、 そのファイルを.gitignoreして管理しました。

少し詰まったところは、gRPCのヘルスチェックを既存のマニフェストでは追加していて、それを忘れていて自分のpythonのgRPCに追加するまで 少し手間取りました。以下の記事を参考にさせていただきました。

無事k8s上からgRPCサーバーのポートをフォワーディングして、protocでつついて、要約サービスからDBに書き込みが行えるようになりました。

Goのブログサービスからの繋ぎこみ

ここが一番大変だったかもしれません。

既存のブログサービスはシンプルながらもかなりコード量が多く、書き方も自分の知らない書き方が多く、コードリーディングに時間がかかりました。 ですが、その分、コードへの理解が深まりましたし、書き方もとても参考になるものが多かったです。

詳細な処理の流れは以下です。

  1. ブログのエントリのレコードを新規作成する。要約文はから文字列を入れておいて、ステータスはprocessingにする
  2. ブログのエントリが新規作成(編集)されたら、gRPCで要約サービスにリクエストを送る
  3. 非同期で実行を行うので、リクエストが受理された旨がレスポンスされる
  4. 要約サービスではGemini APIを用いて要約文を生成する
  5. 要約に成功したら、要約文を書き込み、ステータスをsuccessに更新する(レートリミット等で失敗した場合はfailに更新するエラーハンドリングを入れてます)
  6. DBを見に行って、要約文が入っていたら表示を行う

かなり良い感じの設計かなと我ながら思っています。

ちょっと詰まったところとしては、なぜか作成したエントリのIDと、要約サービスが受け取るIDが違うという問題があり、 ビルドエラーも出ないし、どこかでエラーが吐かれることもないのでデバッグに苦難しましたが、最終的には、IDをuint64で定義していたのに .protoではint32で定義していたため、リクエストされるときに値が詰められていました。

そのほかにも色々と苦労して、やっと要約サービスが動くようになりました。(ニチャア)

おいしいご飯

はてなインターンシップは最高で、もちろん講義も最高だったのですが、ご飯がとてもおいしかったです。

昼食は毎日美味しいご飯が出てきますし、夜ご飯も、毎日京都の美味しいご飯に連れて行ってもらいました。(毎回、社員さんにご馳走になりました)

はてなサマーインターンシップのうなぎ弁当

ほかにも、オフィスにピザやお寿司を頼んで、みんなでフリーのビールやお酒を飲みながら雑談や、モブプログラミングをする時間があり、 毎日楽しくて、気づいたら夜遅くまでオフィスに滞在していました。

オフィスの雰囲気 (一番大事)

このブログで最も伝えたいのはこの部分です。

総じて、はてなのオフィスの雰囲気はとても良かったです。

こんなにも自由なエンジニアの働き方があるのか、こんなにもエンジニアが生き生きと働ける会社があるのか。。。と驚きました。

基本的にリモートの人が多いと思うのですが、インターンのために講師の方やメンターの方が出社してくださり、気さくに話しかけていただいたり、 質問に答えてくださったりと、非常にフレンドリーな雰囲気でした。

終業後は、いきなりオフィスでビールを飲み出す人がいたり、カービィのエアライドをしている人、雑談をする人、お酒を飲む人、プログラミングをでかディスプレイで始める人など、 それぞれが好きなことをしていて、オフィスの雰囲気もとても良かったです。

ふとした瞬間に、技術談義が始まり、偉い人もそうでない人も関係なく、わいわいとしているのはまるで研究室みたいだなぁと思いました。 気になったらすぐに手が動いて、ブラウザを介してスイッチのコントローラから音楽を奏でたり、QRコードおみくじを作ったりと、 エンジニアが好きなことを好きなようにやっているのがとても印象的でした。

感想

こんなに長いブログを書いてしまうほど、1週間が非常に充実していて楽しかったです。

本当にメンターさんが優しくて、業務時間外も色々なところに連れ出してくれたり、丁寧にレビューをしてくれたり、とても感謝しています。

自分は、ほかにも数社インターンを受けていますが、こんなに ホスピタリティが高くて、エンジニアが生き生きと仕事をしている環境は、 明らかに良い意味で異質で、こんなところでエンジニアができたら楽しいだろうなぁと思いました。

こんなブログでは形容できないくらい、はてなのオフィスは雰囲気もよく、環境も良かったです。 ぜひ、はてなのインターンシップに参加して、このはてなのエンジニアリングの文化を体験してみてほしいです。