くらしのマーケット開発ブログ

猫のいる会社、みんなのマーケットの技術ブログ

Robot Frameworkを利用したUIテスト

こんにちは、新卒エンジニアのツヅキです。
今回はRobot Frameworkを使ったSPページのUIテストのお話です。
そもそもRobot Frameworkを使った”SPページのUIテスト”(以後、テスト)とはなんでしょうか?

スマートフォンのブラウザからあるサイトにアクセスし、特定の動作に対して機械的にテストをすること

ここでいくつかの疑問が生まれます。

  • なぜ、わざわざ機械的にテストするの?
  • なぜ、SPページでテストするの?
  • そもそもテストする必要ある?

などなど、では一つずつ考えていきましょう。
なぜ、わざわざ機械的にテストするの?
何度も同じテストを人が一回一回テストすると、とても時間がかかります。しかし、機械的にテストをすることによりテスト時間を大幅に短縮することができるので機械的にテストします。
なぜ、SPページでテストするの?
パソコンのブラウザより、スマートフォンのブラウザの方が多くの人に利用されているので、SPページでテストします。
そもそもテストする必要ある?
テストをすることによってテストケース内の動作は正常に動作できることは保障されるからです。

では、本題のRobot Frameworkのお話です。
Robot Frameworkは何かについて少しだけ説明させていただきます。

受け入れテストやテスト駆動開発 (ATDD) のための、オープンソースの汎用テスト自動化フレームワークです。 簡単に扱えるテーブル形式のテストデータ記述方法を備えていて、キーワード駆動型のテストアプローチに便利です。 テスト機能は Python や Java でテストライブラリを書いて拡張できます。 ユーザは既存のキーワードを使って新しい高水準キーワードを定義でき、それを使ってテストケースを書けます。[1]

どうやら、無料で簡単にテストを作ることができて、いい感じにカスタマイズできる素晴らしいシステムのようです。
今回のSPページのテストに利用するスマートフォンの種類としてiPhoneのシミュレーターを利用します。
大まかに必要なものを説明します。

必要なもの

  • Appium
  • Xcode
  • Python
  • iPhoneシミュレーター
  • 失敗してもめげない心

特に、一番下の失敗してもめげない心はとても重要です。MacがあればiPhoneシミュレータもAppiumもXcodeも簡単にインストールできますが、テスト環境を作ったりRobot Frameworkでテストを書いているとたまに心が折れそうになるのでしっかりと心の準備を整えてから挑んでください!

では早速インストールの話ですが、”brewでAppiumとMacAppStoreなどからXcodeをインストールし、XcodeでiPhoneシミュレーターを設定後、pipでRobot Frameworkをインストールしてみてください。”[2]ここで書くとこのブログを読んでくださる方も書いている私も心が折れそうなので割愛します。
(私がRobot Frameworkが正常に動作するようになる頃には、心のHPが85%くらい削られていました)

2018-08-23 20 32 38

まず最初に、Robot FrameworkからAppiumに対してどのようなものを使うかの設定を行います

Robot Frameworkの設定

*** Keywords ***
Initialize
    ${caps}=  create dictionary  browserName=Safari  platformName=iOS  platformVersion=11.4
    ...                          deviceName=iPhone 8  automationName=XCUITest  useNewWDA=true
    create webdriver  Remote  command_executor=localhost:3000  desired_capabilities=${caps}

こんな感じです。簡単に説明すると、

  • iPhone 8 のシミュレータを使います。
  • iOS11.4を使います
  • localhost:3000から操作を行います。

と書いてあります。 (Robot Frameworkに合わせてAppiumの設定を行う必要があります)

では次にRobot FrameworkでGoogleにアクセスして見ましょう

Webページへのアクセス

go to  https://www.google.com/

ここでのポイントは、go toの間のスペースは1つ~ to http://example.comtoとURLの間のスペースは2つというところです。

次は、特定の要素をクリックするという操作です。

