新卒2年目がスモッカの高速化に成功した話&これからの設計について
目次
1. はじめに
自己紹介
こんにちは。
住まいDiv.で、賃貸情報サービス「スモッカ」のエンジニアをしている、新卒2年目の山本と申します。日頃は、サービスのバックエンドを中心に、改修や開発を行っています。
スモッカでは最近、私が中心となってサービスの速度改善を行い、事業の成長につながりました。
本記事では、そのことについて書いていきます。
本記事で伝えたいこと
- サイト速度を改善することで事業の成長を促す
- どのような流れで速度の改善をすることになったのかについてと、目標の設定の仕方、経緯などを書いています。
- どのようにして速度改善をしたか
- 実際にどのような技術的手法を使って速度の改善をしたのかを書いています。思考の経路、プロファイラーの種類、具体的な改善手法についても書いています
- 低速になった根本的な原因
- 低速になるようなコードが多数生まれてしまう原因について考え、普段の開発の習慣やコードを書くときに考えるべきことなどを書いています。
- 速度改善のプロジェクトから見える、じげんでの働き方
- このプロジェクトから見える、じげんの環境や職場の雰囲気などについて書いています。
2.サイトの速度を解決することで事業の成長を促す
事業課題
まず、私が開発を担当している「スモッカ」では、事業課題として、社内集客目標との乖離が発生してきているという事象がありました。
調査を進めると、スモッカにおいて物件詳細ページにおけるセッション低下が主要因であるという結論が出ました。
セッションとは以下の通りです。
一般的にユーザーはGoogleなどの検索エンジンや他サイトからのリンクを経てサイトに流入後、数ページを閲覧してまた別のサイトへと離脱していきます。 この流入から離脱までを1回としてカウントしたのが、Googleアナリティクスで表示されている「セッション」という数字です。
引用 : 正確なアクセス解析に欠かせない「セッション」正しく理解できていますか?
平たくいうと、詳細ページがユーザーに見られる数が減ってきていたということです。
課題解決のための速度改善
その原因の深掘りをすると、物件詳細ページのディスカバーが減っておりました。ディスカバーというのはGoogleのクロールbotに見られているURLの数のことで、これが落ちるとスモッカのページが検索結果に表示されにくくなります。つまりオーガニック経由で流入するユーザーが減少してしまいます。
これらのディスカバーの悪化前後の理由をさらに探ってみると、サイトのレスポンス速度が悪化しているタイミングとほぼ一致しており、ここでようやく「おそらく速度が原因で売り上げが下降しているのだろう」という仮説が立ちました。
実際に、サイトのレスポンス速度が低下すると、botのクロールバジェットを使い果たしてしまい、ディスカバーのURL数が減少するというのは以下で言われていることです。
Googlebot のクロールの割り当てについて | Google 検索セントラル ブログ
当時の現状と目標
現状の把握
実際に速度の改善をしていく上で、現状のスピードと、目標として今後どのくらいのスピードを出したいのかの洗い出しをはじめました。私はバックエンドエンジニアとして仕事をしているので、サーバーサイドのレスポンススピードの改善を中心に現状の調査や、目標を立てはじめました。まず現状の調査をGoogle Search Consoleでしましたが、おおよそ1200~1300ms程度でした。
目標
現状把握はできたので、次は目標です。レスポンススピードに関しての目標の立て方は、アプリの現状や社内リソース、技術力、情勢などにもよると思います。参考ですが、Google自身の推奨は以下のようになっています。(以下はモバイルについてのドキュメント)
Mobile Analysis in PageSpeed Insights | Google Developers
Google曰く、ページがロードされてからユーザーがコンテンツの操作(つまりタッチしたりスクロールできるまでの操作)ができるまでには、1秒以内の遅延が望ましいということでした。例えばスマホだと4G通信で100ms、DNS lookupによるIPアドレスからホスト名(google.comなど)へのドメイン解決などの必要な処理を考慮して逆算すると、純粋なアプリ側のサーバーレスポンススピードの最終目標は200ms以下とGoogleは推奨しています。
現状1200ms以上で、推奨が 200ms以下となると、これは6分の1のスピードでしたので、これをいきなり達成するのは目標が高すぎるということもあり、まずはもう少し目標を現実的な位置に設定しなければなりません。まずは1000msを切ることを目標に設定しました。
プロジェクト発足
現状のスピードが推奨から大きく外れていることや、「スモッカ」が既に10年近く存在した肥大したコードでできているアプリであることからも、簡単な作業で早くなるとは考えにくく、私が指揮をとり、チームとして作業を進めていくことになりました。
目標到達(400msの改善)
今回のプロジェクトの結果として、現在では800ms前後まで速度を下げることができました。速度改善が成功したことで、当初の課題であったクローラーのディスカバー数が上昇しました。それによりセッション数も上昇し、売り上げにも大きく貢献できたので非常に良い結果が出ました。
以下ではこれらのプロジェクトの経緯と、どんなことを考えて速度の低下をしたかの話を以下でしたいと思います。
3. どのように速度改善をしたのか
低速の原因調査と改善手法の検討
改善箇所の当たりを付ける
速度改善をする上で、まずはボトルネックの調査をしなければなりません。
先ほども述べた通り、サーチコンソールなどで出てくるレスポンスのスピードは、クローラーによって測定されています。クローラーが巡回するということは、URLの存在数が多いディレクトリは、アクセス数が多くなります。レスポンススピードは巡回した全URL平均から算出されるので、URLの存在数が多いディレクトリのレスポンスの比重が高くなります。
もう少し平たく言うと、アクセス数の多い、サイトのコア機能があるページの速度をあげると、サイトの高速化が達成される可能性が高いということです。これがわかったことで作業のスコープを縮めることにも役立ちました。
具体的に今回のケースでの話をします。私の作っているアプリ「スモッカ」では物件の詳細画面が最もユーザーに使われているメインコンテンツ且つ、最も遅いレスポンスを返すページでした。つまりここに関するコードの品質を改善すれば速度が上がっていくことがわかります。
速度改善の定石
ボトルネックのディレクトリ箇所はわかったので、次はもっと細かいコードベースでのボトルネックを探します。速度改善の定石はいくつかあり、それらに該当するコードがないかを検討をつけて探すのが良いと思いました。定石を調べるのに参考にした記事などを以下に貼っておきます。
まとめると、バックエンド(サーバーサイドのレンダリング)の定石としては以下のようなものがあるようでした。
- N+1の解決
- 外部API通信を減らす
- キャッシュの利用
コードをとりあえず読んでみるのはおすすめしない
これらに該当するところがないかを探しすために、最初はとりあえずコードを読んでみましたが、非常に難航しました。どこに何が書かれているのかがなかなかわからないのです。10年近く、あまりリファクタリングをされずに書かれているコードを読むのは難しく、時間がかかるものでした。(もちろん過去の開発者への敬意は忘れてはいけません。負債が貯まるのはしょうがないことです。)
定石の中でも特に、「Solr(弊社の使っている全文検索エンジンのソフトウェア Apache Solr)やSQLのN+1問題が原因なのではないか?」と言う話がチーム内で出ていたので、N+1を中心にみていくことに決めました。1週間ほどコードを読みましたが、プロジェクトが本格的に始まる前に、メンバーがある程度N+1の箇所を直してくれていたこともあり、一見それに関してはあまり問題はなさそうに見えました。しかし、それでも速度としての結果はあまり出ておらず、New Relic(ソフトウェアの構築に役立つオブザーバビリティプラットフォーム)などをみても、まだまだ異常な数のMySQLやSolrへのリクエストがありました。この辺りで、ただコードを読んで直す方法でははいつまでたっても改善しないと考え、方向転換を決めました。
プロファイラーを入れてみる
ここで改めて速度改善のテクニックを調べてみると、プロファイラーが速度の測定に有効だという情報を得ました。インターネットはもちろん、上司や同僚からもそのようなアドバイスをいただいたので、いくつかRubyで使われる代表的なプロファイラーとそれらの機能を調査してみました。以下に代表的なプロファイラーを紹介します。
以下のように、プロファイラーがメソッド単位で、詳細を出してくれます。
$ ruby -rprofile example.rb
% cumulative self self total
time seconds seconds calls ms/call ms/call name
68.42 0.13 0.13 2 65.00 95.00 Integer#times
15.79 0.16 0.03 5000 0.01 0.01 Fixnum#*
15.79 0.19 0.03 5000 0.01 0.01 Fixnum#+
0.00 0.19 0.00 2 0.00 0.00 IO#set_encoding
0.00 0.19 0.00 1 0.00 100.00 Object#slow_method
0.00 0.19 0.00 2 0.00 0.00 Module#method_added
0.00 0.19 0.00 1 0.00 90.00 Object#fast_method
0.00 0.19 0.00 1 0.00 190.00 #toplevel
私はあまり調べてないのですが、ドキュメントが充実していそうです。
1. のProfileに似ていて、メソッド単位で詳細を出してくれます。
1行1行の速度がでるのでRuby単位のパフォーマンスチューニングをするのに向いています。
おそらく一番有名なプロファイラー。
SQLやAPI通信でどれくらい時間がかかったのか、このページを出すまでにどんなコードを通ったかなど、包括的かつ詳細なUIで出してくれる優れものです。
どれもそれぞれにいいところがありますが、私は、最後のrack-mini-profiler選定しました。プロファイラーで、「どのコードをどの順番で」「どんなパフォーマンスで」通っているかがわかってからは、速度改善のプロジェクトも一気に進みはじめました。今まで見えなかった悪さしているコードが見えてきたのです。
速度改善の手法
原因の発見、好循環の始まり
低速の最大の原因は、まとまりがない様々なファイルでSolrのリクエストが呼ばれていたということでした。様々なファイルでSolrが呼ばれているので、1ファイルの中ではダメなコードに見えないのです。しかし全ての処理を俯瞰して見てみると、いらないリクエストだらけということが見えてきました。これがわかってからは比較的スムーズにことが進んでいきました。具体的には以下のような流れでプロジェクトが進んでいきました。
速度改善できそうな細かいissueを私が作成する
↓
メンバーの方々にそれぞれの依頼をして、リファクタリング実装をお願いする
↓
実装してもらっている間に、私が次の改善点を探す
↓
依頼して上がってきたissueのPRを私がレビューする
↓
上に戻る
と言った流れでサイクルができ、効率的な改善が進みました。またこの頃になると私1人で使っていたrack-mini-profilerの使い方を、普段は私の指示のもと動いてくれていた メンバーの皆さんにも共有しました。そうすることでメンバー側からも改善案を出していただけるようになり、より良いサイクルに入ったと思います。
具体的な改善手法
具体的には、いらないSolrリクエストの削除、比較的静的な内容のSQLやAPIのキャッシュ化、リクエストの並列処理などを行いました。これらをどう達成するかなどの記事は既に多数存在すると思うのでここでは省略します。さらに、(これはソフトウェアエンジニアの直接スキルとは関係ないかもしれないのですが)あまりUXとして価値がないのに、非常に重いリクエストを必要とするコンテンツを、マーケターと相談して削除したりなどもしたりしました。
結果的に速度は順調に上がっていき、最終的に800ms程度までになりました。
4. 低速になっていったより根本的な原因
そもそもなぜ煩雑なコードになったのか
このように、一旦は速度改善は成功したわけですが、1つまだ私には気になるところがありました。根本的に「なぜこのような、非常に煩雑で読みにくいコードが書かれてしまったのか」ということです。
もちろん負債というのは溜まっていくものなので、仕方のない部分もあります。しかし、煩雑なコードが一旦生まれてしまうと、開発者は読む気が失せてしまいます。そうなると、より適当なコードをなんとなく動くように追加してその場しのぎの開発をしがちです。このループが無駄なリクエストを生み、さらに、「無駄なリクエストが存在するという事実」にすら気付けないレベルにまでアプリケーションは汚染されてしまいます。これはさまざまな本や記事であげられている例ですが「窓ガラスの割れたり散らかったりしている家に住んでいると、家を汚すことに抵抗がなくなってくる」のと同じです。アプリケーションも1箇所汚くなると、その汚染はたちまち全体に広がっていきます。
より良いアプリケーションを目指して
良いコードとは何かを考える
これを踏まえて、このような事態が起こりにくい、なるべく負債が溜まりにくいコードを書く方法はないだろうか、と考え始めました。読みやすく、変更にも追加にも強いコードが書くことができれば、負債が溜まりにくいのはもちろん、安全で、将来の開発スピードも上がっていくはずです。
これについて詳しく調べていくと、同じことを考えている先人たちは多く、非常に勉強になる考え方にいくつか出会いました。このうち最も重要だと思ったことを2つここでは書きたいと思います。
- SOLID原則
- モデルを厚く、コントローラーを薄く
SOLID原則
まず1の「SOLID原則」についてです。これは、特にオブジェクト指向で用いられる五つの原則の頭字語をとったアクロニムです。ソフトウェア設計をより平易かつ柔軟にして保守しやすくすることを目的にしている原則で、それぞれの原則は以下のようになっています。
- Single Responsibility(単一責任の原則)
- Open-Closed(オープン・クローズドの原則)
- Liskov Substitution(リスコフの置換原則)
- Interface Segregation(インターフェイス分離の原則)
- Dependency Inversion(依存性逆転の原則)
それぞれの原則の詳細に関しては、読者の皆さんで調べていただければ思います。非常にたくさんの記事があるはずです。当時の「スモッカ」ではこれらの原則があまり守られずに書かれていました。全ての解説は長すぎるので割愛しますが、せっかくなので、この中で私が最も重要だと考えるSingle Responsibilityについての解説を簡単にしたいと思います。
Single Responsibilityとは、文字通り常にクラスやモジュール、さらにはメソッドに単一の責任を持たせるというものです。2つ以上の責任を持たせてはいけないという考え方です。
例えば、読者の皆さんの開発に関わっているアプリの、あるクラスを思い浮かべてみてください。そのクラスが何の役割を果たしているのか、を一言で述べられるでしょうか。そのクラスの役割を説明しているときに、「〜と」(and)や「〜の時は」(if, or)などの言葉が含まれていたら、そのクラスは2つ以上の責任を持っていることが多く、直す余地がある可能性が高いです。クラスの設計やリファクタリングをするときに、毎回書き出してみると良いです。
先にクラスの話をしましたが、これはメソッドでも同じです。ここでは具体的にコードベースで見ていきましょう。例えば、ロボット(Robot)クラスというものがあって、ロボットを操作するためのメソッド(operate)があったとします。
まずは、operateの悪い例として非単一責任のメソッドを書いてみます。
class Robot
attr_accessor :speed
def initialize
@speed = 0
end
def operate(type, direction=nil)
case type
when :move
case direction
when :forward
self.speed += 1
when :backward
self.speed -= 1
end
when :stop
if self.speed != 0
if self.speed > 0
while self.speed != 0
self.speed -= 1
end
else
while self.speed != 0
self.speed += 1
end
end
end
end
end
end
このコードは動きますが、「単一責任の法則に反しています。というのも、operateメソッドはロボットが1.なんの操作が行われるのか、2.操作の方向、3.操作のされ方まで知っているからです。つまりこのメソッドには3つも責任があります。理想的にはoperateは、1.なんの操作が行われるのかだけ知っていればいいはずです。それ以降の詳細は他のメソッドに任せるべきなのです。
では単一責任を意識して書き直してみます。
class Robot
attr_accessor :speed
def initialize
@speed = 0
end
def operate(type, direction=nil)
case type
when :move
move(direction)
when :stop
stop
end
end
private
def move(direction)
case direction
when :forward
accelerate
when :backward
decelerate
end
end
def stop
return if stopped?
if self.speed > 0
stop_moving_forward
else
stop_moving_backward
end
end
def stop_moving_forward
while stopped? == false
decelerate
end
end
def stop_moving_backward
while stopped? == false
accelerate
end
end
def accelerate
self.speed += 1
end
def decelerate
self.speed -= 1
end
def stopped?
self.speed == 0
end
end
robot = Robot.new
p robot
robot.operate(:move, :forward)
p robot
robot.operate(:move, :forward)
p robot
robot.operate(:move, :backward)
p robot
robot.operate(:move, :backward)
p robot
robot.operate(:move, :backward)
p robot
robot.operate(:move, :backward)
p robot
robot.operate(:stop)
p robot
#Robot:0x00000157cba2f6d8 @speed=0
#Robot:0x00000157cba2f6d8 @speed=1
#Robot:0x00000157cba2f6d8 @speed=2
#Robot:0x00000157cba2f6d8 @speed=1
#Robot:0x00000157cba2f6d8 @speed=0
#Robot:0x00000157cba2f6d8 @speed=-1
#Robot:0x00000157cba2f6d8 @speed=-2
#Robot:0x00000157cba2f6d8 @speed=0
それぞれメソッドに対しての責任は一つに限られています。operate メソッドの責任は「操作の種類の管理」(1.なんの操作が行われるのか)のみです。具体的には operate は動く(move)か止まる(stop)かの管理していてのみをしていて、「どちらに動くか」といった2.操作の方向や、「どのくらい加速や減速をするのか」といった3.操作のされ方については知りません。責任を委譲しています。
それ以外のコードも一つのメソッドに一つの責任を割り当てられています。moveは引数の方向(direction)だけをとり、方向(direction)をみて速度を前方向に加速させたり(accelarate)、後ろ方向に加速させたり(後ろ方向に加速させるのでdeccelarate)します。2.操作の方向を管理して、あとはそれに合わせたメソッドを呼んでいるだけです。このメソッドの責任も一つです。そして、accelerateは単純に速度をあげていくだけです。これは3.操作のされ方に該当します。
このように責任の分割をしていくことのメリットはいくつもあります。まず、特定の変更の要望が出た時に、その変更は他のメソッドに対して閉じているので、色々な場所をチェックしてコード変更をしなくて良くなります。これは開発スピードの向上につながります。さらに、変更が求められた時に、どこを変更すればいいか明確です。例えば、これからRobotの操作として空を飛ぶ(fly)が追加された場合、moveメソッド内にコードを追加すれば良いというのは明確です。もし加速の幅を2倍にしたい場合は、accelarate を self.speed += 1を self.speed += 2にすればいいのもすぐにわかるはずです。またコードを注意深く読んでいただいた方は気付いたと思いますが、このような責任の分割をするとさまざまなところでコードの再利用もできるようになります。
参考にした本
これらについて、よりわかりやすく、詳しく書かれている良書があったので紹介しておきます。Practical Object-Oriented Design, An Agile Primer Using Ruby (POODR)です。
Practical Object-Oriented Design in Ruby
この本は、たくさんのオブジェクト志向言語で開発する開発者の方に読まれている名著です。洋書ですが翻訳版も出ています。オブジェクト志向言語設計の基礎を徹底的に書いてある本で、簡単に理解できる類の初心者用の本ではないですが、非常におすすめです。
モデルを厚く、コントローラーを薄く
次に、2つ目の「モデルを厚く、コントローラーを薄く」です。
これはRailsのコミュニティでコンセンサスが取れているコードの書き方です。コントローラーにはなるべくコードを書かず、なるべくモデルの中にコードを寄せていくという考え方です。そもそもRailsはフレームワークで、生のRubyではないので、そのまま意識せずに書くと先述したSOLID原則など、オブジェクト指向らしいコードから外れてしまいがちです。そのため、あえてこの意識を持つことで、先述したようなSOLIDなコードがかけるようになります。さらにこれをすると、ユニットテストが書きやすくなりテストカバレッジの向上につながり、安全性の向上につながります。”fat model skinny controller”と検索すると、さまざまなケースの情報が得られます。
「コントローラーを薄く、モデルを厚くという考えに加え、さらに「Railsってこう書くとうまくいきますよね」ということを詳しく書かれている良書があったので、それも紹介しておきます。パーフェクトRuby on Railsです。
パーフェクトRuby on Rails【増補改訂版】:書籍案内|技術評論社
より良い設計者への道
まだまだたくさんの優れた法則や考え方がありますが、ここではキリが無くなってしまうので、このくらいに。これらを意識することで少しずつ変更に強い、より良いソフトウェアが生まれていきます。また、このような設計というのは一朝一夕で身につくものではありません。常に考えることを諦めず、日々調べ、学び、知識を取り入れ続けることが大事だと思っています。
社内に広め、実践していく
これらのことを学んだ私は、この知見を社内に少しでも広めようと活動を始めました。じげんにはTGIF (Thank God/Goodness It’s Friday)と呼ばれる毎月の最終金曜日に行われる勉強会があるのですが、そこでこれらの知見を広めるために登壇しました。
また、住まい.Divのエンジニアチームでコードの書き方に関する規約を決めていっています。定期的にリファクタリングに関するPull Requestの振り返りを行うリファクタリングレビューと呼ばれる定例会も始めました。
5. 速度改善のプロジェクトから見える、じげんでの働き方
この速度改善は大きな事業課題でありながら、新卒2年目の私が指揮をとってプロジェクトを進めることができました。さらに、私が必要だと思った場合は、チームの全員を巻き込んで、リファクタリングプロジェクトのレビューを含めたサイドプロジェクトとしても続けていくことができました。じげんではこのように若い段階から裁量権を持って働くことのできる環境です。このような働き方ができるじげんは、スピード感を持って実践的な経験を積みたい人に最適な職場だと思います。
現在募集中の関連求人はこちら
-
Jobs 【中途・東京】《住まいDiv.》エンジニアリングマネージャー候補(VPoE/開発責任者)
summary-
募集概要
住まいをはじめ、求人や自動車など、ライフイベント領域における最良な意思決定をサポートするインターネットメディアを運営する弊社。
中でも主力事業のひとつである住まい事業部では今後、100億の売上を目指した事業拡大を見据えながら事業計画やシステム設計、組織強化を行う必要があると考えております。
今回のポジションではエンジニアの育成・マネジメントやプロセス改善などの問題解決、組織的改善を行っていただける方を募集いたします。 -
仕事内容
<具体的な業務内容>
・プロダクトオーナー(事業責任者)と協力しながら開発進行・方針の決定
・開発チームが効果的なパフォーマンスを上げる為のチームビルディング
・エンジニアの人員計画策定・育成(目標設定・評価、マネジメント)
・プロセス改善など技術面以外も含めたあらゆる問題解決、組織的改善<じげんでエンジニアになる魅力>
■扱うビッグデータの量と質はベンチャートップクラス
トータルのサービス利用者数が1000万人に上る当社。分野も求人、住まい、自動車、旅行など多岐にわたるため、当社にはメディア上のユーザーの行動に関するビックデータが大量にあります。
例)
・賃貸情報:500万/日のトラフィックデータ
・求人情報:60万件(日本トップクラス)■いかにユーザーに価値のある行動を促進するかに焦点を置いたサービス開発の考え方
技術だけでなくWebサービス全体を深く理解するのはもちろんながら、Webマーケティング・UI/UXの視点や、データを元にした事業開発の視点が求められます。
サービスを成長させるために何をすべきか、分析・解析する力、他職種と柔軟に連携し、企画立案・進行を行うスキルを身につけることが可能です。<開発体制>
事業の企画~開発、実装までを全て自社で担当しており、多種多様な事業を少人数で開発しているため、状況に応じて複数のプロジェクトを同時進行で動かしています。
タテ・ヨコ・ナナメ、エンジニアだけにとどまらず、様々な職種のメンバーとコミュニケーションを取りながら、自分自身で施策を推進し、成果を出すところまでの一連の流れに関わります。
様々な業務を通してマルチに活躍できる人材へのステップアップが可能であり、エンジニアリングを強みとしつつ、技術サイドとビジネスサイドのバランスを取りながらスキルを伸ばしていける環境です。また、ベトナムには弊社グループのみに向けたオフショア開発を行っいるZIGExN VeNturaという子会社があり、
国内には開発の拠点として沖縄にも支店があり、それぞれ交流も活発に行っております。<主に使用している技術等>
*言語
Ruby, JavaScript, SCSS
*フレームワーク
Ruby on Rails, jQuery, Vue.js
*環境
Linux, nginx, AWS, Docker, CircleCI, GCP
*データベース
MySQL
*プロジェクト管理
Jira, GitHub
*支給マシン
MacBook Pro 16inch
*開発手法
アジャイル、スクラム -
応募条件
【必須スキル】
・開発エンジニアとしてのご経験 3年以上
・ピープルマネジメントのご経験【歓迎スキル】
・Web業界でのVPoE経験、もしくはそれに準ずるエンジニアリング部門責任者経験
・人員計画策定やエンジニア組織構築のご経験
・スクラム開発のご経験
・スクラムマスターとしてのご経験
・大規模サイトの保守・運用経験
*「大規模」の目安…10万URLsで100万UU以上のトラフィックのあるサービス【求める人物像】
・技術志向よりサービス志向
・時代や技術に左右されないポータブルスキルを身につけたい
・数値やビジネスに強いエンジニアになりたい
・事業のプロとしてサービスの成果にコミットしたい -
雇用形態
正社員
-
試用期間
6カ月
※試用期間中の待遇などに変更はありません。 -
勤務地
東京都港区虎ノ門3-4-8
-
勤務時間
フレックスタイム制
・コアタイム:10:00~16:00
・フレキシブルタイム:(始業)7:00~10:00 (終業)16:00~22:00
・1日の標準労働時間:8時間
※所属長の判断により、10:00~19:00等の固定シフトとなる可能性がございます。 -
休日・休暇
完全週休2日制(土日祝)、夏季休暇、年末年始休暇
年次有給休暇(時間単位での取得も可能) -
想定給与
月給:500,000円~666,667円
※固定残業手当(45時間分):130,058円~173,411円を含む。
※45時間を超過した時間外労働の残業手当は追加支給。
※採用時のポジションにより、試用期間終了後、
別途役職手当・管理監督者手当を支給する場合あり。上記はあくまで想定であり、ご経験・スキルを考慮して決定いたします。
(給与改定年4回) -
待遇
【保険】
各種社会保険完備(雇用・労災・健康・厚生年金)【交通費】
全額支給【受動喫煙防止のための取組み】
屋内原則禁煙(喫煙室あり)【福利厚生・社内制度】
・関東ITソフトウェア健康保険組合
・ベネフィットステーション
・社内クラブ活動支援
・リファラル採用決定でインセンティブ支給
・誕生日月にAmazonギフトカード1万円分支給
・社内交流イベント(全社会、シャッフルランチ等)
・N-minutes(1日20分間昼寝ができる)
・資格補助制度
・服装自由 等 -
選考フロー
書類選考→ 一次面接 → 適性検査+二次面接 →(最終面接)→ 内定
※面接はオンラインで実施させていただきます
※適性検査については一次面接通過のご連絡後、最終面接までにオンラインで受験いただきます。(15分程度)
また、選考の合否は適性検査結果のみで判断されることはありません。
※決裁権限者や特定のポジションでの採用の場合、内定通知前にリファレンスチェックを実施させて頂いております。ご理解頂けますと幸いです。 -
よくあるご質問
こちらをご覧ください→FAQ
-