要素の選択

click element  <XPATH>

この操作は特定のXPATHをもつ要素をクリックするという操作です。ここでも、click elementの間のスペースは1つ、element <XPATH>の間はスペース2つです。<XPATH>の部分には特定の要素を示すXPATHを示してあげてください。

次は、特定の要素に対して入力するという操作です。この操作のおかげで、ボックスなどに対して文字を入力することができます。

文字の入力

input text  <XPATH>  <入力したい文字列>

この操作は特定のXPATHに対して文字列を入力するという操作です。input textの間のスペースは1つ、text <XPATH> <入力したい文字列>の間はスペース2つです。<XPATH>の部分には特定の要素を示すXPATH、<入力したい文字列>の部分には入力したいテキストをそのまま入力してください。

次は、特定の要素が見つかるまで待つという操作です。この操作があるおかげで、読込みが早い時も、遅い時も、普通の時も要素のクリックや入力が正常にできるまで待ってくれます。

待機

wait until element is enabled  <XPATH>

この操作は特定のXPATHを読み込むまで待つという操作です。

2018-08-23 20 27 22

いかがでしたか?
今回は基本的な部分だけでしたが、他にもifforといった条件分岐や繰り返しを行うことができるので興味がある方は調べて見てください! 一緒に働いてみたいといった方もぜひお待ちしてます!

参考

[1] https://robotframework-ja.readthedocs.io/ja/latest/quickstart/QuickStart.html
[2] http://thinkami.hatenablog.com/entry/2017/09/15/222958

家賃を予測してみよう!

皆さん、こんにちは。エンジニアのトゥエンです。

あなたは家を探したことがありますか。私はもうすぐ引っ越しする予定です。 ですから、今日、「線形回帰」を使って、東京でシェアハウスの家賃を予測してみましょう。

f:id:curama-tech:20180820124309j:plain

問題

下記のような、部屋の家賃や面積、フロアについてのデータがあるとします。

面積(m²) フロア(F) 家賃(千円)
7 2 45
7.12 1 51
7.2 1 52
7.69 1 53
7.79 1 52.6
8 1 52
8.28 1 54
8.37 2 54.2
8.7 2 56
9.93 2 64
10.5 2 65
10.53 1 72
11 3 75
12.19 3 78.3
12.4 1 80

これを使って別の部屋の家賃を予測してみましょう。

少し数学について

線形回帰

上の問題は、「線形回帰」と呼ばれる、「教師あり学習」の一形態です。

線形回帰の公式は

{ \displaystyle 
        Y' \approx  Xw = Y 
    }
  • { \displaystyle Y' } : 予測の値
  • { \displaystyle Y } : 実際の値
  • { \displaystyle x } : インプットデータの値
  • { \displaystyle w } : ウェイト

損失関数

目標は実際の値(Y')と予測の値(Y)の差が最小です。ということは、関数の得る価値を最小するために { \displaystyle w } を見つける必要があります!

{ \displaystyle 
        L(w) = \frac{1}{2}\sum_{i=1}^{N}(Y'_{i}-Y_{i})^{2} = \frac{1}{2}\sum_{i=1}^{N}(Y'_{i}-X_{i}w)^{2} 
    }

問題の解決

損失関数の定義から、これが最適化問題であることがわかります。最適化問題を解決するために、一般的な方法の1つは、導関数を使用することです。

ちなみに、以前、凸最適化問題を紹介しました。よかったら、読んでください。

家賃予測

家賃は、次の式で計算されます。

家賃 = 面積 * { \displaystyle w_1 } + フロア * { \displaystyle w_2 }

家賃を予測するために、{ \displaystyle (w_1, w_2) }の適切な値を見つけなければなりません。

Pythonの scikit-learn ライブラリを使って、早く解決することができます。

import numpy as np
from sklearn import linear_model

X = np.array([
    [7, 7.12, 7.2, 7.69, 7.79, 8, 8.28, 8.37, 8.7, 9.93, 10.5, 10.53, 11, 12.19, 12.4],
    [2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 3, 3, 1]
]).T

Y = np.array([
    [45, 51, 52, 53, 52.6, 52, 54, 54.2, 56, 64, 65, 72, 75, 78.3, 80]
]).T

linear = linear_model.LinearRegression(fit_intercept=False)

linear.fit(X, Y)

print(linear.coef_)

結果:

[[ 6.74732924 -0.88385193]]

{ \displaystyle
    (w_1, w_2) = (6.74732924, -0.88385193)
}

ですから、3階にあり、面積8m²の部屋の家賃は約54700円です。

f:id:curama-tech:20180820124410p:plain

精度をテストしてみます。本例ではデータセット全体を 80:20 の割合でトレーニングデータとテストデータに分割します。

from sklearn.model_selection import train_test_split

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2)

linear.fit(X_train, Y_train)

linearScore = linear.score(X_test, Y_test)

print(linearScore)

結果:

0.8280773078631194

1に近いほど精度は高くなります。

おわりに

我々みんなのマーケットテックチームでは「くらしのマーケット」を一緒に作る仲間を募集しています!興味がある方はぜひ気軽に連絡ください。

次回は、都築さんの予定です。

参考文献

[1] ウィキペディア

[2] Machine Learning is Fun! – Adam Geitgey

[3] Machine Learning co ban - Vu Huu Tiep, 2018

[4] scikit-learn

スタートアップの社内ネットワーク構築アンチパターン

こんにちは。みんなのマーケットでCTOをしております戸澤です。

この記事でわかること

スタートアップは、組織の急拡大のため年単位でオフィスの移転をすることがよくあります。 弊社も移転を繰り返し、その度に新しいオフィスの社内ネットワーク構築を行ってきました。

今回は、これまでの社内ネットワーク構築の経験をもとに、5,30,70名のそれぞれの規模のときに、どんな社内ネットワーク構成にしたかを紹介します。 また最後に、それらの経験から得られたアンチパターンをまとめますので、参考になればと思います。

f:id:curama-tech:20180809205438p:plain:w300

社内ネットワーク構築の歴史

弊社は2011年に創業したスタートアップで、東京と宮崎にオフィスがあります。東京オフィスは、これまでに7回の移転をしています。 このうち、最初の4回はシェアオフィスだったため、社内ネットワークの構築と管理は同居している他の会社の方がやってくれましたが、 5回目からは、自社のみのオフィスとなったため、自分たちで構築と管理をするようになりました。 5,6,7回目のそれぞれの移転で、人数が〜5名, 〜30名, 〜70名規模のオフィスとなったため、この組織規模別に社内ネットワークの構成を紹介していきます。

また、弊ブログの「Amazon Connect使ってみた!」の なぜ電話システム(IVR)が必要なのかでも触れていますが、 弊社には電話を多く使う業務があり、その電話はコンサル電話と呼ばれるブラウザ上から電話できるシステムを使って行われます。 tech.curama.jp

この電話の通信はWi-Fiを通して行われ、音声が途切れたり、相手の声が聞こえないなどのトラブルを何度も経験してきました。

電話というジッターやレイテンシ等の条件がある中で、持ち運びやすさのために有線LANの接続ではなくWi-Fi接続で安定させるための取り組みを行ってきましたので、その経験も参考になればと思います。

〜5名

当時、マンションの1LDK一室をオフィスにしていました。 この広さ、人数であれば、一般家庭でのネット利用と変わらず、家庭向けの機器や回線を選択することでコストも抑えられます。

なので、

  • ルーター(Wi-FiのAP付き): NECの家庭用のもの(Atermシリーズ)
  • 回線: フレッツ(マンションタイプ&最大1Gbps) + 個人向けISP(月800円ほど)

以上の構成で問題なく、ネットが利用できました。

〜30名

30名となると、広さはマンションの一室レベルではなくオフィスレベルになり、クライアント数も多くなるので、家庭用の機器では対応できません。 そのため、ルーターとアクセスポイント(AP)を業務用の機種から新しく導入しました。

ルータの選定は、他の方が書かれた記事を参考にしながら、YAMAHAで規模にあう機種を選びました。 YAMAHAのルーターを初めて導入するため、こちらの本も参考に構築を進めました。

ノンエンジニアのための社内ネットワーク施工・構築ガイド 20~40人規模のLAN環境を自分で作ろう (Do IT Yourself)

ノンエンジニアのための社内ネットワーク施工・構築ガイド 20~40人規模のLAN環境を自分で作ろう (Do IT Yourself)

また、回線もクライアント数の増加に対応できるよう、フレッツより大きい帯域幅が謳われているものを用意しました。

  • ルーター: YAHAMA RTX810
  • AP: Buffaloの業務用AP
  • 回線: フレッツのシェアドアクセス方式を利用した会社のもの

以上の構成で問題なく、ネットが利用できました。

〜70名(現在)

30名のオフィスでは、回線にフレッツより帯域幅の大きいシェアドアクセス方式のものを利用していました。 新オフィスでも継続利用を検討しましたが、移転工事にあたりフレッツよりも開通に時間を要するという説明を受け、 早くの移転を予定していたためそれに間に合うように、比較的開通までの時間が短いフレッツを利用することにしました。

当初、フレッツでは厳しいと考えていましたが、問題なく使えることがわかり現在も継続して使用しています。 NTTの収容局の混雑具合にもよりますが、70名規模でもフレッツで問題なく通信できていることから、〜30名でもファミリータイプであれば問題なく使えたと思っています。

ルーターはRTX810だとNATディスクリプターが近々枯渇することが予想できたので、より多くのNATディスクリプターをサポートしている上位機種のRTX1210を導入しました。

また、APもBuffalo1台のみでは対応できるクライアント数が厳しいので、今後YAMAHAでネットワーク機器を揃える方針でYAMAHAのAPを1台追加し、BuffaloとYAMAHAを併用しました。

  • ルーター: YAMAHA RTX1210
  • AP: Buffaloの業務用AP x1 + YAMAHAのAP x1
  • 回線: フレッツ(ファミリータイプ&最大1Gbps) + 個人用のISP

これでしばらく問題なく使えていたのですが、Windowsアップデートの日に回線が重くなり、パケットロスが多く発生しました。 弊社のWindows端末は数台だけで、社内のWindowsアップデートではなく、そのISPの利用者全体のアップデートに起因しているようでした。

ISP側もWindowsアップデートの日は重くなることを把握していて、毎月のWindowsアップデート日に発生する可能性があり業務に支障がでることが予想されるため、個人用ISPからIIJの法人向けISPに切り替えました。 IIJのISPはSLAがあり、今のところ、Windowsアップデート日やそれ以外でも重くなることは経験していません。

  • ルーター: YAMAHA RTX1210
  • AP: Buffaloの業務用AP x1 + YAMAHAのAP x1
  • 回線: フレッツ(ファミリータイプ&最大1Gbps) + IIJの法人向けISP

この構成で利用していきましたが、人数が60名くらいから稀にコンサル電話の音声が途切れるという問題が発生し始めます。 トラフィックを監視していると途切れが発生する直前に、大容量の通信(ISOファイルのダウンロードなど)が走ると、途切れが発生することがわかり、ルータとAPででQOSと端末ごとの速度制限を導入しました。 速度制限は250Mbpsといったかなり高速の通信をある時間以上すると、通信速度を不便にならない範囲で落とす仕組みです。これで途切れは減ったものの、まだ度々起きる状態でした。

電話トラブルの厄介なところは、原因がネット環境以外にも考えられることです。 ヘッドセットの調子、ブラウザ、電話システムのバグ、相手の通信状況など場合によっては、これらが原因のこともありました。

有線接続の場合は途切れが少ないとの声もあり、社内ネットワーク構築の会社の意見を聞いたところ、 現在の2台のAPでは台数が足りなく、メーカーも別でAP間の連携が取れないため端末分散ができないため、APで通信が詰まっている可能性があるという話になりました。 検証用のAPを導入し試験運用してみたところ、途切れがなくなったため、APの増設工事を依頼しました。

  • ルーター: YAMAHA RTX1210
  • AP: ArubaのAP x4
  • 回線: フレッツ(ファミリータイプ&最大1Gbps) + IIJの法人向けISP

現在は、この構成でネットを利用しています。 電話の途切れはなく、APのメーカーも統一されたことで管理が楽になりました。

これからこうしたい

クライアント数が増えること、トラブル時の損失のインパクトも大きいことを考えると、フレッツのベストエフォートのプランではなく、帯域保証のプランに変えるつもりです。

また、当初からの流れで私がメインとなって社内ネットワークの管理をしてきましたが、今後の規模を考えると次回からはエンジニアにメインの管理をお願いしたいと思っています。

アンチパターン

さて、社内ネットワーク構築の歴史をもとに、アンチパターンをまとめていきます。

機器間の連携が取れないAPを導入する

バラバラのメーカーのAPを導入すると、設定を変える際にmaster機で設定したものをslave機に自動反映することができず、個々に設定することになり管理がつらいです。 また、自動チャンネル変更もAP間で連携が取れなく、双方で永遠とチャンネル変更を繰り返してWi-Fiが何度も途切れることがありました。

現在は同じメーカーのAPを導入していて連携が取れるため、1台のAPにクライアントが集中しないように、AP間での端末分散もできるようになりました。

最初に複数台購入するときはもちろん揃えるとして、 途中でメーカーを変えたくなった場合でも、古いメーカーは使わずに、すべてのAPを新しく導入するメーカーで揃えることをおすすめします。

ジッターやレイテンシが通信要件に入っているのにWi-Fiを使う

専門の会社にAPの増設工事をしてもらい、Wi-Fiでの電話利用ができていますが、今後クライアント数が多くなった場合はどうなるかわかりません。

無線と有線は、トレードオフなところがあるので状況によるとは思いますが、トラブル時の対応工数を考えると有線LANを使うことをおすすめします。

また、ジッターやレイテンシ、パケットロスなどが通信要件に入っている場合、専門の会社に相談して設計や機種選定、キャパシティプランニングを行うことをおすすめします。

SLAのない個人向けISPで頑張る

問題なく使えていたという理由で個人用ISPを継続利用しましたが、ある日回線が遅くなる現象が起きました。

急ぎで導入したい場合は個人ISPの方が早いと思いますが、問題ないからといってそのまま継続するのではなく、 トラブル時の業務や売上へのインパクトを考えて、SLAや帯域保証があるISPに後に変えることをおすすめします。

今の人数だけに対応できる機種を導入する

30名から70名への移転する際、ルーターの買い替えをしました。 数年以内のオフィスの移転が見えているなら、最初から上位機種を購入した方が良かったと思います。

人数に対してオーバースペックにはなりますが、耐用年数は数年程度ではないので、今後の増員を見越して長く使えるものを導入することをおすすめします。

自分ですべて管理できると思う

トラブルが起きた際にネットワークに強いエンジニアの方であれば、問題ないのだとおもいますが、そうでない場合は対応工数が大きいです。 自分でやることで勉強になるという利点はあるのですが、特に電話の途切れトラブルでAPに起因する部分は早い段階で専門業者に相談するべきでした。

最近では、すべてマネージドでやってくれるサービスもあるようなので、社内メンバーがプロダクトに集中して、マネージドできるものはお願いするという選択は大いにありだと思います。

最後に

今回は組織の人数別に事例を紹介しましたが、実際は人数よりも接続するクライアントの数や利用状況への依存が大きいので、考慮した上で適用する必要があります。

最後に、みんなのマーケットに興味がありましたら、会社の雰囲気や事業を知っていただくための、ざっくばらんな面談もやってますので、ぜひ連絡ください。

次回は、Backendエンジニアのトゥエンさんがお送りします。

Swift: Memory leaks、 豊かな人々も泣く!

こんにちは、エンジニアのDuyです。

今日はSwiftのメモリリークについて、話そうと思います。

f:id:curama-tech:20180802152853p:plain:w262:h263

最近、技術が発展しているため、モバイルデバイスの容量も大きくなっているんですが、メモリを管理しないと、アプリが遅くなって、アプリの容量が大きすぎることによって、アプリがcrashする可能性もあります。お金持ちなのにお金を無駄遣いしたら、ある時点でお金がなくなってしまう。お金がなくなったら、豊かな人々も泣く!

そのため、メモリを管理するのが大切です。

つまり、メモリリークとは?

メモリリークはプログラムが確保したメモリの一部、または全部を解放するのを忘れ、確保したままになってしまうことを言う。そのメモリは参照されないので、開放できないし、利用もできない。

リークはいつ?どこから?

アプリを開発するとき、サードパーティのライブラリを使ったら、リークが発生する可能性があるし、CALayerやUILabelのようにAppleによって作成されたクラスからリークが発生する可能性もあります。さらに、デベロッパーのコードはリークがよく発生します。(残念なんですけど、それは本当のことです!)

ある朝、目を覚まして、綺麗な空を見ます。あなたは出社して、自分の席に座って、前日の困っていたことを突然スムーズに解決できますが、アプリを何回かテストしているうちに、だんだんと遅くなってしまいます。あなたがリークを作成しました。(実は寂しくてもうれしくても、リークを作成する可能性があります。)

どうやって、リークを避けることができるでしょうか? リークが発生したら、どうやって、リークを解決できるでしょう?

リークを避ける、あるいはリークを解決できるようにするため、Swiftのリークの原因をさがしましょう!

強参照サイクル (Strong Reference Cycles)

強参照は、参照が存在する限り参照が指すクラスインスタンスを割り当て解除できないことを意味します。下記の例を一緒に見ましょう!

(*) StaffとDeviceの例:

class Staff {
    let name: String
    init(name: String) {
    self.name = name 
    }
    var device: Device?
    
    deinit { 
        print("Staff \(name) is being deinitialized") 
    }
}

class Device {
    let name: String
    init(name: String) { 
        self.name = name 
    }
    var staff: Staff?
    deinit { 
        print("Device \(name) is being deinitialized") 
    }
}

Staffはnamedeviceという2つプロパティがあります。Staffは必ずdeviceがあるとは限らないので、deviceはオプショナルです。 類似、Deviceは2つプロパティがあります。nameとstaffです。

今、変数を定義します。下記の変数のイニシャル価はnilです。

var staff: Staff?
var device: Device?

次に、StaffとDeviceのインスタンスを上の変数にアサインします。

staff = Staff(name: "yamada hanako")
device = Device(name: "macbook")

2つのインスタンスをリンクします。

staff!.device = device
device!.staff = staff

リンクしたあとは、こういう感じになります。

f:id:curama-tech:20180802160844p:plain

変数をnilにします。

staff = nil
device = nil

staff及びdevice変数によって保持されている強参照は無くなりますがが、StaffDeviceのインスタンスはまだ強参照を残ります。それはメモリリークです。

他の例を一緒に見ましょう!

(*) Playerの例:

class Player {
    let name: String
    let age: Int

    lazy var detail: () -> String = {
        return "Name: \(self.name), age: \(self.age) "
    }
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    
    deinit {
        print("Deallocated!")
    }
}

var player: Player?
player = Player(name: "yamada", age: 20)

player?.detail()

player = nil

これから見ると、playerがnilに設定されている時にPlayerインスタンスが割り当て解除されないため、deinitのprintを実行されません。それもメモリリークです。

先程、リークを作りましたが、どうやって解決しますか?

弱参照(Weak Reference)

弱参照は、それが参照するインスタンスを強く保持しない参照です

弱参照は参照するインスタンスを強く保持しない参照であるため、ARCが参照インスタンスを破棄しないようにします。(オフィシャルドキュメント)

(*) StaffとDeviceの例をもう一回見ましょう!

もし、var staff: Staff?の行は weak var staff: Staff?にしたら、下記のスクリプトを実行して、

staff = nil
device = nil

結果は

Staff yamada hanako is being deinitialized
Device macbook is being deinitialized

というのは、StaffとDeviceのインスタンスを割り当て解除されました。リークを解決できました。

weakにはよくThe Delegation Patternを使います。例えば:

    
    open class UITableView : UIScrollView, NSCoding, UIDataSourceTranslating {

        public init(frame: CGRect, style: UITableViewStyle) // must specify style at creation. -initWithFrame: calls this with UITableViewStylePlain

        public init?(coder aDecoder: NSCoder)

        
        open var style: UITableViewStyle { get }

        
        weak open var dataSource: UITableViewDataSource?

        weak open var delegate: UITableViewDelegate?

[...]

または、

@IBOutlet private weak var label: UILabel?

これを見ると、weakはnilをセットできるので、定数にできません。

非所有参照 (Unowned Reference)

弱参照と同様に、非所有参照は、それが参照するインスタンスを強く保持しません。 ただし、弱参照とは異なり、他のインスタンスが同じ存続時間またはより長い存続時間を持つ場合、非所有参照が使用されます。(オフィシャルドキュメント)

例を見ましょう!

class Workspace {
    let name: String
    var channel: Channel?
    init(name: String) {
        self.name = name
    }
    deinit { 
        print("Workspace \(name) is being deinitialized") 
    }
}

class Channel {
    let name: String
    let workspace: Workspace
    init(name: String, workspace: Workspace) {
        self.name = name
        self.workspace = workspace
    }
    deinit { 
        print("Channel #\(number) is being deinitialized") 
    }
}

var workspace: Workspace?

workspace = Workspace(name: "slack")
workspace!.channel = Channel(name: "private", workspace: workspace!)

workspace = nil

Workspaceはchannelがあるかどうか決まっていないがChannelは必ずWorkspaceに属します。

この場合は、WorkspaceChannelのインスタンスは強参照があるので、deinitの関数を実行されません。

しかし、unownedをつかったら?

class Channel {
    let name: String
    unowned let workspace: Workspace // unowned を追加
    init(name: String, workspace: Workspace) {
        self.name = name
        self.workspace = workspace
    }
    deinit { 
        print("Channel #\(number) is being deinitialized") 
    }
}

こういう感じになります。

f:id:curama-tech:20180802160746p:plain

この行

workspace = nil

を実行すれば

Workspace slack is being deinitialized
Channel #private is being deinitialized

理由は、非所有参照のため、workspace変数が保持する強参照を解除すると、Workspaceインスタンスへの強参照はなくなります。メモリリークを解決できました。

キャプチャーリストを定義する(Capture List)

キャプチャリストは、weakまたはunownedキーワードをクラスインスタンス(selfなど)への参照や、値によって初期化された変数(delegate = self.delegate!など)とペアにしたものです。(オフィシャルドキュメント)

Playerの例をもう一回見ましょう!

lazy var detail: () -> String = {
        return "Name: \(self.name), age: \(self.age) "
    }

変更して、

lazy var detail: () -> String = { [unowned self] in // [unowned self] を追加
        return "Name: \(self.name), age: \(self.age) "
    }

もう一回実行したら、結果は

Deallocated!

というのはリークも解決できました。

最後に

私たちテックチームでは「くらしのマーケット」を一緒に作る仲間を募集しています。興味がある方は是非お気軽にご連絡ください (コーポレートサイト https://www.minma.jp/ )。

入社後の新卒研修ってどんなもの?今年はこんなことやりました!

こんにちは、ディレクターのめぐみです!

テクノロジー本部では現在採用に力を入れています。
去年からは新卒採用も始めたのですが、新卒の学生さんが会社選びをするにあたり、公開している情報が少ないってことに気付きました。なので入社したらまずどんなことをするの?そのイメージを持ってもらうべく、エンジニアの新卒研修について紹介します!

エンジニアの新卒研修、こんなことやっています!

テクノロジー本部では、1ヶ月ほどにわたり、みんなのマーケットで使っている技術や仕組みを知ってもらうための研修を行っています。

例として、

  • くらしのマーケットで使っている技術を使ってwebサービスを作る
  • ER図の更新をする

といったことをしています。

具体的には、下の6つのステップを踏んで、システム開発や設計について理解してもらいます。

  • 1.WEB技術の基本である、RESTやHTTPについて理解
  • 2.くらしのマーケットで利用されているmicro-serviceについて理解
  • 3.APIから必要な情報を取得するserverを構築
  • 4.HTTPの基本技術である、GETとPOSTを利用してWEBページとserver間での情報のやり取りを行いwebページに情報を出力するシステムを構築
  • 5.APIから取得した情報をredisを使って一定時間保存し、serverとAPI間の余分な通信を減らす技術を導入
  • 6.serverから非同期通信を利用して情報ごとに更新を行う技術を導入

私たちは「まずは実践してみること」を大切にしているので、実践しながら学べる研修内容になっています。 こうすることで技術面はもちろん、会社のカルチャーを理解してもらうのが狙いです。

新卒研修を受けた社員に感想を聞いてみました!

新卒のtakafumiくんに聞いてみました!

大学では情報系の勉強をしていましたが、今までwebに関することをほとんどやってきませんでした。 ただPythonを使うことには慣れていたので、web系の開発もできるだろうという安易な感覚でいました。しかし、実際はPythonを使うところは出てこず、node.js(typescript)でweb側の開発をすることになってだいぶ苦労しました。 それでも、先輩のエンジニアに0から教えてもらいながら研修を乗り越えることができました。  

とのこと。

くらまのシステムについても理解が深まったそうで、みんなの会話が徐々にわかるようになってきたみたいです。仕事をする上ではまずこれが重要ですね。

大変なことも多かったようですが、「何かを作ることが好き」+「みんなのマーケットで働く人の役に立ちたい」というモチベーションで取り組んでいたようです。

テクノロジー本部だけじゃなくて他部署の研修も参加できるよ!

そもそも、

  • くらしのマーケットってどういうサービスなのか?
  • どんな人がどんな風にサービスを使っているのか?


が理解できていないと開発する上で判断に困ることが出てきます。 なので、サービスについて理解するために、様々なプログラムや研修を用意しています。希望があれば他部署の研修でも参加することができます。

例えば、

  • ユーザーの気持ちを理解するために、予約申し込みから訪問サービスを受けるところまでを体験する
  • 事業者側の利用ルールを理解するために、くらしのマーケットへの出店登録から予約獲得までの流れを体験する
  • 出店している事業者向けの売上アップ講座に参加する

などがあります。売上アップ講座では、サービスを提供している出店者と直接話をすることもできるので、くらしのマーケットへの理解がより深まります 。

最後に

いかがでしたか?入社したら最初にどんなことをやるのかのイメージを持っていただけたでしょうか。
研修内容については受けた社員からフィードバックをもらい、次回の研修に役立てています。研修を受けた後にスムーズに開発に入れるような内容にしていきたいと思っています!

私たちテックチームでは「くらしのマーケット」を一緒に作る仲間を募集しています! 特に2019年新卒採用を積極的にしています。 こちらのサイトよりエントリーしていただいた方には個別説明会やカジュアル面談などを行なっております。
ぜひ応募お待ちしています!