TECH PLAY

株式会社マイナビ デジタルテクノロジー戦略本部

株式会社マイナビ デジタルテクノロジー戦略本部 の技術ブログ

215

概要 マイナビエンジニアブログの記事をスクレイピングして、更新される度に通知が飛ぶプログラムをGASのライブラリであるCheerioで作りたい!! 前提 マイナビエンジニアブログを自動通知したいと思うときがきっと来るはず。。。 そんな時に役立つのが、今回紹介するCheerioを使ったスクレイピングの技術です!! 流れとしては、GASとスプレッドシートを紐づけてGASでURLをスクレイピングした後に、スプレッドシートのURLと照合して、もしURLが一致していたら、スプレッドシートに書き込みとGmail通知をしないようにします。どのURLとも一致しなかったら、スクレイピングしてスプレッドシートに書き込みします。書き込んだあとは、Gmailに通知を飛ばす処理を書く感じ。。。 下ごしらえ ①Google Drive上にスプレッドシートを作成します。スプレッドシートのヘッダー及び、UIは以下の図のようにします! ②作成したスプレッドシートの拡張機能から、Google Apps Script(以降、GASと表記)を選択します。 ③GASのライブラリタブの「+」ボタンを押し、CheerioのIDをコピペしましょう! CheerioのID 1ReeQ6WO8kKNxoaA_O0XEQ589cIrRvEBA9qcWpNqdOP17i47u6N9M5Xh0 これをGASのライブラリのところにコピペしましょう! Cheerioとは、簡単に説明するとHTML要素を受け取り、DOM操作的なことをするためのライブラリです! ④マイナビエンジニアブログ一覧のURLです。どこかにメモをしておきましょう!ホームページ上で「F12キー」を押すと、開発者画面になります。 https://engineerblog.mynavi.jp/posts/ 本題 関数定義 Webスクレイピングには、HTML要素が必要なので、まず、URLからHTML要素を取ってくる処理を書きます。 function scraping() { let resultList = []; const html = UrlFetchApp.fetch("https://engineerblog.mynavi.jp/posts/").getContentText(); const cheerio = Cheerio.load(html); } 分解すると、以下のようになります。 let resultList = []; これは、最終的なスクレイピング結果を格納するリストです。scraping関数のうち、最も上位階層に書きます。 UrlFetchApp.fetch("各サイトのURL").getContentText(); これで、そのWebページ全てのHTML要素を取得でき、 Cheerio.load("HTML要素"); こちらで、Cheerioによって、HTML要素を分析するための準備ができました。 Cheerioの使い方 ここから先のCheerioの使い方としては、 cheerio('クラス.クラス名').each(function(i, elem) { cheerio(elem).text(); }) 上記のコードで、タグで囲まれたテキストを取得でき、 cheerio('クラス.クラス名').each(function(i, elem) { cheerio(elem).attr('タグ名'); }) こちらで、タグの中にある要素の値を取得できます。 実際にCheerioを使う // ブログのタイトル一覧を取得 let titleList = []; cheerio('div.article-info h3.article-list-title-h3').each((i, elem) => { titleList.push(cheerio(elem).text().toString()); }) // ブログの各URLを取得 let urlList = []; cheerio('div.archive-contents div.list-content ul li.article-list-li-type5 a').each((i, elem) => { let url = "https://engineerblog.mynavi.jp" + cheerio(elem).attr('href').toString(); if (!(url.includes('tag'))) { urlList.push(url); } }) 上記のコードで、それぞれのブログのタイトルとURLが取得できました。 詳しく見ていきましょう! let titleList = []; タイトルを格納するリストを作ります。 let titleList = []; cheerio('div.article-info h3.article-list-title-h3').each((i, elem) => { titleList.push(cheerio(elem).text().toString()); }) このコードで、ブログのタイトルが取得できています! 'div.article-info h3.article-list-title-h3' cheerio()の中に、このようにありますが、記法はCSSと似ていて、 'タグの名前.クラス名 タグの名前#ID名' これでタグで囲まれた要素を取得できます。ここで「.」は、次に続く文字列がクラス名であることを表しています。 「.」= クラス 「#」= ID 左から右にかけてより詳細なタグへと向かうように書きます。タグとの間は空白を空けましょう! 次に、Cheerioで解析したHTML要素を一つずつ取り出します。 .each((i, elem) => { }) eachの第2引数に解析結果が格納されています。 cheerio(elem) 解析結果は、これで取り出すことができました!また、cheerio()は、text()、attr()を持つことができます。 cheerio().text() → タグで囲まれた文字列を取得 cheerio().attr() → タグ内のクラスや、hrefの値を取得 今回は、h3タグで囲まれたタイトルを取得したいため、text()を使います。 titlelist.push() titleListのリストに、取得したタイトルを追加します。 以上の作業で、タイトルが取得できます。 次に、URLを取得するコードを見てみましょう! <a class="hover-thumb_title-mynavi_life" href="/mynavi_life/mynavi_sys_newoffice/"></a> URLは、このように、aタグの中にあります。これを取得するには、前述のようにattr()で取得します。 cheerio(elem).attr('href') これで、aタグの中にあるhref情報を取得できます。 しかし、実際のHTMLを見ると、このさらに下の階層にaタグとhref情報が存在します。この下の階層のhrefは取得したくないので、href情報の値で、絞り込みを行う必要があります。 今回必要なURLは、tagという文字列が入っていないURLです。 let url = "https://engineerblog.mynavi.jp" + cheerio(elem).attr('href').toString(); if (!(url.includes('tag'))) { urlList.push(url); } このように書くことで、tagがついていないときにurlListに追加する処理が実現できます。 以上のコードで、ブログのタイトルとURLを取得することができました。 スプレッドシートに書き込み ここからは、スクレイピングした情報をスプレッドシートに書き込みを行います。 その前に、今回のスクレイピングは同じものをスクレイピングしないようにしたいので、URLを照合する処理を書きましょう。 const spreadSheet = SpreadsheetApp.openById(<スプレッドシートID>); const sheet = spreadSheet.getSheetByName(<シート名>); const urlValues = sheet.getRange(2, 2, sheet.getLastRow(), 1).getValues(); //多次元配列を一次元配列に変換 const urlValuesFlat = urlValues.flat(); URL照合には、URLのみを取得すれば良いので、(2, 2, シートの最後の行, 1)が範囲となります。 flat関数は、多次元配列を一次元配列に直す関数です。getValues()で取得した値は、二次元配列のため、一次元配列に直す必要があります。 このコードは、resultListを定義した上位階層の部分に書きます。 次に、スプレッドシートに書き込みを行うには、二重リストである必要があります。 if (titleList.length == urlList.length) { for (let j=0; j<urlList.length; j++) { if ( !(urlValuesFlat.includes(urlList[j])) ) { resultList.push([titleList[j], urlList[j]]); } } } else { throw new Error("タイトルとURLの数が一致しません"); } resultListを用意して、その中に、リストを埋め込むことで、resultListは二重リストになります。 forループで数字を回すことで、タイトルとURLがそれぞれ入っているリストのIndexを回すことができます。 if ( !(urlValuesFlat.includes(urlList[j])) ) この部分は、スプレッドシートにもともとあるURLとスクレイピングしてきたURLが被っていないかを照合しています。 被っていなかったら、resultListに、タイトルとURLをpushします。 if (titleList.length == urlList.length) { } else { throw new Error("タイトルとURLの数が一致しません"); } この部分は、タイトルとURLの数が一致していたらresultListにpushする処理です。 もし数が合わないと、違うURLを取得していることになるため、エラーにしましょう。 やっとスプレッドシートに書き込む準備が整いました!! // スプレッドシートに書き込み if (resultList.length > 0) { sheet.getRange(sheet.getLastRow()+1, 1, resultList.length, 2).setValues(resultList); } resultListに値が入っているときに、書き込み処理を行います。 書き込む行は、前にスクレイピングしたブログの下に入れるので、スプレッドシートに値が入っている最後の行+1が、書き込みを始める行になります。書き込む行数は、リストの値の数の分だけです。 そのため、(最後の行+1, 1, リストの長さ, 2)となっています。 複数ページのfetch エンジニアブログは、もちろん1ページでは終わっておらず、複数ページにまたがります。ページをループさせ、それぞれのページでもURLfetchを行っていきましょう。 for (let i=0; true; i++) { try { const html = UrlFetchApp.fetch( `https://engineerblog.mynavi.jp/posts/page/${i}/`).getContentText(); const cheerio = Cheerio.load(html); /** * スクレイピング処理 */ // 要素が取得できなかったら、ブログは存在しないのでbreak if (titleList == "") { break; } /** * スクレイピング処理 */ } catch(e) { console.log(e.message); break; } } for (let i=0; true; i++) まず、上のコードでページ番号をループさせます。 `https://engineerblog.mynavi.jp/posts/page/${i}/` このように埋め込むことで、各ページのfetchが可能になります。 このままだと、無限ループになるため、タイトルが取得できなくなったらbreakすることも忘れずに!! if (titleList == "") { break; } 念のため、エラーが発生した際もbreakしましょう! catch(e) { console.log(e.message); break; } ちなみに、トライキャッチとは、簡単に言うとエラーが発生しない間はトライの処理を行い、エラー発生でキャッチの処理を行うことを指します。 ここまでで、スクレイピングの処理が完了しました!!ここまでのコードをまとめると、次のようになります! function scraping() { let resultList = []; const spreadSheet = SpreadsheetApp.openById("1CSRh2KnFP33wb1QPigBCxw7xD5c8EvgmBJzXAts7Ias"); const sheet = spreadSheet.getSheetByName("スクレイピング結果"); const urlValues = sheet.getRange(2, 2, sheet.getLastRow(), 1).getValues(); for (let i=1; true; i++) { try { const html = UrlFetchApp.fetch(`https://engineerblog.mynavi.jp/posts/page/${i}/`).getContentText(); const cheerio = Cheerio.load(html); //多次元配列を一次元配列に変換 const urlValuesFlat = urlValues.flat(); // ブログのタイトル一覧を取得 let titleList = []; cheerio('div.article-info h3.article-list-title-h3').each((i, elem) => { titleList.push(cheerio(elem).text().toString()); }) // 要素が取得できなかったら、ブログは存在しないのでbreak if (titleList == "") { break; } // ブログの各URLを取得 let urlList = []; cheerio('div.archive-contents div.list-content ul li.article-list-li-type5 a').each((i, elem) => { let url = "https://engineerblog.mynavi.jp" + cheerio(elem).attr('href').toString(); if (!(url.includes('tag'))) { urlList.push(url); } }) if (titleList.length == urlList.length) { for (let j=0; j<urlList.length; j++) { if ( !(urlValuesFlat.includes(urlList[j])) ) { resultList.push([titleList[j], urlList[j]]); } } } else { throw new Error("タイトルとURLの数が一致しません"); } } catch(e) { console.log(e.message); break; } } // スプレッドシートに書き込み if (resultList.length > 0) { sheet.getRange(sheet.getLastRow()+1, 1, resultList.length, 2).setValues(resultList); } } メール送信 あとは、メール送信のコードを書いて終了です!! function sendGmail(resultList) { const toMail = '<送信先メールアドレス>'; const subject = '【自動送信】エンジニアブログの更新'; const options = { from: '<送信元メールアドレス>' }; let bodyList = []; for (let result of resultList) { let eachBody = `${result[0]}(${result[1]})`; bodyList.push(eachBody); } const joinBody = bodyList.join('\n'); const body = `以下のエンジニアブログが更新されました!\n\n${joinBody}`; GmailApp.sendEmail(toMail, subject, body, options) } 詳しく見ると、以下のようになります! const toMail = '<送信先メールアドレス>'; const subject = '【自動送信】エンジニアブログの更新'; const options = { from: '<送信元メールアドレス>' }; これは、メールの送信先、題名、送信元を指定しています。 let bodyList = []; for (let result of resultList) { let eachBody = `${result[0]}(${result[1]})`; bodyList.push(eachBody); } const joinBody = bodyList.join('\n'); const body = `以下のエンジニアブログが更新されました!\n\n${joinBody}`; これは、本文に更新されたブログのタイトルとURLを載せているコードです。 一旦、一次元リストにまとめてから、それをjoin関数を用いて、改行区切りで文字列に変換しています。 変数bodyに本文を埋め込んで、 GmailApp.sendEmail(toMail, subject, body, options); これで送信完了!! あとは、このメール送信のタイミングが、resultListを書き込むときにすれば、まとめて更新分のブログを送信できます。 /** * メール送信 * スプレッドシート書き込み */ if (resultList.length > 0) { sendGmail(resultList); sheet.getRange(sheet.getLastRow()+1, 1, resultList.length, 2).setValues(resultList); } scraping関数の中の、このif文の中に埋め込みましょう! トリガー設定 最後に、完全自動実行を実現てみましょう! GASにはトリガーが設定できます。今回は、毎日18:00になるとスクレイピング処理するトリガーをセットします。 メニューから、「トリガー」を選択します。 右下にある「+トリガーを追加」ボタンを押します。 「実行する関数を選択」をscraping、「イベントのソースを選択」を「時間主導型」、「時間ベースのトリガーのタイプを選択」を「日付ベースのタイマー」、「時刻を選択」を「午後6時~7時」にします。 あとは既定の値で、「保存」ボタンを押します。 上の図のようになってたらOK!! 完成 ▼完成コード function scraping() { let resultList = []; const spreadSheet = SpreadsheetApp.openById("1CSRh2KnFP33wb1QPigBCxw7xD5c8EvgmBJzXAts7Ias"); const sheet = spreadSheet.getSheetByName("スクレイピング結果"); const urlValues = sheet.getRange(2, 2, sheet.getLastRow(), 1).getValues(); //多次元配列を一次元配列に変換 const urlValuesFlat = urlValues.flat(); for (let i=1; true; i++) { try { const html = UrlFetchApp.fetch(`https://engineerblog.mynavi.jp/posts/page/${i}/`).getContentText(); const cheerio = Cheerio.load(html); // ブログのタイトル一覧を取得 let titleList = []; cheerio('div.article-info h3.article-list-title-h3').each((i, elem) => { titleList.push(cheerio(elem).text().toString()); }) // 要素が取得できなかったら、ブログは存在しないのでbreak if (titleList == "") { break; } // ブログの各URLを取得 let urlList = []; cheerio('div.archive-contents div.list-content ul li.article-list-li-type5 a').each((i, elem) => { let url = "https://engineerblog.mynavi.jp" + cheerio(elem).attr('href').toString(); if (!(url.includes('tag'))) { urlList.push(url); } }) if (titleList.length == urlList.length) { for (let j=0; j<urlList.length; j++) { if ( !(urlValuesFlat.includes(urlList[j])) ) { resultList.push([titleList[j], urlList[j]]); } } } else { throw new Error("タイトルとURLの数が一致しません"); } } catch(e) { console.log(e.message); break; } } /** * メール送信 * スプレッドシート書き込み */ if (resultList.length > 0) { sendGmail(resultList); sheet.getRange(sheet.getLastRow()+1, 1, resultList.length, 2).setValues(resultList); } } function sendGmail(resultList) { const toMail = '<送信先メールアドレス>'; const subject = '【自動送信】エンジニアブログの更新'; const options = { from: '<送信元メールアドレス>' }; let bodyList = []; for (let result of resultList) { let eachBody = `${result[0]}(${result[1]})`; bodyList.push(eachBody); } const joinBody = bodyList.join('\n'); const body = `以下のエンジニアブログが更新されました!\n\n${joinBody}`; GmailApp.sendEmail(toMail, subject, body, options); } これで完成です!!scraping関数を実行すると、更新分だけ、スプレッドシートに書き込みを行い、メール通知が来ます。 初回のスクレイピング処理は、すべて取ってくるため、メール通知には、全てのエンジニアブログが来ます。 所感 Cheerioを使うと、GASでも比較的簡単にスクレイピングができるんです!私自身、Parserというライブラリも試しましたが、要素を取り出すときに苦労しました。 結果的にはCheerioで良かったと思っています! 業務では、似たようなスクレイピングを行うことがありますが、そのときもCheerioを使ってスクレイピングすることが多いです。 今回紹介したスクレイピングで、ブログの自動通知を行うというものは、業務自動化の一種なので、広義の意味でRPAに該当します!ぜひ、この記事を見ている方々は試してみてほしいです!! 投稿 エンジニアブログの更新分をGmailに通知してみた は マイナビエンジニアブログ に最初に表示されました。
アバター
はじめに こんにちは、私、23年新卒入社のM.Mと申します。 突然ですが、CRMについてご存じですか? 「CRMって聞いたことはあるけど、実際何かはよくわかってない…」 「顧客の情報のなんかでしょ???確か…。」 など、聞いたことは有るけど「よくわからない」という方が大半ではないでしょうか? 分かります。 かくいう私は、2か月前に現場配属され、初めてそこでCRMという言葉を知ったほどです。 そこで、今回は、配属してから2か月で学んだ、「CRMとは何か」 について、新卒ながら、記事を書いてみました。 新卒ながらの着眼点として、本記事を楽しんでくだされば、幸いです。 CRMとは この章ではCRMについて、書いていきます。 そもそも、「CRMとは何なのか」 一体、「何に役立っているか」 実際、CRMが「無いとどうなるか」 の3つの観点からお話出来ればと思います。 CRMとは何なのか CRMとは、 Customer Relationship Management  の略で、一言で言うと「顧客関係管理」のことを指します。顧客関係とは、”一般的に企業とお客様の間で成り立っている関係”のことで、この関係はお客様が一般消費者(サイト利用者など)であればBtoC、お客様が企業であればBtoBと称します。 例えば、マイナビにおけるBtoBの顧客関係には どのような企業がマイナビ2025に求人広告を掲載しているのか 求人広告をどの媒体で掲載しているのか(就職・転職・アルバイトなど…) などがあります。 現在、多くの企業がこういった顧客関係を管理する”CRM”を導入しており、会社の営業活動を支える基盤として重要な役割を担っています。 何に役立っているか では、このCRM、実際何に役立っているでしょうか? 一言でいうと、「企業の管理を出来る」ことに役立っています。 マイナビでも実際CRMツールを使ったデータの統合管理を行っておりますが 例えば 各拠点に点在するマイナビの拠点間で、情報を共有することが出来る 同じ企業に2回以上、架電(営業の電話)をかけてしまう事を防げる。 などの情報のサイロ化を解消することが出来ます。 また、支社の管理や、合併した会社についても、管理することが出来るので 「企業の管理を出来る」ことは全社的に大きなメリットになります。 無いとどうなるか 何に役立っているかについてその逆、 無いと「企業の管理が出来ない」という状態に陥ってしまいます。 支社ごとに各企業を管理することになるので、 お客様に対して持っている情報がバラバラになる 複数の営業担当がアプローチしてしまう可能性 がある 話の食い違いなどにより大きな出戻りが起こる可能性がある など、サイロ化が起こります。会社規模に比例してその問題は大きくなります。 SFAとCRMの関係性 ここまではCRMについて触れてきました。 CRMは、単体で強い効力を持ちますが、より強くCRMを生かす方法があります。 そこで、よくCRMとセットで扱われるもの、それが SFA です。 今回は、SFAについても軽く触れていきたいと思います。 よく間違えるSFA・CRMは実は違う SFA・CRMは、一色端として扱われることが非常に多いですが、実際は全く異なるものです。 SFAとはSales Force Automationの略で、「営業支援システム」と訳されます。詳しい説明は省きますが、営業進捗の可視化や活動管理を行うものです。 CRMは顧客管理を行う事がメインであることに対して、SFAは営業活動の管理を行うものであるので、根本的に全く違います。 SFAとCRMはセットで使うととても強い では、全く違うものだから、相性が悪いのかと言われれば、そうではありません。 寧ろとても強い効力を持ち、SFA・CRM双方において相乗効果を持ちます。 例えば、CRMの基盤を整えた上で、SFAを配置すると、 顧客情報を的確に営業職にコミットした営業活動を促進することが出来ます。 且つ、顧客関係のカテゴライズ化や商談・受注の情報などを管理することにより 成功フォーマットを作成することが出来るなどのメリットがあります。 つまり、CRMとSFAを一緒に活用することで、 的確なアプローチをもって、営業活動を行うことが出来る 受注成功情報や、企業分析などを行うことが出来るようになる。 気が付けない需要に気が付くことが出来るようになる。 など、色々な旨味を得る事が出来るというわけです。 最後に 今回は、CRMについて説明してみましたがいかがでしたでしょうか。 新卒ながらに知っている「CRMとは何か」について書いてみました。 正直、この文章を書きつつ、「まだまだ、分かっていないなぁ」と思いながら書いていました。もっと深い部分にCRMの底力と魅力があると思っています。 より多くの人にマイナビを知ってもらう為にも、新卒として様々な勉強をしていきたいと思います。 投稿 最近流行りのCRMとはいったい何だ!? は マイナビエンジニアブログ に最初に表示されました。
アバター
はじめに 皆さん、こんにちは。ITディベロップメント1部のS.Tです。 この記事では、私がベトナムの協力会社と協業で、弊社の既存業務システムの約700件のテストコードを3ヶ月で実装したときの話を紹介しようと思います。 背景 この案件が発生した経緯について説明します。 過去に、とある事業部の業務システムを内製し、保守運用をしていました(PHP,Laravelを使用)。 そのシステムは、開発当時はスモールスタートかつスピード重視だったため、テストコードを書いていませんでした。事業部の成長と共にシステムが拡張されていく中で、既存のPHP,Laravelのバージョンでは限界があり、アップデートの必要性が高くなっていきました。 しかしシステムの規模的に、バージョンアップをしたとしても不具合が頻発する危険性があります。そこで、テストコードを作成し、ソースコードの品質を担保する必要があるという話になりました。   ただ、一つ大きな問題がありました。それは、システムの規模が大きくなりすぎてしまったため、当時の社内のリソースだけで開発を進めると時間がかかり過ぎることでした。 そこで白羽の矢が立ったのが、当時丁度提携したばかりの ベトナム の協力会社N様でした。 開発の流れ 協力会社N様と協力して開発を進められることになりましたが、その前に弊社の方で協力開発のための準備をする必要がありました。 具体的には以下の準備を行いました。 テストを実行できる環境を用意 開発スケジュールの決定 協力会社N様との連携方法の決定 テストを実行できる環境を用意 弊社でPHP、Laravel のテストコードについての技術調査を行い、どのメソッド単位でテストを行うかを決定し、実際に自らテストコードを書いてみたりしました。 開発スケジュールの決定 これに関しては、開発の工数を大まかに見積もり期限を設けました。また、テストのチェック内容を定義し、協力会社N様が何を実装すれば良いのかを明確にしました。 協力会社N様との連携方法の決定 週に一度協力会社N様とのオンラインミーティングを行い、お互いの進捗確認をしました。また、仕様の確認やソースコードのレビューに関しては、SlackとGitHub上で英語で行うことになりました。 補足 先ほど英語でやりとりをするとの話がありましたが、当時非常に不安だった記憶があります。というのも、システムの仕様が複雑な部分の細かいニュアンスをうまく伝えられないのではないかや、先方の質問にうまく英語で答えられないのではないかと考えていたからです。 実際には、オンラインミーティングでは先方に通訳の方がいたため、日本語でコミュニケーションを取ることができました。また、SlackとGitHubでのやりとりではGoogle翻訳などのツールを活用したことで、比較的スムーズに連携ができました。 実際の開発 事前に準備した内容をもとに開発がスタートしました。開発の流れとしては、週一回の定例会で先方の2週間分のタスクとその進捗、弊社のレビュー状況を確認するといった流れで進めていきました。開発自体は滞りなく進められてはいましたが、実際に開発が始まると想定外の事態が起きるものです。今回の場合は、以下2点が特に印象に残っている想定外の事態です。 技術的な提案を先方の方からしてくれる 先方の開発スピードが速すぎてレビューが追いつかない 技術的な提案を先方の方からしてくれる これに関しては、弊社としても非常に助けられました。結果的に提案していただいた内容の多くを採用し、開発速度を加速させることができました。 先方の開発スピードが速すぎてレビューが追いつかない これは完全に弊社側のリソース不足が原因だったのですが、先方の開発スピードが速すぎて、レビューがどんどん溜まって行く事態が発生してしまいました。この事態を解消するために、しばらくレビューばかりしている時期もありました。笑 二つとも良い意味での想定外で、こういった要因もあって最終的に、あらかじめ設定していたスケジュール通りに開発を終えることができました。 まとめ 上記のように、当初不安に感じていた英語でのやりとりも問題なく行うことができ、先方からの提案や想定外の開発スピードのおかげもあり、結果として表題にあるように、約700件のテストコードを3ヶ月で実装することができました。 終わりに 以上、ベトナムの協力会社と共に約700件のテストコードを3ヶ月で実装した話でした。 私自身も、初めて海外の方と仕事をするということもあり、不安に思うことも多かったですが、先方の通訳の方とGoogle翻訳に助けられ、なんとか完遂することができました。 英語での会話はできなくても、読み書きが最低限できれば問題なく業務遂行ができることはわかりましたが、次回同じような案件にアサインされた際にもっとスマートに格好よく業務遂行できるように、英語の勉強をしっかりしようかなと思った次第です。笑 長くなりましたが、最後まで読んでいただきありがとうございました。 投稿 既存業務システムの約700件のテストコードを3ヶ月で実装したときの話 は マイナビエンジニアブログ に最初に表示されました。
アバター
はじめに 2023年11月15・16日、4年ぶりに Google Cloud Next Tokyo'23 が東京ビッグサイトで開催されました。 当記事では筆者が参加した15日の内容についてレポートします。 イベント内容 Google Cloudを導入している企業のリーダーがビジョンや取り組みについて話をする 基調講演 、9つのジャンルに分かれた各企業の取り組みやクラウド活用事例が聞ける ブレイクアウトセッション 、Google Cloudの操作を学べるハンズオンセッション、各企業のブースで最新のサービスや事例を知ることができる Expo 、Google Cloudのデモも体験できるエンジニアのための Innovators Hive など様々なプログラムが用意されていました。 ブレイクアウトセッション 今回参加したブレイクアウトセッションのうち2つをピックアップします。 11冠エンジニアを輩出した組織とは?チーム立ち上げのための6つのキーポイント 講演者 株式会社G-gen 執行役員 CTO 杉村 勇馬 氏 講演概要 株式会社G-genは、Google Cloudインテグレーターで、2021年9月はエンジニアの数は杉村さん1名でしたが、2023年11月現在は23名にまで増えている状況。 スタートアップの企業でなおかつGoogle Cloudという先端技術に触れているということもあり、採用基準ではカルチャーマッチを1番に意識しています。 例) 攻めていくようなスタートアップの気持ちがあるか 教育制度を一緒に作ってもらえるか また、採用時点では23名中14名がクラウド経験者であり、そのうちGoogle Cloudを知っている方は5名でした。したがって、入社後に徐々にGoogle Cloudのプロフェッショナルへ成長していく流れとなっています。現在では11資格のコンプリート者が8名いる状況。プロ資格を持っている方は21名、パートナートップエンジニアとして選出されたのは9名です。 6つのキーポイント 今回の講演のテーマでもあったチーム立ち上げのための6つのポイントは下記になります。 ①分かりやすい行動指針を示す 行動指針などはいくつ作っても覚えられないことは実践できないため、 G-genの行動指針は本来は12個ありますが、 オーナーシップ スピード 成果 顧客視点 の4つを技術部門の行動指針にしています。(サーバーワークスの4つの行動指針) ②全ての業務を成長の場にする スタートアップだからこそエンジニア1人でもいろいろな業務領域があり、クラウドインテグレーション、プロジェクト構築、技術サポート窓口も同じエンジニアが担当しています。 このようなことを部署横断で実施することで、いろいろなエンジニアが複数の業務をできるようにしており、技術マーケティングもすべてのエンジニアにある程度行ってもらっています。(例:テックブログ執筆やウェビナーの登壇など) Google Cloudの正しい知識を身につけることになり、正確かつ論理的な文章を書き、体系的なドキュメントを校正することにもなります。これは、お客様とのプロジェクトにおいて、設計ドキュメントをどのように体系的かつ分かりやすく書くかに繋がっていきます。 ③学習を奨励する文化を作る ★一番重要★ スピードと受注率には相関性があると思っています。 計算式でいくらか出すことはできないが、売上利益の向上に確実には繋がると考えています。 【G-genが行っていること】 資格試験の受験代金全額補助 勉強会の奨励(業務時間中OK) 知識のシェアの奨励 (★特に重要) Slackで技術的な質問をすると、誰かが率先してすぐに答えるような仕組みをつくっています。技術マネージャーが率先して実施していかないとこの流れはできません。 ④資格を正義にしない 【資格は持っているが仕事はできない人に決してなってほしくない】 レベル0-100で段階を分けたとすると… 100⇒①要件定義・設計に活かせるレベル 75⇒②技術者として深く説明できるレベル 50⇒③嚙み砕いて理解(腹落ち)したレベル 《資格合格はこのレベルにすぎない》 25⇒④概要を把握したレベル 0⇒⑤名前しか知らないレベル ⑤会社の中に閉じない エンジニアは閉じこもりがちだと考えています。 そのため、お客様と積極的に技術交流や懇親会などを行うことを奨励しています。 これにより、以下のメリットが得られると考えています。 技術的な知見がプラスになる 新しいビジネスに繋がる可能性 外の世界が見えて見識が広がる 『世界が広がると技術力の幅も広がる』と考え、少しでもお客様と接点を持つことを励行しています。 ⑥コミュニティに貢献する 【コミュニティには参加せよ】 エンジニアには、コミュニティに参加することを奨励し、業務時間中の活動も許容しています。 前述と同様にメリットとしては以下のようなものがあると考えています。 技術的な知見がプラスになる 新しいビジネスに繋がる可能性 外の世界が見えて見識が広がる 感想 G-genがこの短期間で社員を増やしつつ、それぞれのスキルを高められているのはこういった仕組みがつくられているからなのだと知ることができました。 『世界が広がると技術力の幅が広がる』はまさにそうだなと思いましたし、 知識やスキルを得るためにインプットアウトプットする機会をもつ必要性を改めて感じました。 そのためにも会社という狭い世界の中だけでなく、外に出て新たな発見が得られるような風土をつくらなければいけないと思いました。 グローバルNo.1サービスを目指すmeviyに、なぜカルチャー推進が重要なのか?~社員の自己肯定感を高める#IAmRemarkable エンジニアに限らず、Google発信のワークショップを紹介するセッションもありました。 講演者 株式会社ミスミID企業体IDマーケティング推進室 ジェネラルマネジャー 大川 英恵 氏 Google Cloudパートナー事業本部Partner Development Manager,Data Analytics 小澤 真由子氏 講演概要 事業拡大に伴って、海外チームが加わり、コミュニケーションカルチャー等に課題が出てきた株式会社ミスミ。「困った」「わからない」「仲間が欲しい」に対してすぐに繋がれるコミュニティーを作ることを目的とし、公募で社内プロジェクトを募ってチームを結成。この課題を解決すべく実施したのが、Googleが提供する「IAmRemarkable」という取り組みです。 この取り組みは、ワークショップという形で提供されていて、もともとは女性やマイノリティの方々が自分の意見をしっかり言えるようになるための、という目的で始まりましたが、次第にマイノリティだけではなくどんな人にもこのワークショップが必要であると認識され始めるように。職場などのあらゆる場所で自分の実績をオープンに語ることを目指しています。 業務と関係ない取り組みに参加して良いのか、というメンバーのためらいや、ポジティブに集まったメンバーでもなるべく負荷をかけずに実施するにはどうしたら良いか等運営方法へ課題もありましたが、多様性とマイノリティグループを後押しし、モチベーションと自己肯定感の改善、チームの結束強化が狙えるこの取り組みで、同社はただ心理的安全性を実施するのではなく、なぜ必要なのかを事業部全体で理解することが出来、イノベーションを起こすカルチャーづくりを推進することが出来ました。 感想 カルチャーづくりを考えた際に、仕組みを整える、担当を決める…等ではなく、「困ったときにすぐ繋がれるコミュニティを作る」はなかなか出てこない、出てきても実現に意外とハードルが高い箇所なのではと思っており、実現されている力強さと、その意欲に対してアンサーが出来る取り組みとの両方に感銘を受けました。 組織活性、連携強化を目標に掲げる組織は多いかと思いますが、「そもそもなぜやるのか?」の部分についてもしっかりとフォーカスする、かつ”組織の全員が”その理由と重要性を理解する、というところまで落とし込めているかというと、出来ていない組織の方が多いのではないかと思います。本質の目線が合っていないと、どうしても必要な時に協力し合えないので、この研修を通して、お互いを知り、「なぜ必要なのか」を理解し合うことで、本当に連携が取れた組織が作れていくのが理想ではないかと感じました。 おわりに 今回は2講演をピックアップしましたが、興味を引くものが多く、講演時間が被っていて泣く泣くいずれかに絞ったものや、申し込み定員オーバーで断念したものも多く、心残りも…。 次回の開催も楽しみにしています! 投稿 Google Cloud Next Tokyo’23 参加レポ は マイナビエンジニアブログ に最初に表示されました。
アバター
何の記事? AIで画像に 悪夢 のような変換を施す手法を紹介します! 例)集合体が苦手な方は閲覧注意です… ※画像はtensorflowより引用 ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ この手法を TensorFlowのチュートリアル 通りに実装する際の流れの解説とTips 実際に試した例 を紹介する記事です! 何に使うの? 画像認識でDNN(Deep Neural Network)がちゃんと学習できているのかを可視化できる 深層学習ではモデルの予測が何を根拠に判断されているかが分からないという問題があり、その解決方法の一つ 同様の可視化手法で有名なのはCAM(後述) コンピュータービジョンの表現方法としての可能性 実際にプロのアーティストのミュージックビデオで使用されている Doing It for the Money (Foster The People) ◦ 0:37~をご覧ください 説明 概要 DeepDreamとは Alexander Mordvintsevによって作成されたコンピュータービジョンプログラムです。 画像の分類をするために学習した特徴を、逆に画像に足して出力することで悪夢のような変換をしています。 TensorFlowのチュートリアル通り に実装すれば任意の画像で変換可能。 チュートリアルではimagenet(物体認識ソフトウェアの研究で用いるために設計された大規模な画像データベース)で学習した機械学習モデルを使用しています。 やり方 チュートリアルを参考に、好きな画像でやってみましょう!! 基本的な流れを紹介し、ちょっとずつTipsも加えます。 画像を用意 ・変換前の画像を用意します。 ・Tips:画像があまり大きいと時間がかかることがあります! 特徴抽出モデルを用意 ・チュートリアルではInceptionV3を使用しています。 ・InceptionV3は、GoogLeNet (Inception v1) を改良したモデルです。tensorflowではImageNetによる事前学習済みモデルが用意されています。 ・ Tips : InceptionV3でなくとも任意の事前学習済みモデルを使用できます! KerasのAPI には多くの事前学習済みモデルがあるため、モデル変更の際はそちらを試してみるといいかもしれないです! また、 事前学習済みモデルを任意のデータセットで転移学習したものを使う ことにより、任意の悪夢風変換を行うこともできます! このあとの章で 自分の顔で転移学習したものを使った例 を載せています。 損失を計算 ・チュートリアルの損失計算部分では、選択した各レイヤーのすべての平均を取り、全レイヤーの平均値を合計したものを返しています。 勾配上昇方 ・普通は勾配降下法で損失を小さくしていきますが、DeepDreamでは入力画像に対して計算した勾配を元の画像に追加する勾配上昇方で変換を行っています。 その他補足 チュートリアル内で選択した画像の変換に使うレイヤーは、選択したレイヤーを最終層としたモデルを作成するのにつかわれています。つまりInceptionV3を指定レイヤーの部分で区切ったモデルを使って勾配の抽出を行っている感じです。 ↓レイヤーを選択している部分↓ # Maximize the activations of these layers names = ['mixed3', 'mixed5'] layers = [base_model.get_layer(name).output for name in names] 基本は変換したい画像に対して勾配を計算して元の画像に足すだけですが、 勾配を小さくしたやつを何回も足すようにするとイイ感じになります! img = img + gradients*step_size 入力画像を拡縮してちょとずつ勾配を足してもイイ感じになります(Octaveという手法) def octave(original_img): OCTAVE_SCALE = 1.30 img = tf.constant(np.array(original_img)) base_shape = tf.shape(img)[:-1] float_base_shape = tf.cast(base_shape, tf.float32) for n in range(-2, 3): new_shape = tf.cast(float_base_shape*(OCTAVE_SCALE**n), tf.int32) img = tf.image.resize(img, new_shape).numpy() img = run_deep_dream_simple(img=img, steps=50, step_size=0.01) img = tf.image.resize(img, base_shape) img = tf.image.convert_image_dtype(img/255.0, dtype=tf.uint8) return img CAMとの違い 同様の画像分類モデル可視化手法であるCAM(Class Actiovation Mapping)では、勾配を取得し分類スコアに最も影響を与える入力画像の部分を識別します。 CAMの一般化手法であるGrad-CAMでの出力例 このような出力をするにあたり、CAMでは重要度をヒートマップで表した画像を新たに作成し、元の画像の上に薄く重ねます。 それに対してDeepDreamでは入力画像に対して計算した勾配を、小さく薄めて元の画像に直接足しています。 転移学習で任意の変換をしてみた ざっくりとした流れ 顔写真をたくさんあつめてデータセットを作る ↓自分の画像↓ tensorflowの転移学習チュートリアル に従ってInceptionV3を転移学習しました。(犬と猫のデータセットを自前のデータセットに置き換えるだけです) 転移学習後、InceptionV3のレイヤーConv2dの5と6を選択してDeepDream ↓選択レイヤーを出力にした勾配計算用のモデル図↓ 結果 若干髪の毛などの特徴で変換が行われている、、、? おわりに 以上、悪夢のような画像変換を行うAI手法「DeepDream」の紹介でした。 手法自体は少し昔のものですが、内容はインパクトがあって面白いと思い紹介させていただきました。 昨今流行っている画像生成AIよりも仕組みは簡単だと思うので、この記事を見て興味を持った方はぜひトライしてみてください。 おまけ・勾配を小さくしないでそのまま入力画像に足した場合のDeepDream Stepsizeを0.1にするとこんな感じでした。 ノイズに近いですね。ちょっとゴーギャンっぽい? 投稿 DeepDreamによる悪夢のような画像変換 は マイナビエンジニアブログ に最初に表示されました。
アバター
記事の説明 この投稿は、ファシリテーター未経験者の私が部署内でワークショップを開催し、その経験から学んだことについて書いたものです。 自己紹介 私は新卒で企画職として採用され、新規事業の企画やローンチ後のプロダクト施策提案を主業務とする部署に所属しています。配属されて数か月ですが、社内の様々な人とコミュニケーションを取りながら業務を進めていくことに楽しさを覚えています。 今回は、部署内で初めてワークショップを開催し、その経験から学んだ「場づくり」の大切さについてお話ししようと思います。 ワークショップの内容 私が開催したのは「カスタマージャーニーマップ」を作成し発表するワークショップです。ベンチマーク本として『はじめてのカスタマージャーニーマップワークショップ(加藤希尊著)』を参考にしました。 カスタマージャーニーマップを通じて、顧客の現状(As Is)を把握し顧客のあるべき姿(To Be)までの旅(フロー)を想像することで、精度の高い仮説を導き出すことができます。各自が持っている企画案のターゲット顧客の状態や感情を書き出し、顧客への理解を深められれば良いなという想いで行いました。 企画した背景 一般的にカスタマージャーニーマップは、マーケティング業務の中の販促フローを考える時に使われることが多いです。ではなぜ、ローンチ前の企画段階で顧客を考える必要性があると考えたのか。 それは、株式会社コーセーの商品企画を担当した青山陽一郎さんの動画を拝見し、顧客の状態を企画段階で言語化することの重要性を学んだためでした。 商品企画で大事なことは【自分ごと化による熱意と自信を持つ「共感」×分析・解釈により根拠を証明する「説得力」】が重要と述べられていました。どんなに質のいい商品だとしても、顧客に「共感」してもらわなければ商品は売れないのだと解釈しました。まずは顧客のことを考える、そこから商品の価値を見いだせるのではないかと考え、ワークショップを企画しました。 出典: 商品企画で大事なコト ~コーセーでの商品企画経験を事例に~ | GLOBIS学び放題×知見録 (ちなみにこのコンテンツは、弊社福利厚生の一つにある『GLOBIS 学び放題』内で視聴できます。福利厚生が充実していることは弊社のバリューであり有難く活用させていただいています!) いざ開催 ークショップは2時間で行いました。ワークでは、各自で企画テーマを決め、ペルソナを具体的に想像し、カスタマージャーニーマップを作るといった作業工程で行いました。 通常このようなワークショップは体感半日~丸一日かけて取り組むものですが、今回は業務時間中ということで時間を短めに設定しました。限られた時間の中で熱心にワークに取り組んでいただいた先輩方、ありがとうございます! ワークショップの手順 ※08番は時間の都合により省略しました。 参加者のシート1 参加者のシート2! 参加者は7つの手順に沿って、顧客の感情や状態について付箋や印刷物を用いてシートを作っていきました。最終的に、参加者全員がカスタマージャーニーマップを完成させることができました。 とりあえずこのワーク自体は最後までやり遂げることができました。 振り返り さて、ここからは振り返りです。 ファシリテーターとしての技量、ワークの環境、完成度など踏まえた自己評価は以下の通りです。 自己評価 40点/100点 理由 「場づくり」の大切さを理解していなかった 今後の対策 1. 当日対応は先回りして用意すべし 当日のワークの中でこのような質問や要望をいただきました。 シートの書き方を教えてほしい →説明していなかった 記述例はないのか?→用意していなかった 合間に連絡業務が入りワークが一時中断してしまった→仕方ない 参加者の中にはカスタマージャーニーマップのことを知らない方も当然います。そんな環境下では、参加者の知識量、心理的状態、考えていることに応じて用意するものを先回りして考える必要がありました。当日なにが起きても大丈夫なように、チェックシートなど作りながらワークショップの精度を上げていきたいところです。 2. 参加者が心地よく感じられる型を意識するべし みなさんにとって心地いいデザインがあるように、ワークショップにも心地いいデザインがあるみたいです。株式会社MIMIGURIの安斎勇樹さんは、ワークショップをデザインすることは、「経験のプロセス」をデザインすることであると述べています。経験のプロセスをデザインするためには、「学習環境」を有機的にデザインすることが大事なのだとか。 上記の説に従うと、今回のワークショップは、使える時間が参加者にとって豊かな経験になるようにプロセスをデザインすることができていなかったなと振り返ります。参加者同士のアイスブレイクの時間を設けていなかったり、参加者が手を動かす時間が長すぎたりと、見直す部分がたくさん見つかりました!今後は、ワークショップの内容と併せて、参加者にとって心地のいいワークショップにするために学習環境を有機的にデザインしていこうと思います。 出典: ワークショップをデザインするとはどういうことか|安斎勇樹 おわりに 今回、ワークショップを開催したことで、多くの課題を見つけ出せたことは大きな収穫だと捉えております!また、ファシリテーター未経験だからこそ分かった「場づくり」の大切さを肌で感じることができてよかったです。 顧客視点に立った企画立案は今後も業務で必要不可欠になってくるため、今回の振り返りを糧にアップデートをしていきたい所存です。これからも日々精進してまいります! (´っ・ω・)っ メリクリ! 投稿 ワークショップを開催して学んだ「場づくり」の大切さ は マイナビエンジニアブログ に最初に表示されました。
アバター
はじめに GCPにはさまざまなストレージサービスやデータベースサービスがあります。 GCP試験の勉強中、頭がごちゃごちゃになったポイントでした。(私の場合) 今回は6つのストレージサービスについて簡単にまとめていこうと思います。 Google Cloud Storage(GCS) 特徴 オブジェクトストレージサービス 容量無制限 低価格 ◦Amazon S3と同じ感じ いろいろ ストレージクラス GCSには以下の4つのストレージクラスがあります。 種類  説明 例 費用目安 Standard  アクセス頻度の高いデータや短期間だけ保存されるデータ用。 ウェブサイト、ストリーミング系、モバイルアプリ $0.02~[GB 単位/月] Nearline 月一程度のアクセス頻度のデータ保存用。 30日以上保存が必要なバックアップデータ $0.01~[GB 単位/月] Coldline 四半期に一度程度のアクセス頻度のデータ保存用。 90日以上保存が必要なバックアップデータ $0.004~[GB 単位/月] Archive 年一程度のアクセス頻度のデータ保存用。 データアーカイブ、バックアップ $0.0012~[GB 単位/月] ユースケース 画像、テキスト、動画、その他のファイル形式などいろんなものを入れたいとき。 頻繁なアクセスのないバックアップデータなど。 非構造化データ置き場 基本はS3的な使いどころ Cloud SQL 特徴 フルマネージドなリレーショナルデータベースサービス MySQL、PostgreSQL、SQL Serverを使用可能 適切なディスクタイプとサイズを選択可能 ◦専用コア: 最大 64 TB ◦共有コア: 最大 3 TB いろいろ Cloud SQLの特長を掘り下げていこうと思います。 高可用性(HA構成) プライマリインスタンスと別のゾーンにスタンバイインスタンス配置 ◦プライマリインスタンスとスタンバイインスタンスは同期レプリケーション ◦障害時、スタンバイインスタンスにフェイルオーバー リードレプリカ リードレプリカは非同期レプリケーション 読み取りワークロードの負荷分散が可能 ※クロスリージョンレプリカ:リージョン間でのデータ同期が可能 ユースケース リレーショナルがいいけどオートスケールが不要な時 PostgreSQLを使用するとき CRM ERP系 Eコマースやウェブ系 SaaSアプリの構築 BigQuery 特徴 サーバレスで費用対効果に優れたエンタープライズデータウェアハウス 大量のデータセットを格納しながら即時処理が可能 データクエリ用の双方向性のあるSQLインターフェイス いろいろ データドリブンな分析機能がいくつかあるのでまとめていきます。 リアルタイム分析 イベント ドリブンな分析でビジネス イベントにリアルタイムで対応することが可能 組み込みのストリーミング機能あり ◦ストリーミングデータを自動的に取り込み、すぐにクエリが可能 予測分析 レコメンデーションと検出のシステムの構築が可能 BigQuery と BigQuery ML を使用する必要がある ◦BigQuery ML :BigQuery で GoogleSQL クエリを使用して機械学習モデルを作成し、実行することができるもの ログ分析 ログデータを保存して探索したり、クエリを実行することが可能 ◦Googleアナリティクスで収集しているデータ(メジャメントプロトコル)をBigQueryに送り、集計・可視化することも… マーケティングデータウェアハウス スケーラブルなマーケティングデータウェアハウスの構築が可能 ◦BigQuery でマーケティング データと広告データを統合 ◦キャンペーンあたり、ユーザーあたりのコンバージョンに与える影響についての記述的分析 ◦BigQuery はキャンペーン マネージャー 360 の元データにアクセスできるため、この情報を利用可能 B ユースケース 大規模なデータ分析 SQLを使ったビッグデータ処理 Cloud Bigtable 特徴 フルマネージド NoSQL ビッグデータのデータベース サービス 数十億行、数千列の規模にスケール可能(=数テラバイト、あるいは数ペタバイトのデータを格納可能) ◦Google 検索、アナリティクス、マップ、Gmail など、多数の主要サービスを支えているのと同じデータベース いろいろ 個人的に料金体系がパッと見だとよくわからなかったので要点をまとめます。 課金対象 ◦Bigtable インスタンスのタイプ、使用しているインスタンスのクラスタに含まれる合計ノード数   ◦数/時間 ◦テーブルで使用しているストレージ量   ◦GB/日   ◦1か月での平均値から、月額を算出 ◦ネットワーク帯域幅の使用量   ◦GB/日 Cloud Bigtable の料金の公式ドキュメント には、事例に基づき料金の例が載っているので大変助かります ユースケース 時系列データ ◦複数のサーバーにおける時間の経過に伴う CPU とメモリの使用状況など マーケティング データ ◦購入履歴や顧客の好みなど ◦低レイテンシーな読み書きを要するシステム   ◦IoT・AdTech・金融サービス等 グラフデータ クレジットカードの不正利用検出(にも活用できるらしい) Cloud Spanner 特徴 無制限のスケーリング リージョンにわたる強整合性 最大 99.999% の可用性※マルチリージョン構成の場合 フルマネージド いろいろ Spannerの特長的な部分をいくつかピックアップします。 強整合性と水平スケーリングの両方が可能 Spannerはリレーショナルデータベースなので強整合性を保証しつつ、 noSQLデータベースでもあるため、グローバルに水平スケーリングが可能です。 (なかなか珍しいらしい…) 読み取り方式 Spannerには「強力な読み取り方式」と「ステイル読み取り方式」があります。 「強力な読み取り方式」 ◦デフォルトの読み取り方式 ◦強整合性を持った読み取りが可能◎ ◦読み取りの都度最新のデータであるかチェックするため、 内部通信が発生しレイテンシが大きい△ 「ステイル読み取り方式」 ◦高速な読み取りが可能 ◦レプリカ自身が持つ最新のデータであるかのチェックをスキップする   ◦強整合性が重要ではない場合は良さそう ユースケース ミッションクリティカルなシステム ◦AdTech・金融サービス等 ポケモンGOはこちらを使用しているらしい Datastore 特徴 アプリケーション向けのNoSQLデータベース シャーディングとレプリケーションを自動で処理 負荷に合わせて自動的にスケールが可能 可用性と耐久性に優れている いろいろ Datastoreの特徴的な機能についてまとめていきます。 ACIDトランザクション 単一のトランザクションで複数のデータストアオペレーションを実行するACIDの特性により、データの整合性を確保 ◦不可分性(Atomicity) ◦貫性(Consistency) ◦独立性(Isolation) ◦永続性(Durability) 多様なデータ型 複数のデータ型が使用可能 ◦整数 ◦浮動小数点数 ◦文字列 ◦日付 ◦バイナリデータ 管理ダッシュボード さまざまな機能をダッシュボード上で使用可能 ◦エンティティ統計の表示 ◦データベースのクエリ ◦インデックスの表示 ◦データのバックアップと復元 ユースケース どれだけ増えても処理速度の変化を発生させたくないもの ゲームデータ ユーザデータ Google App Engineのデータベース さいごに 今回は6つのストレージ・データベースサービスについてまとめてみました。 それぞれの特長によって、使い分けしていきたいと思います。 投稿 GCPのストレージ・データベースサービスたちをまとめてみた は マイナビエンジニアブログ に最初に表示されました。
アバター
はじめに GCPにはリソース階層というものがあります。 私がしょっぱなで躓いたところです。 前提として階層の関係性と役割を理解していないと、GCPまわりのドキュメントが何も理解できませんでした…。 「最低限この理解があれば先の勉強に進むことができた」レベル感でリソース階層についてまとめてみました。 階層構造の全貌 階層構造を図で表すとこのようになります。 大きい枠組みとして組織ノードがあり、配下にはフォルダがあります。 フォルダではフォルダ自体をまとめることも可能です。 フォルダの配下にはプロジェクトがあり、各リソースはプロジェクトに紐づいている形になります。 下層から見ていくと理解がしやすいかなと思いますので、まずはリソースからまとめていきます。 リソース リソースとは、GCPでシステムを構築していく際に使用するサービスのことです。 具体的には、サーバを使用したいときに使うGoogle Compute Engine、ストレージを使用したいときに使うGoogle Cloud Storageなどのことです。 このようなGCPサービスのことをリソースと呼びます。 (AWSでもリソースっていいますね'ω') リソースは、1つのプロジェクトに属します。 プロジェクト GCPにて構築するシステムの単位です。 プロジェクトを使用することで、システムごとに管理することが可能です。 具体的な管理内容の例として、以下のものがあります。 請求の管理 ◦プロジェクト単位で請求が発生します。 ◦発生した費用の請求先アカウントを指定できます。 ユーザの管理 ◦プロジェクトごとにオーナーとユーザの作成を行い、管理することが可能です。 プロジェクト自体は以下の形式で管理します。 「名前・プロジェクトID・プロジェクト番号」 名前 ◦任意 プロジェクトID ◦永続的かつ不変なGCP全体で一意 ◦基本的に自動割り当て     ◦ただし自分でも決められる プロジェクト番号 ◦固有 プロジェクトはフォルダに属します。 フォルダ 部署、部門、チーム、アプリケーションなどの単位でプロジェクトをまとめることが可能です。 複数のフォルダをフォルダをで管理することも可能です。 フォルダを活用するメリットには以下のようなものがあります。 メリット チームの管理権限を付与することで各チーム独立して対応・作業が可能 フォルダ内のリソースはそのフォルダのIAMポリシーを継承 デメリット IAMポリシーの継承範囲を見誤るとミスオペの原因に、、、 フォルダは、フォルダもしくは組織ノードに属します。 組織ノード 階層の最上位で、プロジェクトをまとめて管理することが可能です。 リソースの使用状況の確認とポリシーの適用を一元的に行うことができます。 G Siiteドメインがある場合、GCPプロジェクトは自動的に組織ノードに属します。 そうではない場合はGoogle Cloud Identityを使用して作成が可能です。 組織ノードで付与したIAMポリシーは自動ですべてのプロジェクトに継承されますので気を付けましょう! 最後に 階層構造によって管理を行うのは、GCPとAWSの大きく異なる部分かなと思います。 階層構造の理解ありきでGCPは話が進んでいくことがありうるイメージなので、まずは階層の全体像をつかむ必要があると感じました。 投稿 GCPのリソース階層について は マイナビエンジニアブログ に最初に表示されました。
アバター
はじめに GCPのIAMは、AWSのIAMとはまた別の概念を持っています。 そろそろこんがらがってきたので、GCPのIAMについて思考整理のためにまとめてみました。 IAMについて Cloud IAMとは アクセスの①主体②アクション ③対象リソースを指定することができます。 ⓵ 主体:ユーザ・グループ・アプリ ⓶アクション:特定の権限・操作 ⓷対象リソース:Google Cloudサービス 例えば、Compute閲覧権限ユーザをA君がもらうとすると、以下のようになります。 ⓵主体:A君のユーザ ⓶アクション:読み取りの権限・操作 ⓷対象リソース:Compute Engineリソース 今回は①と②についてまとめてみます。 ①主体 リソースに対してアクションを起こす主体のことを総称して メンバー と呼んでいます。 メンバー には以下の種類があります。 メンバー Googleアカウント Gメールアドレスとの関連付けが可能です。※所謂普通のGoogleアカウントのことです。 GCPを使用するユーザ(開発者や管理者などなど)を指します。 サービスアカウント アプリケーションやVMに属するアカウントの事です。 アプリの様々な論理コンポーネントを表します。 GCDKのコード実行するときなどに使用されるアカウントです。 わかりにくいですがGCP Service Accountを理解するを読んだら理解できました。 ◦インスタンス・イメージ・アプリコード内に鍵や認証情報埋め込まなくてよいっていうのがポイントっぽいです。→(・・? ('ω')。oO(たぶん、AWSのIAMロールに近い感じ…) Googleグループ Googleアカウントとサービスアカウントをグループ化できます。 ◦まとめてアクセスポリシーの適応などが可能です。 workspaceドメイン 「~.com」のような組織のインターネットドメイン名ごとのアカウントです。 workspaceにユーザを追加することで、Googleアカウントが作成されます。 Cloud Identity Google管理コンソールにて、ユーザとグループが管理できます。 50ユーザまで無料ですが、GoogleドキュメントやGoogleドライブなど使用できないサービスもあります。 workspaceドメインに似てます。 ②アクション 特定の権限・操作をまとめたものを ロール と呼んでいます。 ロール には以下の3つの種類があります。 ロール 基本ロール GCP側で準備してくれている役割ごとのロールのことです。 以下の3つがあります。 閲覧者 ◦読み取り専用     ◦既存リソースやデータの表示が可能 編集者 ◦閲覧者権限含む ◦状態を変更するアクションが可能     ◦既存リソースの変更     ◦アクセスの変更削除  など… オーナー ◦編集者権限含む ◦管理者権限     ◦メンバーの追加や削除が可能     ◦プロジェクトおよびプロジェクト内のすべてのリソースの権限とロールを管理     ◦プロジェクトの課金情報を設定  などなど 事前定義ロール 特定のリソースに対するロールのことです。 GCPリソースへのアクセス権を細かく決められるため、他のリソースへの不正アクセスなどを防ぐことができます。 いくつかあるうちの何個か('ω')ノ Compute管理者ロール:Compute Engineリソースに対する全アクション許可 ネットワーク管理者ロール:ネットワークリソースの作成・削除可能 ◦※FWやSSLには適応外✖ ストレージ管理者ロール:ディスク・イメージ・スナップショットの作成・削除可能 ◦※プロジェクトのイメージ管理者にプロジェクトの編集者ロールを渡したくないな…って時に使える カスタムロール カスタマイズが可能なロールになります。 事前定義ロールよりも自分好みの権限の組み合わせにできます。 多くの企業では、  最小権限モデル  が採用されているらしいです。 ユースケース インスタンスオペレーターロールを定義! ユーザにこのロールを付与することで、「VM起動・停止は可能だが再編成はできない」という権限を持ったユーザを発動! バインディングとポリシー バインディング メンバーとロールの紐づけを バインディング と呼びます。 AWSの時はなかった概念の気もするが、強いて言えばterraform使って構築するときのアタッチメントなんちゃらみたいなやつ…? バインディングでは条件を決めることができます。 条件でインスタンス名等を指定できます。AWSの IAM Policy的な奴だと思います。 ポリシー バインディングをまとめたものをポリシーと言います。 誰がどのロールを持つかをまとめたものがポリシーです。 リソースは、上の階層(親)からポリシーを継承となります。 IAMポリシーの階層はGoogle Cloudリソースの階層と同じです。 強さで言うと、「制限の緩い親ポリシー>制限の厳しいリソースポリシー」になります。 親レベルで付与されたアクセス権を子ポリシーで制限はできないです。 って事で最小限で付与していくのがベストプラクティスになるってことですね('ω') さいごに(かんそう) 権限の分断などが細かくできるので、複雑には見えますが使いこなすとかなりいい感じに開発・運用ができるなと思いました。 特に大人数でいろんな立場の人がいるプロジェクト等ですとかなりいい感じに思います。 ポリシー継承のIAMの決まりなども複雑なので、GCPのリソース階層とIAMの関係についても今後まとめてみたいと思います。 投稿 【学習メモ】GCPのIAMについて調べてみた は マイナビエンジニアブログ に最初に表示されました。
アバター
はじめに ITD 2部1課 のM・Sです。 CSS Gridを学ぶ際に、面白いサイトを紹介していただいたので共有させていただきます。 そもそも、CSS Grid とは? CSS Grid Layout(グリッドレイアウト) は、二次元のレイアウトをCSSで自由に操作できる機能です。 格子状のマス目にグリッドを好きな順番におけたり するので複雑なレイアウトを従来よりも簡単に実装することができます。 ↓みたいなレイアウトを簡単に実装できる。 なぜグリッドレイアウトがいいのか 従来のWebサイトでは、 flex を使用してレイアウトを作成していきます。 flex とは、横並びのレイアウトを簡単に実装できるプロパティーです。 flexでも、十分レイアウトすることはできるのですが、問題点として、 "無駄なネストが増える" "要素の並び替えが難しい" という問題点がありました。 こちらの画像のようなレイアウトを実装しないといけない場合。 flexでは、こんな感じで実装します。 <style> body { width: 200px; } header, nav, article, footer { border: solid 1px #333; box-sizing: border-box; } header { height: 30px; } div { display: flex; } nav { width: 30%; } main { width: 70%; } article { display: block; height: 30px; } footer { height: 30px; } </style> <body> <header>タイトル</header> <div> <!-- ←横並び用のdivタグ --> <nav>ナビ</nav> <main> <article>記事1</article> <article>記事2</article> <article>記事3</article> <article>記事4</article> </main> </div> <footer>フッター</footer> </body> タイトル + ナビと記事の横並び + フッター のようなイメージですね。 シンプルなレイアウトでさえ、divタグのように ネストしてしまっていることがわかります。 gird だと、こんな感じで実装します。 <style> header, nav, article, footer { border: solid 1px #333; box-sizing: border-box; } body { width: 200px; display: grid; grid-template: repeat(6, 30px) / 30% 70%; } header { grid-area: 1 / 1 / span 1 / span 2; } nav { grid-area: 2 / 1 / span 4 / span 1; } main { grid-area: 2 / 2 / span 4 / span 1; } article { display: block; height: 30px; } footer { grid-area: 6 / 1 / span 1 / span 2; } </style> <body> <header>タイトル</header> <nav>ナビ</nav> <main> <article>記事1</article> <article>記事2</article> <article>記事3</article> <article>記事4</article> </main> <footer>フッター</footer> </body> タイトル + ナビ + 記事 + フッター のコンテナごとに 二次元配置が可能になるため簡単に実装することができます。 今回の例だとdivタグがあるかないかの差ですが、 要素が増えれば増えるほどこのネストが発生するので、 flexの使いすぎで深いhtml構造になってしまう ということでできることなら grid を使っていきたいですね。 さらに上記では活用していませんが、 grid は順番を気にせず配置できる ので、レスポンシブ等で 表示の順番が大きく変わる際にも対応することが可能 です。 なので今回は、flex を卒業すべく、gridに触れてみようと思います! gird をゲーム感覚で学べる GRID GARDEN そんな、gridレイアウトですが、学べる教材がかなり少ない印象です... 紹介記事などはあるのですが、実際に手を動かしながら学べる教材が殆どありません ... そこで紹介いただいたのが、"GRID GARDEN" でした。 全28ステージあり、gridで使われるプロパティーを色々学ぶことができます。 例えばステージ1だと、 こんな感じで穴埋めのgrid-colum-startのプロパティーが空欄でそれを入れていくという感じですね。 こんな感じで28ステージあるのですが、大体、30分くらいで全ステージできました! Gridレイアウトのプロパティーは一通りさらえたかなという印象でした。 Gridを使ってみたいといった方には、おすすめの内容な気がします! ですが、内容としては "どういうプロパティーがあるか知る" がメインなので もう1アウトプットあればいいなと思いました。 余談 FLEXBOX FROGGY 同様のゲームで flex も学べるみたいです。 他にも面白そうなcssのゲームがありそうですが、紹介した2つ以外は有料っぽいですね https://flexboxfroggy.com/#ja アウトプットしてみる Grid 用いた面白そうな模擬コーディングを探してみたら、良さげな課題があったのでこれを軽くやってみようと思います。 普通のwebサイトでも活用先はあると思うのですが、管理画面の方が1画面で写すコンテンツが多い関係上、gird がより効果的だと思ったのでこれにしました。 課題 https://codepen.io/TurkAysenur/pen/QWyPMgq 実際に書いたコードが こちら です。 (あくまで grid の学習なので、完璧には模写していないのとクラスの命名などをあまり考慮せず実装しています...) ▼画面 PC (1075px ~) ▼画面 タブレット (900px ~ 1075px) ▼画面 SP ( ~ 550px) コードに関しても軽く触れます。 girdの部分のみ抜き出してみました。 こんな感じになります。 <!--簡略版 詳細は上記をご覧ください。--> <body> <h2 class="header-left">TASK MANAGER</h2> <aside class="sidebar">...</aside> <div class="header-right">...</div> <div class="tasks">...</div> <div class="detail">...</div> </body>`` //grid body { display: grid; grid-template: 70px 1fr / 360px 420px 1fr; .header-left { grid-area: 1 / 1 / span 1 / span 1; } .sidebar { grid-area: 2 / 1 / span 1 / span 1; } .header-right { grid-area: 1 / 2 / span 1 / span 2; } .tasks { grid-area: 2 / 2 / span 1 / span 1; } .detail { grid-area: 2 / 3 / span 1 / span 1; } } @media screen and (max-width: 1075px) { body { .tasks { display: none; } .detail { grid-area: 2 / 2 / span 1 / span 2; } } } @media screen and (max-width: 900px) { body { display: block; .header-left { display: none; } .sidebar { display: none; } } }` 終わりに コード書いた感想ですが、grid を使った方が レスポンシブ対応もはるかに楽だと 感じました。 細かい表示非表示はもう少し書いていますが、レイアウトのレスポンシブは大体これくらいでできます。 かなりスッキリかけた印象です。 まだまだ、使いこなせていないですが、積極的に使っていきたいなと思いました。 以上です。 最後まで見ていただきありがとうございました 投稿 ゲーム感覚で “CSS Grid” が学べる “GRID GARDEN” をやってみた は マイナビエンジニアブログ に最初に表示されました。
アバター
はじめに 先日、AWS 認定デベロッパーアソシエイト(DVA)を受験したので、体験記として残します。 これから受験する人の参考になれば嬉しいです。 筆者のスペック 新卒1年目のインフラエンジニア AWS歴 2か月 AWS SAA取得済み AWS認定 デベロッパーアソシエイトとは AWS Certified Developer - Associate AWS DVAはその名前の通り開発者向けの資格です。 公式サイトでは以下の経験を持つ人を本試験の受験対象者と記しています。 少なくとも 1 つの高度なプログラミング言語の深い知識を持つ開発者として勤務した経験 AWS テクノロジーに関する経験 オンプレミス IT の経験、オンプレミスとクラウドのマッピングの理解 他のクラウドサービスでの業務経験 また、AWS認定全体ではアソシエイトレベル(中級者向け)の試験とされており、AWSを用いたアプリケーション開発について1年以上の実務経験を有している人が目安となっています。 試験の内容は以下の通りです。(DVA-C02の場合) 試験時間:130分 問題数:65問(採点対象外15問を含む) 出題形式:択一選択問題または複数選択問題 出題分野: ◦AWS のサービスによる開発 ◦セキュリティ ◦デプロイ ◦トラブルシューティングと最適化 サンプル問題がこちら↓  (※ AWS Certified Developer - Associate (DVA-C02)試験問題サンプル より引用) Q. デベロッパーは、ユーザーがほぼリアルタイムでコメントを投稿したりフィードバックを受け取ったりできるようにする必要があるウェブアプリケーションを作成しています。 これらの要件を満たすソリューションはどれですか (2 つ選択)。 A) AWS AppSync スキーマと対応する API を作成する。Amazon DynamoDB テーブルをデータストアと して使用する。 B) Amazon API Gateway で WebSocket API を作成する。AWS Lambda 関数をバックエンドとして使用す る。Amazon DynamoDB テーブルをデータストアとして使用する。 C) Amazon RDS データベースによってバックアップされる AWS Elastic Beanstalk アプリケーションを作 成する。長期間有効な TCP/IP ソケットを許可するようにアプリケーションを構成する。 D) Amazon API Gateway で GraphQL エンドポイントを作成する。Amazon DynamoDB テーブルをデータ ストアとして使用する。 E) Amazon CloudFront への WebSocket 接続を確立する。AWS Lambda 関数を CloudFront ディストリ ビューションのオリジンとして使用する。Amazon Aurora DB クラスターをデータストアとして使用する。 AWS SAAとの違い AWSの登竜門的な資格としてAWS認定 ソリューションアーキテクトアソシエイト(SAA)があります。 同じアソシエイトレベルの試験ですが、SAAでは幅広いAWSサービスから表面的な内容が出題されるのに対して、DVAでは限られたAWSのサービスから少し深い内容が出題される印象です。 問われるサービスにも違いがあり、SAAではあまり出題されないCode兄弟(Code Commit・CodeBuild・CodeDeployなど)やAWS CDKやCloudFromationなどの構築系サービスなどからも出題されます。 難易度は個人的にはSAAの方が少し高いかなぁと感じました。 得手不得手あると思いますが、SAAは単純に覚えるサービスが多い印象です。逆にDVAはAWS CLIのコマンドオプションなどの細かい部分も出題されるので、普段からAWSを触っていないと難しく感じるかもしれません。 結果 結果は… 合格しました!! 772/1000なのでまぁ微妙なスコアですね… SAAより簡単と言ったもののスコアは下がってしまいました。 全セクションのコンピテンシーは満たせているので良しとしたいところです。 高得点ではないですが、一応合格は合格なので自分が勉強した方法について書いておきます。 勉強方法 勉強方法についてですが、まずAWS認定はSAAとSAP以外の試験は学習教材があまり充実していません。 また、試験自体も定期的に更新されるため最新版に対応していなかったりと注意が必要です。 今回受験したDVA-C02に関しても現状対応している参考書はありません。(※11月末にポケットスタディシリーズからC02対応版が出るみたいです。)そのため、本で勉強することが好きな人には辛い試験だと思います。 私がやった勉強は以下の通りです。 Input Udemy: AWS認定Developer Associate(DVA-C02)試験対策トレーニング C02版に対応してる貴重な学習教材です。2倍速でさらっと見て試験の雰囲気をつかみました。 Udemy Bussinessで無料で受けられるのはすごくありがたいです。 ただし、これだけだと合格は難しいと思います。 書籍: AWSの基本・仕組み・重要用語が全部わかる教科書 結構前に買った本です。AWSのサービスがどんなものかざっくり知るのに便利ですが、あくまでざっくりなのでほかの資料と組み合わせて使うのがおすすめです。 ハンズオン :手を動かすことが一番理解につながるので以下の3つ取り組みました↓ ◦ AWS Codeサービス群を活用して、CI/CDのための構成を構築しよう! ◦ AWS SAMを使ってテンプレートからサーバーレスな環境を構築する ◦ Amazon Elastic Container Service 入門 コンテナイメージを作って動かしてみよう 公式ドキュメント: AWS Documentation 結局ここに行きつきます。詳しくサービスのことを知ろうとするとここを見ることになりますが、読解には訓練が必要です。 その他:ChatGPT(GPT-4) 神です。最近課金してしまいました。 気になったことを投げると参考文献付きで回答してくれるため、学習の効率がすごく上がりました。令和最新版の勉強法です。 ※情報が古い場合もあるため注意が必要です。 Output 模試: CloudTech SAAを受験した際に、Udemyの模試が本番と乖離していると感じたので、契約しました。(検索すれば他にもいろいろあります。) 約5000円で90日間AWS認定全資格の模試が受けられます。 DVAは266問用意されていて分量と難易度がちょうどよかったです。最終的に2周しました。 公式サンプル問題: AWS Certified Developer - Associate Official Practice Question Set (DVA-C02 - Japanese) 公式が20問の模擬問題を出してくれています。解説も充実しているので一度は受けておくのをおすすめします。 私は前日に受けて65%だったのですごく焦りました。 おすすめとしては、まずUdemy+ハンズオンである程度の内容をインプットしたら問題演習をしつつ、足りない知識を公式ドキュメントやChatGPTなどを用いて補うのが一番効率が良いと思います。あまりインプットで完璧を目指しすぎると沼にはまっちゃう気がします。 試験を振り返って いくつか個人的な教訓です。 前日は睡眠をしっかりとる 試験は130分とまぁまぁ長いです。集中を保つのが大変ですし、問題文も専門用語が多くて解読にエネルギーを使うので万全な状態で臨む必要があります。 試験は早めに予約する 試験日を決め、メリハリを付けて勉強をすることが大切です。試験の24時間前まで予約可能ですが、土日に受ける場合は早めに予約しておきましょう。 ちゃんと手を動かす CI/CDやIaCは実際に試してみないとなかなか理解が深まりません。この記事内で上げたハンズオン以外にもネット上にあるものを使って動かしてみるのが大事だと思います。 まとめ 今回めでたくAWS認定を2冠することができました! 資格で培った知識を業務で活かせるように頑張ります。 次はSolutions Architect Professionalか Security Specialtyあたりを受けたいと思います。 p.s. ベンダー資格は受験料が高いので、受験料補助制度(1回までは会社から受験料が出る制度)にすごく助けられています。ありがとうございます。 投稿 AWS認定 デベロッパー アソシエイト (DVA-C02)を受けてみた は マイナビエンジニアブログ に最初に表示されました。
アバター
はじめに 今年もアドベントカレンダーの季節がやってきました。マイナビからも20人以上のエンジニアが参加して、クリスマスまで毎日記事を投稿します! カレンダーは毎日更新されますのでお楽しみに! アドベントカレンダー 2023年12月 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Twitterでも発信中 マイナビの公式Techアカウントでも、毎日更新していきます。 こちらもぜひご覧ください! @mynavi_tech 投稿 アドベントカレンダー2023開催します! は マイナビエンジニアブログ に最初に表示されました。
アバター
はじめに 皆さん、こんにちは。マイナビエンジニアブログ編集部です! この度、デジタルテクノロジー戦略本部(以下:デジ戦)の新オフィスリニューアル工事が完成しました! こだわりが詰まった自慢の新フロアになっています。 今回はそのなかでもTOWN HALLというスペースをメインにご紹介させていただきます。 ぜひこのブログを見て来社気分を味わっていただければと思います。 執務エリア TOWN HALLのご紹介の前に、まずは執務エリアの一部をご紹介させていただきます。 執務エリアはABW(アクティビティベース)を採用し、作業内容や気分によって働くスペースを選択できるようになっています。 ▲全席デュアルモニターまたは湾曲モニターを設置。作業効率を高めて働くことができます。 TOWN HALL TOWN HALL(タウンホール)は、勉強会や懇親会など幅広い用途で活用できるコミュニティスペースです。 執務エリアと隣接しており、ガラス張りの壁には部署名である「Drive Digital Inovasion digital technology strategy division」の文字が!かっこいいですよね。 TOWN HALL内にあるモニターやテーブルは動かすことができるため、会議室とは異なり人数の縛りがなく利用ができるスペースとなっています。 ▲プロジェクターが設置してあるため、プレゼンテーション形式での利用も可能です。 ▲可動式モニターも複数あるため、グループワーク形式での会議も可能です。 ▲壁際にはベンチのような座れるスペースもあるため、多数の社員が集うことができるようになっています。 椅子やモニターなどを移動させて広場のような形にすることもできるので、部署全体での懇親会など大規模なイベントの実施も可能です。 先日もTOWN HALLのお披露目会を行い、多くの社員が飲食を伴いながら交流を深めていました! ▲お披露目会でデジ戦:坂本本部長がお話をされている様子 「このイノベーティブな空間を利用して、社内外を問わないオープンなコミュニケーションを活発化させ、より良いアイデアが湧き出てくるような場にしていきたいと考えています。 そして、そのアイデアを自ら開発し世の中にご提供していく基点にもなれたらと思っています。」 さいごに 今回は新しくオープンしたコミュニティスペースである「TOWN HALL」をメインにご紹介させていただきました。 今後はこのスペースを利用して、社員のスキルアップのための勉強会や交流を深めるためのイベントなどを行っていく予定です。
アバター
はじめに 株式会社マイナビでは実際の仕事を数か月かけて体験していただく就業型インタ―ンシップを実施しています。 本記事はインタ―ンシップに絶賛参加中のK君に就業型インターンシップに参加したきっかけや、実際に参加して経験した業務などをインタビューをさせていただいた内容について記載をします。 自己紹介 情報系の学部に所属している大学3年生です。 大学1年生の時に、HTML/CSS・JavaScriptを授業で習いプログラミングに興味を持ちました。勉強し始めた当初は中々うまくいかず難しいな、と感じていましたが一つ一つ出来ることが増えていく達成感が好きになりました。 就業型インタ―ンシップ参加まで マイナビの就業型インタ―ンシップは「マイナビ2025」経由で応募をしました。情報系の企業に絞って探していた際にマイナビのITコースが募集をしているのを見て、正直マイナビにITのイメージは無かったものの、興味のある教育にも同時に関わることが出来るのではないかと思い応募をしました。 書類選考や面接後から初出勤までは1か月程時間があったので、面接時に聞いた技術のキャッチアップやアルゴリズムを勉強しました。ただ、インタ―ンシップに対して特別準備をするわけではなく自分の知見を更に広めたいという思いから今まであまり触れてこなかった技術を学んでいました。 就業環境について 1日のスケジュール 時間 やること 9:15~9:30 オフィスに出社して1日のタスクを確認 9:30~12:30 タスクを行う・適宜相談 12:30~13:30 お昼休憩(新宿駅周辺でランチ) 13:30~15:00 タスクを行う・適宜相談 15:00~16:30 課会(やったことやお悩みについての共有会) 16:30~17:30 タスクを行う・適宜相談 17:30~17:45 進捗共有・退勤 インターン生は週2~3回の出勤のうち半分程度がリモートワークです。 テスト前や用事がある日にはシフトも柔軟に対応していただくことができました。 オフィス環境 オフィスは新宿駅直結のミライナタワーです。席はフリーアドレスになっていて、出社の時は好きな席に座って作業をします。オフィスには私たちの所属している開発課だけでなく、AIシステム課・マーケティング課・RPA課など様々な組織の方が働いています。毎日座席が違うので気分も変わりますし、オフィスからはスカイツリーなど東京の景色が一望できるのがお気に入りのポイントです。 私は今回のインターンシップで初めて企業のオフィスに入りました。それまではエンジニアはパソコンの前でプログラミングをする事だけが仕事なのかな、と思っていましたが実際に足を踏み入れてみるとそうではなく、ディスカッションなどコーディング以外のこともされていたので驚きました。 ▲会議室での一コマ。大きいディスプレイをみんなで見ながらディスカッション中 仕事内容 使っている技術について プロジェクトにもよりますが、私が参加させていただいたプロジェクトは以下のような技術を利用していました。 PHP データベース 実際にやったこと 社内プロジェクトの機能実装 不明点があればメンターを初めとする社員の皆さんにSlackで質問をしたり、対面で質問をしていました。 学びと感想 本インターンシップは私にとって初めての就業型インターンシップでした。エンジニアとして働くということが今まではぼんやりとしたイメージでしたが、インターンシップに参加した事で仕事のイメージがつき、1人ではなくチームで開発をすることがどういうことなのかを理解することが出来ました。 特に印象的だった出来事としてはエラーが起きたときに、メンターの方に質問をしたときのことです。他の業務があったと思いますが優しく、質問をしやすい環境を作って頂き様々な目線でアドバイスをくださいました。結果として業務も成功し、1つ1つ自分の出来ることが増えたときの達成感を味わうことが出来ました。 また、普段1人ではできないようなことにも沢山挑戦をさせていただきました。マイナビ=自社開発を積極的行っているというイメージもつきましたし、参加前は若手社員の方は「上から言われた指示を淡々とやるのではないか」と思っていましたが様々なことに手を挙げて意欲的にチャレンジをしていらっしゃったのも印象的でした。 ▲メンターの方にエラー内容を相談中 今後の目標 今回、インターンシップに参加して普段自分ひとりでプログラミングをする場合と、企業でチームでプログラミングをしている場合ではレベルにギャップがあることに気付きました。頑張ってそのギャップを少しでも減らせられるようにスキルをあげて行きたいと思います。 様々な年代・バックグラウンドを持った方と働くことが非常に楽しいと感じたので、今後も自分自身を磨いていきたいです。エンジニアとして働きたい、と改めて感じました。 まだまだインターンシップは続くのでもっと沢山のことを吸収できるように頑張ります!
アバター
はじめに 座学嫌いな自分ですが、Udemyを活用してAWS SAA-C03を取得できたので受験記録としてまとめておこうかと思います。 大変恥ずかしながら計画性があまりにもないので、反面教師と捉えてください。(こんなはずじゃなかったのにな) ※ちなみにマイナビでは、自己研鑽ツールの1つとしてUdemy Businessが1人1人提供されていますので、今回はUdemyをフル活用して資格取得しました プロフィール 社会人4年目 文系学部卒 AWS歴 1年前後 入社からずっとオンプレにお世話になってましたが、2022年4月の社内ツールのクラウド化プロジェクトからAWSに関わりを持ち始めました。 ただ、実際の構築は基本ベンダーに依頼しているので、自分ではあまり触れてない…という感じです。1年と言ってもほぼ初心者です。 受験のきっかけ これから本格的にAWS構築・運用に関わるので、知識習得のステップの一つとして受験しました。 受験日は後からでも変更できるし、「1回落ちても再受験無料!」のようなキャンペーンをしていた時期だったので、受験申込のハードルが低かったのも今回の受験の後押しになりました。 試験概要 公式で AWS 認定試験ワークショップ というウェビナーをやっているので、視聴しました。 受講したUdemyコース ① AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得 受験用というより、受験を決める前にAWSの基礎を学ぶために観ました。 (ちなみに私は2倍速視聴しました。) ② 【SAA-C03版】これだけでOK! AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座 基本これやれば大丈夫だと思います。 ハンズオンも含まれているので、業務でAWSを使わない人にも○。 その代わり、ボリュームがかなりあります。 ③ 【SAA-C03版】AWS認定ソリューションアーキテクト アソシエイト試験:短期突破講座(300問の演習問題) 日頃AWS触ってるよ~って人は最悪これだけでもいいです。 出る順で説明してくれてます。 序盤に「アソシエイト試験の出題問題の分析」というセクションがあるので、 これは全員観ておいて損はないと思います。 私は結果的に最後の追い込みに使いました・・・ 勉強の流れ 理想 ③のセクション1,2で試験の概要、出題範囲と傾向を確認 ↓ ②を一通りコツコツ観て(セクション3~7は重点的に)、模試を受験する 間違った箇所や自信がなかった箇所は前セクションに戻って復習 ↓ ③であまり馴染みのないサービスの復習をする 現実(非推奨) ②の基本パート(セクション1~セクション7 S3まで)を観て、問題を解く ↓ 受験日まで残り2日しかないことに気づく ②を観終われない ↓ ③のセクション2で出題傾向を確認し、  ・セクション4~セクション5まで(小テスト含む)  ・セクション6以降のうち、自信がない箇所(小テスト含む) を観る 受験当日 就活のSPIを受けるのと同じく、テストセンターで受験しました。 必要なのは身分証明書2点だけ(顔写真付き1点を含む、運転免許+保険証など) 会場に持ち込み可能なのは、顔写真付き身分証明書1枚と渡されたホワイトボード・マーカーのみです。 選挙カーの音で気が散ったので、席備え付けのイヤーマフ?ヘッドホン?してました。 頭が大きいので具合悪くなりました。使い捨て耳栓も配ってたので貰っておけばよかった。 130分で65問なので、1問2分ほど使えますが半分くらい時間が余りました。 予め見直ししたいところはチェックをつけられるので、ゆっくり見直し。 わからない問題は消去法です。 終盤になると謎の自信が湧いてきますが、常に自分を疑うように心がけました。 結果 14時ごろ試験終了で、当日の18時ごろに合否のメール(というかcredlyのデジタルバッチ付与)がきました。 さすがにこのタイトルでメールが来て不合格だったら落ち込みますね。 ※この時点では来ていませんでしたが、2日後に正式な合格通知メールが届きました。 スコアはAWS認定のマイページから確認しました。 …ギリギリですね。 高校・大学受験と違って、最初から720点とれば合格って決まってるんで合格は合格です。 受験終了後、マイナビの資格取得支援制度を使って受験料補助の申請を行いました。16500円(税込)が戻ってきます。(ありがたや) (でも課税処理はしっかりされるので、100%戻ってくるわけではなさそう) 不合格でも申請できますが、1つの資格につき申請は1回のみ可能です。 所感 ・ネットワーク系やサーバ構成、複数のサービスを組み合わせる問題は、とりあえず適当に回答し後でホワイトボードで図を書いて考えました。「インバウンドが~でアウトバウンドが~で…」と文章になっていると混乱するので。。 ・②③の教材は頻出のサービス組み合わせについてはしっかりカバーしてくれているので、セットで覚えておいてよかったと思いました。 ・思い切りよく進めてくのが大事だと思います。模試をやってこなかったので時間配分にビビッて序盤ブーストかけましたが、結果的に時間が余ったので心にゆとりができました。 ・受験後2週間は同一試験の受験をできませんが、自分のタイミングで受けられ、かつ再受験無料だったので何も気負うことなく受けられました。 反省点 学習計画がゆるふわすぎた 私は電車通勤のような決まったスキマ時間があまりないので、 意識して取り組まないと時間だけが過ぎていってしまいます。 Udemyは学習計画の機能があるので、活用すればよかったなと思います。 なるべく自分で手を動かすことが重要 ②はハンズオン動画を含んでいますが、自分で手を動かした方が確実に身につくし 細かい設定も確認出来るので可能であれば一つ一つ触りたかったです 全てを無料枠で収めることはできませんが、 AWSはウェビナーの視聴等でクレジットもらえる時があるので、活用できるといいと思います。 (私はまだEC2、S3、VPCくらいしか触れてません) 前日はちゃんと寝る 言うまでもないです。 洋裁にハマった→試験2週間前に新しいミシンを買った ここ最近、退勤後は毎日縫ってました。 試験終了後も(これでまた縫える…)と思ってました。 こういう新しいことをするのは合格後にしましょう。 試験2日前に好きな映画が公開された→公開当日にしっかり観た まとめ Udemy見放題と受験料補助のおかげで、AWS SAAを取得できました。 会社の制度には感謝しかないですね・・・! かなり効率的に学べる教材ですし、出先やお風呂の中、オフラインで保存をしていれば飛行機の中など場所を選ばず視聴できるのがアドバンテージでした。 いつでも受けられる分、なかなか踏ん切りがつかないので、とりあえずお金だけ払っちゃうのもアリだなと感じました。Swing the batですね。 高得点で合格しているわけではないですし勉強不足なので復習が最優先課題ですが、次はSysOps Administrator - Associateの取得を目指したいです。
アバター
はじめに 情報系の学部出身ではないですが、二ヶ月で基本情報処理技術者試験を合格できました!今回は合格までの道のりを記録としてまとめさせていただきます。 これから基本情報処理技術者試験にチャレンジするぞ!という方の参考になればと思います。 プロフィール 新社会人(2023年4月入社) デザイン系の学部の為ITは未学習 インターンなどでプログラミングをしていたのでコードは多少書けるレベル 受験のきっかけ 正直なところプログラミング経験には多少自信があったのですが…入社してすぐ、ITの基礎研修にて事件が起こりました… “ IT用語が全く分からないんです…! (プロトコル? ファイアウォール? 何の話…?)“ さすがにまずいと思い、研修期間中に受けると受けると決めていた 基本情報技術者試験 で最低限のITスキルを付けようと考え、本格的に勉強を始めました。 試験概要 基本情報処理技術者試験とは 情報処理技術者試験は、「情報処理の促進に関する法律」に基づき経済産業省が、情報処理技術者としての「知識・技能」が一定以上の水準であることを認定している国家試験です。 ( https://cbt-s.com/examinee/examination/fe より) エンジニアとして基礎的な知識を問う試験になります。 試験概要 A問題・B問題ともに パソコンを用いたマークシート方式(CBT方式)です。 科目A 試験時間: 90分 内容: テクノロジ系・マネジメント系・ストラテジ系の3分野から四択でそれぞれ出題されます。 問題数: 60問 (テクノロジ系: 41問、マネジメント系: 7問、ストラテジ系: 12問) 科目B 試験時間: 100分 内容: アルゴリズム・プログラミングとセキュリティーの2分野から問題が出題されます。アルゴリズム・プログラミング分野は、疑似言語を用いた出題になります。 問題数: 20問 (アルゴリズム・プログラミング分野: 16問、セキュリティー: 4問) 難易度 合格要件として、A問題 B問題ともに600/1000点を超える必要があります。 受験者数 合格者数 合格率 R2秋季 52993人 25499人 48.1% R3春季 32238人 13522人 41.9% R3秋季 52831人 21167人 40.1% 新制度移行前は、23~25%程度でしたが、新制度移行後に合格率が上がりました!合格率は40%台に上昇したので少し易化しているのかもしれません! 勉強をした感じ、指定の範囲を繰り返し学習すれば短期間での合格が可能だと思います! 情報学部の方は、A問題も少し学習すれば合格点に達すると思います! プログラミング経験者の方は、B問題も問題の解き方や流れも十分に練習すれば合格点に達すると思います! ※あくまで体感です 勉強方法 全体スケジュール 試験の2か月前から、本格的に勉強を開始しました。 最初の二週間は、IT初学者向けの動画を視聴して、ITの基礎を学習しました。 デジ戦ではUdemyのアカウントを1人1つ付与しているためUdemyの動画での学習です。 そのあとに、基本情報処理技術者試験対策の動画と過去問道場を並行し、午前対策を行いました。 試験から3週間ほど前から午後問題対策の動画を視聴し、問題演習を行いました! 結果 結果としては、 午前問題: 805/1000 午後問題: 840/1000 と元々、ITの基礎知識はありませんでしたが合格することができました! 次に対策方法を見ていきます! 基本情報処理技術者試験 A問題(午前問題)対策 Udemy動画教材① ~始めから効率よく学ぶ~ 基本情報技術者試験 最速 合格講座 ITの基礎知識を学習すべく、最初に学んだ講座です! 基礎理論〜セキュリティーなどのテクノロジー分野全般 + B問題を学習することができます! IT全般のイメージを持つのにとても役立つのでおすすめです!僕は、テクノロジー系の動画を受講しました。動画も一分野1時間ほどで見れます! ですが、午前問題で更に高得点を取るためにもう1講座受講しました。 https://www.udemy.com/course/lerning-fe Udemy動画教材② 現役講師が教える【基本情報技術者試験 科目A】講座 Udemy動画教材①よりもより実践的な内容を学べるのが、「現役講師が教える【基本情報技術者試験 科目A】講座」です。 動画の中で理論の解説・実際の過去問の演習を行うような形になります。 動画の中で実際の問題のイメージをつけることができるのでこの講座を学習すれば、もう過去問に入っても大丈夫だと思います! https://www.udemy.com/course/kihon_joho 基本情報技術者過去問道場 実際に動画教材や本で学んだら次は実践です。動画で学んだ範囲の過去問を「基本情報技術者過去問道場」で学習します。 自分は全範囲全問題を演習したのですが、演習してみて75%ほど正答できていれば、その範囲に関しては追加で過去数年分の問題を演習すれば十分だと思います。 https://www.fe-siken.com/fekakomon.php IPA公式 サンプル問題 IPA公式からも2023年改定後のサンプル問題が出題されています。問題自体の基本的な変更はありませんが、問題の難易度をつかんでおくにはとても有用な問題だと思います。 https://www.ipa.go.jp/shiken/syllabus/henkou/2022/20221226.html 基本情報処理技術者試験 B問題(午後問題)対策 Udemy動画教材③ 現役講師が教える【基本情報技術者試験 科目B】科目B対策専門コース Udemy動画教材②の講師の方が解説されている午後問題対策講座、「現役講師が教える【基本情報技術者試験 科目B】Javaプログラミング言語を使った、科目B対策専門コース」です。 こちらの問題は午後問題のために必要な考え方や例題演習と解説を行ってくれるような教材です。 新方式に移行して問題がだいぶ変更になっていますが、まだ過去問や対策問題が少ないためこの教材の中に含まれている類題はとても勉強になりました。おすすめです。 https://www.udemy.com/course/kihon_joho_b IPA公式 サンプル問題 B問題に関しても、IPA公式から2023年改定後のサンプル問題が出題されています。一回分(20問) と 6問がサンプル問題として、公開されているので必須で解きたい内容になります! https://www.ipa.go.jp/shiken/syllabus/henkou/2022/20221226.html まとめ 基本情報を勉強して良かったこと 基本情報を勉強してみて、幅広いITに触れることができました。当初、「IT用語が全く分からない」という不安が解消されて、研修・業務中に出てくる単語も基本情報処理技術者で勉強したから理解が出来る!ということが増えたので間違いなく資格を取得して良かったです。   おわりに 以上が、自分の基本情報処理技術者の合格体験記になります! まだまだ未熟ですが、取得した基本情報を活かして今後の業務に取り組んで行きます! ITの基礎的な知識を習得されたい方はぜひ挑戦してみてください! 最後までご覧いただきありがとうございました!
アバター
はじめに はじめまして!2023年度新入社員K.NとM.Mです。 今回のブログでは、2023年度新入社員研修の中で行った「研修運営」について紹介したいと思います。 研修運営って何?なんでやるの?という説明から、実際に経験した新入社員との座談会の様子をまとめていきます! ▼研修カリキュラムの詳細については別記事にまとめていますので、ぜひこちらもご覧ください! ###card_post_id=1471### 本記事の編集者 アザラシさん 座談会のファシリテーター兼編集者 文系学部出身 研修で初めてプログラミングを学びました。 白米が好きです。 コアラさん 本記事の共同編集者 情報系学部出身 プログラミング経験が浅く、研修中は無駄に長いコードを書いていました。 スマートなコードをかけるように日々訓練中です。 研修運営について 研修運営って? 研修運営とは、研修を進める上で必要な物品の準備や進行を、教育担当の上司に任せるのではなく、すべて新卒の自分たちで行うものです。 具体的には、 朝会/夕会の進行 講師の方との連絡やアテンド 研修会場やZoom環境の準備 研修のグループ分け 持ち物や連絡事項のリマインド  etc… 円滑な研修運営に必要だと思うことを自分たちで考え実行します。 研修運営は、約2か月の研修期間を4つのタームに分けて、12~13人/グループで担当しました。また、各タームの最後には成果報告会を行い、同期や上司、研修の講師の方に運営での取り組みや振り返りを共有しました。 なぜ研修運営を行うの? マイナビは自らビジネスを生み出す事業会社です。そのため、ただ依頼をこなすだけではなく、自ら課題を見つけて解決を目指す姿勢が求められます。それは営業職だけでなく、マイナビで働くすべての社員、私たちシステム職にとっても同じことです。 その一歩目として、主体性をみにつけるためにも新卒研修の研修運営を自分たちで行っています! 研修運営についてはご理解いただけたでしょうか? 続いて各運営班のリーダーとの座談会の様子をご覧ください! 運営班リーダー座談会 座談会に参加する新入社員 うしくん:運営1班代表 運営1班のリーダー。 情報系の学部を卒業しました! 最近、サウナに行くことが増えて、よく”伊良コーラ”を飲んでいます。 デトックス効果があるので、リラックスしたい時に是非!   うまくん:運営2班代表 運営2班のリーダー。 文系の学部を卒業しました。 最近はものすごく腰が痛くて、長時間座っているのがつらいです。 姿勢が悪いらしいので社会人っぽく背筋を伸ばしていこうと思っています。 しろくまくん:運営3班代表 運営3班のリーダー。 情報系の学部を卒業しました。 最近引っ越しをしたので新しいお店を開拓しています。 お金だけ心配です。 ひつじさん:運営4班代表 運営4班のリーダー。 情報系の学部を卒業しました。 つい最近旅行に行った後、体調崩して寝込んでいました。 体力が落ちているから運動しなきゃなと思って、1カ月が経ちました…。 座談会 研修運営を振り返って 早速ですが、研修運営について振り返ってみていかがですか? 自分たちは、一番初めの研修運営班で、やることが何も見えていない状態だったため、前途多難でしたね。 その分、学びは多かったですが・・・ただ運営を担当していた期間の研修の記憶はあまりないです・・・。それだけ精一杯頑張りました。 初めの班は本当に大変そうでしたよね。ざっくりと研修運営については説明があったものの、研修を受けながら自分たちで運営していくというのは簡単ではないですよね。 2班はいかがですか? 研修も同じだけど、運営はグループ活動だったから、同じチームになれた人とは仲良くなれたと思います。運営については、基本的には1班がつくってくれた基礎を引き継ぎ、改善できるところは工夫をしていきました。 2班はつつがなく終わっていたイメージがありますね。 一人ひとりが役割を全うしてくれていたから、そう見えていたのかもしれないです。 自分たちのグループも1班と2班がやってくれたことを引き継いだので、そんなに大変ではなかったですね。非常に協力的なチームだったので、成果報告会以外は大きな問題なく終わったと思っています。 成果報告会は急遽オンラインでの開催になったんでしたね。 報告会の形式を事前に確認していなかったから、段取りが悪くなってしまったんですよね。事前確認・調整の大切さを学びました。ただ、1班と4班に比べたら、全然大変ではなかったですよ。 私は1班同様、運営班を担当していた期間の記憶がないですね。(笑)  1班が運営の0から1を作って、2班3班がよりよく変化させていたから、4班は最後どうするかハードルが上がっている状態でした。研修自体も大詰めでしたし、その焦りもある中での運営だったので、本当に大変でした。 各班の取り組み 各チームいろいろ工夫しながら運営を行っていたようですが、各班ならではの取り組みなどはありましたか? 自分の班は主軸となって動く人を3人ほど決めました。その人たちで仕事の洗い出しをした後に、メンバーに割り振っていくという仕組みでやっていました。ですが、仕事量の差が出てしまったので結局全員で仕事を割り振るように分担を変えたりしていましたね。 途中で仕組みを変えたんですね。 そうですね。初日と最終日では変わったことが多かったですね。 やってみないと分からないことが多かったのでまずはやってみて、こっちの方が効率的なのではないか等意見をもらいながら試していきました。 試行錯誤しながらの運営だったんですね。 2班ではどんな取り組みがありましたか? 2班の目標は、「何事も起こらないように終えること」だったので、新たな何かをやるというよりも1班がやっていたことを工夫できたらいいなというマインドでしたね。 メンバーがやった方がいいことを提案してくれて、それを1つずつ実践していきました。 2班から研修のチーム分けが自動になりませんでしたか? メンバーがチーム分けのアルゴリズムを作ってくれたので、新しいチームを作るときにはそれを動かしていました。あと、在宅の日の出席確認をPower Automateを使って自動化しました。各役割を固定化していたので、やることが明確になって、みんなが自主的に自分の仕事をこなしてくれました。 チーム分けの自動化はとても画期的でしたよね。3班も自動で行っていましたが、2班のものを使ったんですか? 3班は2班のものを改良して使用しました。2班のアルゴリズムの問題点として、1度同じチームになった人と何度も一緒になってしまうことがあったので、そこを改善できるようにしました。 2班のやっていたことを引き継いでさらに良くしていったのですね。新しく始めたことはありますか? リモートワークでの自習日(※研修がなく、自分でスケジュールを立てて良い日。研修の振り返りをしたり、勉強会を開いたり…)があったので、ブレイクアウトルームの使い方を決めました。あとは、先輩への欠席連絡を始めましたね。細々したことをやっていました。 3班は仕組みづくりがしっかりされていた印象があります。細々と仰っていますがそういう小さなことが先輩社員の皆さんは非常にありがたいと好評だったそうですよ。 4班はいかがですか? 4班は役割をローテーションさせていました。3班の成果報告会で司会が固定だったことが指摘されていました。 全ての役割に今の我々がやる意味があると思うので、全員が司会を経験できるようにしました。 たしかに、司会が毎日変わっていたのが印象的でした。 研修の目的として、失敗を恐れずにとにかく経験してみようというのがあったので、それに則してやってみました. 4班ならではの取り組みだと、意見箱の設置ですかね。フォームを作成して、新卒から随時意見をもらい、運営に反映できるようにしました。手探り状態で始めたので、教育担当の方と相談しながら試行錯誤しました。 今までやっていない施策に挑戦するということはうまくいかない可能性もある中で、うまく工夫して周りを巻き込みながら改善をしていたイメージがあります。 そうですね。4班のみんながいろいろ考えて動いてくれた結果、何とかうまくいったような気がしているので、班のみんなに感謝です。 研修後に活きていること では、最後に研修運営後に活きていることがあれば教えてください。 今まで、自分が正しいという考えが結構強くて、チームを引っ張っていかないといけないという気持ちがありました。自分に自信もありましたし・・・でも実際は全然そんなことはなくて、研修運営を通して周りにたくさん助けられているということに気づけました。 あとは、タスクを割り振ったり、細分化したりする能力が身につきましたね。 自分はメンバーを信頼することの大事さを学んだと思っています。今までメンバーを信頼していなかったというわけではないけれど、研修運営を通して、一緒に仕事をやる人たちを信頼してみんなでやろうという気持ちの持ち方がとても大事というのを感じました。 チームで何かをやる経験が今までなかったから、チームワークの大切さを学びました。研修最後のチームで行う開発演習で活きた感じがします。 開発演習で、僕のグループは、班員が1人体調不良で欠席というハプニングが起きたのですが、最後まで連携をとってやりきることができました。 誰かと協力しながら成し遂げようとする経験をできたのが良かったです。活かされていることとしては、運営をしているときに報連相の重要さを感じていたので、それを意識しています。 ただ自分の考えを伝えるのではなく、相手の立場に立って、どういう内容が欲しいのかを考えて発言するように心がけるようになりました。 あとがき いかがでしたでしょうか? 研修運営の内容や、新入社員ならではのリアルな感想がお伝えできていれば幸いです。 研修運営を通して、社会人として必要なスキルである、「何事にもひとりひとりが主体性をもって取り組む姿勢」を身につけることができました。 コアラさん エンジニアは1つのチームで業務を行うことが多いので、協調性やコミュニケーション力は欠かせません。研修期間にチームで1つのことを成し遂げる経験ができたことは、今後の業務にも活きてくると思います。 研修期間に培った力を活かせるように今後も積極的に何事にも取り組んでいきたいです。 今回の記事は以上になります。最後まで読んでいただきありがとうございました!
アバター
はじめに こんにちは!23卒の開発エンジニアのT.NとN.Yです。 この記事では、今年度行われた、マイナビのシステム職向けの新卒研修について、具体的にどんなことを学んだのか紹介していきます。 主にマイナビのシステム職に興味のある学生の皆さんを対象として、イメージをつかめるような記事を作りたいと思いますので、ぜひ参考にしてみてください。 全体スケジュールと前提 前提条件 今年度システム職として採用された新入社員は、システムエンジニア、開発エンジニア、データサイエンティスト、デザイナー、マーケター、企画職など、配属職種は様々です。 しかし、新人研修では職種関係なく全員が3ヶ月間同じ研修を受けました。 これは、専門に関係なく基礎的なITスキルを身に着けることで、将来的に「複数職種を跨いで活躍する人材になる」ことを目的としているからです。 スケジュール 最初に、研修期間のスケジュールをまとめました。 システム職の新人研修は、3か月間にわたって実施されます。ビジネス基礎などの社会人として必要なことから、WEBアプリの開発演習まで多岐に渡って内容を網羅していきます。 いかがでしょうか? マイナビについて知る研修から、ITの基本的な知識やアプリ開発の流れまで、3か月間盛りだくさんな内容であることが分かるかと思います! 研修期間中は毎日の日報記入があり、長期間にわたるアウトプットを通じて、研修が始まる前と終わった後で自分自身がどのように成長し、変化があったのかを感じることができました。 また、1人三分で自分の好きな事などを発表する「三分間プレゼン」を実施し、スライド作成や短時間で伝える力、大勢の前での発表など、配属されてからも必要となるスキルを養うことができました。配属先の異なる同期の発表を聞くことができたのも研修ならではだったと感じています。 さらには、研修を受講するだけでなく、研修を自分たちで運営することもありました。 会場の用意や講師の方のアテンド、連絡事項などを新入社員自身で行いました。 ▼こちらに関しては、別の記事で詳しくまとめているので、併せて読んでみてください! 2023年システム職新人研修・振り返り~研修運営編~ ただ技術を教わる以上に、社会人として、マイナビ社員として、必要な要素を身に着けられる研修だったのかなと思います。 ここからは、それぞれの研修について、一つずつ説明していきます。 ビジネス研修、事業部研修など 私たち新入社員が研修で学ぶものは、テクノロジーに関することだけではありません。 まずは、デジタルテクノロジー戦略本部の各部門の役割について、それぞれ説明を受けました。 他にも下記のように、様々な研修を通じて新社会人としての準備をしていきました。 オンボーディング研修 オンボーディング研修では、まずはテクノロジー分野の発展についてを学び、そこから自社事業についてを考えました。また、実践的に学びを深めるために、サービスについて分析するワークを行いました。 ペルソナ設定や3C分析といった、沢山のワークを通じて、マイナビの一員としてのマインドセットを養うことが出来たのではないかと思います。 事業部研修 マイナビには、就職事業本部(代表サービス:マイナビ20XX)、転職事業本部(代表サービス:マイナビ転職)、アルバイト事業本部(代表サービス:マイナビバイト)など、多くの事業部があります。 総合職の各事業部配属の新卒を対象とした本研修は、各事業部ごとに実施されます。サービスやビジネスモデルの理解から営業フローの学習まで、様々なカリキュラムが用意されていました。 私たちも、営業を始めとした他職種と共に研修に参加し、カスタマーへの提案やテレアポの練習に参加しました。「システム職なのに営業の練習?」と思う方がいるかもしれません。ですが、自分たちが携わる市場やサービスについて知ることは、今後仕事をしていく上でとても重要なことです。この研修を通じ、会社全体において課題を解決するためにシステム職が担う役割を学ぶことができました。 他にも、マーケティングの基礎や、ロジカルシンキングを学ぶ機会がありました。 どんな業務に携わるにせよ、問題解決能力やコミュニケーション能力は欠かすことができません。これらの研修は、今後ずっと使える力を養うキッカケになりました。 Python、フロントエンド、インフラなど IT研修では、web開発に関連する以下のような技術を学びます。 アルゴリズム Linux / AWS HTML / CSS データベース Python / Flask 短い期間で上記の範囲をカバーするカリキュラムですので、技術に関しての知識を深めるためだけのものではありません。 「自分で考えて、自分で行動していく力を身に着ける」力を養うことが、ゴールとして掲げられていました。 もちろん、技術に慣れている人もいれば、初めてエディタを開く人もいます。習熟度や得意なことはバラバラですので、研修中のワークでは、互いに協力しながら取り組むことが多くありました。教える側も教わる側も、どうすれば自分の考えが上手く伝わるか、工夫を重ねて上達したように感じます。 同期たちと共に頑張ることで、技術面の成長だけでなく、今後も役立つ自走力を身に着けることができました。 また、私たちは、自習日や空き時間を活用して、それぞれ基本情報やITパスポートなど資格試験の受験を行いました。 これからIT職として働く基盤を固めるための、有意義な時間を過ごせたと思います。 チーム開発 技術研修の締めくくりとして、チーム開発を実施しました。 6〜7人の班に分かれて、要件定義から設計、実装、テストまでを2週間で行いました。 PythonのFlaskというフレームワークを利用して、チケット予約サイトを作成することが、今回与えられた課題です。 この課題には、「全員1人1機能は実装する」という条件がありました。 ですので、得意不得意に関わらず、全員がIT研修で学んだことを活かして開発に取り組む必要がありました。 一方で、開発を行うためのヒアリングや設計書を作ることも必須です。採用職種とは関係なく、上流から下流までをひと通り経験することとなりました。 下の画像は、とある班の作成した成果物です。 この演習では、それぞれの班は開発請負側であると同時に、ユーザーの立場も兼ねています。 例えば、A班はB班に対して「こんな機能があるサイトを作ってほしい」と依頼します。反対に、B班もA班に対して要望を依頼する、といった感じです。 二つの立場が並行するため、慌ただしくはありましたが、両方の立場を経験するからこそ、ユーザー側と開発側との合意を探る難しさを知ることができました。 個人的には、ヒアリングが難しかったです。班員のキャパシティやリリースまでの期間を踏まえて妥協を探ることが、特に大変でした。 また、チームでの開発ですので、個人が黙々と取り組んでいるだけでは成り立ちません。スムーズな協力と連携のためにも、メンバー間で役割分担やタスクを共有することは、必須の課題でした。 演習開始のころは、情報共有や連携が上手くいかず、手戻りの発生する場面が散見されました。中には、グループ内でgithubの運用が整備されておらず、コードが消え飛んでしまうアクシデントが起こることもあったそうです。 様々なトラブルが発生していましたが、運用マニュアルの作成や共有ツールの導入など、問題解決力を活かすことで、一つずつ解決できました。 成果報告会 3か月の研修の最後、チーム開発の集大成として、成果発表会を行いました。 私たちは、実装したサイト紹介と開発演習から得た学び、また、研修を通じた成長の三項目について発表を行いました。 劇形式で発表してみたり、キャッチーなスライド構成にしてみたり、伝え方に関して個性が光る発表会となりました。 最後の締めくくりとして相応しく、3か月かけて学んだことを総動員することができたのではないかと思います。 成果報告後には、三部門での賞が用意されていました。参加してくださった先輩社員たちの投票によって最優秀賞と発表賞の班が、講師の方の評価からは技術賞の班が、ひとつずつ選ばれました。 賞を頂けることはもちろん嬉しいですが、何よりも、自分一人ではできなかった挑戦があったことが、この研修を通じた一番の収穫だったと思います。 研修で得たすべてを、これからの糧として活かせるように、今後も精進していきます。 さいごに 以上が、23卒システム職の研修カリキュラム振り返りになります。 もっと詳しく聞きたい方は、マイナビのインターンや説明会に参加するといいかもしれません。 ぜひ、いろんなイベントに参加してみてくださいね!
アバター
はじめに 始めまして、23年新卒入社のG・Sです。 マイナビ2023年新卒入社で参加者を募って、6/3(土)4(日)開催のSECCON Beginners CTF 2023に参加してきました。 本記事は、我々新卒チームが解いた問題のwritupになっています。 今回参加したCTFについて SECCON Beginners CTF 2023 日本のCTF初心者〜中級者を対象としたCTFのコンテストで毎年6月の上旬に開催されています。今回は2018年の初開催から数えて6回目の開催となります。 出題範囲は、crypto、pwnable、misc、web、reversingでした。 Writeup 我々のチームはBeginnerを全て解くことができました!!! ひとつずつ解説していこうと思います。 CoughingFox2(crypto) CougningFox2.tar.gzを展開するとcipher.txtとmain.pyが入っていました。 cipher.txtとmain.pyの内容はそれぞれ以下の通りです。 cipher = [4396, 22819, 47998, 47995, 40007, 9235, 21625, 25006, 4397, 51534, 46680, 44129, 38055, 18513, 24368, 38451, 46240, 20758, 37257, 40830, 25293, 38845, 22503, 44535, 22210, 39632, 38046, 43687, 48413, 47525, 23718, 51567, 23115, 42461, 26272, 28933, 23726, 48845, 21924, 46225, 20488, 27579, 21636] # coding: utf-8 import random import os flag = b"ctf4b{xxx___censored___xxx}" # Please remove here if you wanna test this code in your environment :) flag = os.getenv("FLAG").encode() cipher = [] for i in range(len(flag)-1): c = ((flag[i] + flag[i+1]) ** 2 + i) cipher.append(c) random.shuffle(cipher) print(f"cipher = {cipher}") プログラムを読むと暗号化を行い最終的に cipher というリストを出力していることが分かります。このことから cipher.txt に書かれていたものは暗号化がおこなわれた後のものでと考えられます。また暗号化の部分はi文字目とi+1文字目を足して2乗し、iを足したものであることから、一つの文字が分かれば次の文字を総当たりで探し (flag[i] + flag[i+1]) ** 2 + i を計算しcipher.txt内の配列に存在するか確認すれば芋づる式に解きFlagを得ました。 Flag : ctf4b{hi_b3g1nner!g00d_1uck_4nd_h4ve_fun!!!} 学び 暗号は一見難しそうなものでもプログラムを書いたりすることで容易に解けてしまうものも多く存在しています。 よって、暗号の選定をする際にはきちんと脆弱性がないものを選ぶことが重要であると感じました。 poem(pwnable) poem.tar.gzを展開するとpoemとsrc.cが入っていました。 poemは実行ファイルであり、src.cの内容は以下の通りです。 #include <stdio.h> #include <unistd.h> char *flag = "ctf4b{***CENSORED***}"; char *poem[] = { "In the depths of silence, the universe speaks.", "Raindrops dance on windows, nature's lullaby.", "Time weaves stories with the threads of existence.", "Hearts entwined, two souls become one symphony.", "A single candle's glow can conquer the darkest room.", }; int main() { int n; printf("Number[0-4]: "); scanf("%d", &n); if (n < 5) { printf("%s\n", poem[n]); } return 0; } __attribute__((constructor)) void init() { setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); alarm(60); } このプログラムを読むと数値nを読み取り、配列に格納されているn番目のポエムを出力するプログラムであることが分かります。読み込んだnが5より大きいときはポエムを出力しないようにしてありますが、0より小さい場合はそのまま配列にアクセスすることになっています。 よってnにマイナスの値を入力することでほかの領域のアドレスにアクセスすることがで、-4を入力することでFlagを得ました。 Flag : ctf4b{y0u_sh0uld_v3rify_the_int3g3r_v4lu3} 学び Pythonなどでは、リストなどの範囲外のindexを指定した場合IndexErrorが出ますが、C言語ではエラーが出ずに別メモリ領域にアクセス可能になります。 これを防ぐためには、境界値を正しく設定し条件分岐することが大事たと感じました。 YARO(misc) YARO.tar.gzを展開するとrule_example.yarとserver.pyが入っていました。 それぞれ内容は以下の通りです。 rule shebang { strings: $shebang = /^#!(\/[^\/ ]*)+\/?/ condition: $shebang } rule maybe_python_executable { strings: $ident = /python(2|3)\r*\n/ condition: shebang and $ident } #!/usr/bin/env python3 import yara import os import timeout_decorator @timeout_decorator.timeout(20) def main(): rule = [] print('rule:') while True: l = input() if len(l) == 0: break rule.append(l) rule = '\n'.join(rule) try: print(f'OK. Now I find the malware from this rule:\n{rule}') compiled = yara.compile(source=rule) for root, d, f in os.walk('.'): for p in f: file = os.path.join(root, p) matches = compiled.match(file, timeout=60) if matches: print(f'Found: {file}, matched: {matches}') else: print(f'Not found: {file}') except: print('Something wrong') if __name__ == '__main__': try: main() except timeout_decorator.timeout_decorator.TimeoutError: print("Timeout") コードを見るとruleを入力させ、yaraというマルウェア解析・検知ツールを用いて検索を行っています。 下記のようなruleを書くことでflagの一文字目がAかどうか確認できます。 rule flag { strings: $shebang = /ctf4b{A.*}/ condition: $shebang } これを繰り返して探索していくことでFlagを得ました。 Flag : ctf4b{Y3t_An0th3r_R34d_Opp0rtun1ty} 学び ユーザーに任意の正規表現を書かせるようなプログラムを書くと秘匿情報を探索される可能性があるため注意が必要だと学びました。 polyglot4b(misc) polyglot4b.tar.gzを展開すると画像ファイルsample/sushi.jpgとpolyglot4b.pyが入っていました。 import os import sys import uuid import shutil import subprocess print( f"""\033[36m\ ____ _ _ _ _____ _ _ _ | _ \ ___ | |_ _ __ _| | ___ | |_ | ____|__| (_) |_ ___ _ __ | |_) / _ \| | | | |/ _` | |/ _ \| __| | _| / _` | | __/ _ \| '__| | __/ (_) | | |_| | (_| | | (_) | |_ | |__| (_| | | || (_) | | |_| \___/|_|\__, |\__, |_|\___/ \__| |_____\__,_|_|\__\___/|_| |___/ |___/ {"-" * 68} >> """, end="", ) file = b"" for _ in range(10): text = sys.stdin.buffer.readline() if b"QUIT" in text: break file += text print(f"{'-' * 68}\033[0m") if len(file) >= 50000: print("ERROR: File size too large. (len < 50000)") sys.exit(0) f_id = uuid.uuid4() os.makedirs(f"tmp/{f_id}", exist_ok=True) with open(f"tmp/{f_id}/{f_id}", mode="wb") as f: f.write(file) try: f_type = subprocess.run( ["file", "-bkr", f"tmp/{f_id}/{f_id}"], capture_output=True ).stdout.decode() except: print("ERROR: Failed to execute command.") finally: shutil.rmtree(f"tmp/{f_id}") types = {"JPG": False, "PNG": False, "GIF": False, "TXT": False} if "JPEG" in f_type: types["JPG"] = True if "PNG" in f_type: types["PNG"] = True if "GIF" in f_type: types["GIF"] = True if "ASCII" in f_type: types["TXT"] = True for k, v in types.items(): v = "🟩" if v else "🟥" print(f"| {k}: {v} ", end="") print("|") if all(types.values()): print("FLAG: ctf4b{****REDACTED****}") else: print("FLAG: No! File mashimashi!!") コードを読むと10回入力を受け取り入力を結合して file コマンドを実行しその出力にPNG、JPEG、GIF、ASCIIの文字列があるかを確認して全てあればフラグを出力しています。 まずsample/sushi.jpgを file -bkr sample/sushi.jpg を行うとDescriptionの欄にCTF4Bという文字を見つけられます。このことからDescription欄には、任意の文字を入れることができると考えられます。よってCTF4Bの後ろにPNGJPEGGIFASCIIを追加して、 nc polyglot4b.beginners.seccon.games 31416 < sushi.jpg とやることで、Flagを得ました。 Flag : ctf4b{y0u_h4v3_fully_und3r5700d_7h15_p0ly6l07} 学び fileコマンドを使ってファイルを識別する際に正しく処理を書かなければ、ユーザーの悪意によっていくらでも偽装できることが可能であるとわかりました。今回の問題のミスをなくすためには、fileコマンドの解析をファイルタイプを示している部分だけにするなどの工夫が必要であると感じました。 Forbidden(web) Forbidden.tar.gzを展開するとnginxで作られたWebアプリケーションが入っていました。 app/index.jsの内容は以下の通りです。 var express = require("express"); var app = express(); const HOST = process.env.CTF4B_HOST; const PORT = process.env.CTF4B_PORT; const FLAG = process.env.CTF4B_FLAG; app.get("/", (req, res, next) => { return res.send('FLAG はこちら: <a href="/flag">/flag</a>'); }); const block = (req, res, next) => { if (req.path.includes('/flag')) { return res.send(403, 'Forbidden :('); } next(); } app.get("/flag", block, (req, res, next) => { return res.send(FLAG); }) var server = app.listen(PORT, HOST, () => { console.log("Listening:" + server.address().port); }); コードを読むと block で/flagに遷移したとき403を返していることが分かります。 nginxは、URLの大文字小文字の区別がない。すなわち"/flag"と"/Flag"は、同じページであると判断されます。 しかし、JavaScriptでは、 if (req.path.includes('/flag')) で分岐を行いブロック処理を記述しているため、 https://forbidden.beginners.seccon.games/flag は403が帰ってくるが https://forbidden.beginners.seccon.games/Flag とすることでフラグを得ることができます。 Flag : ctf4b{403_forbidden_403_forbidden_403} 学び フレームワークの仕様をしっかり理解していることが大切であると感じました。 今回の例では、nginxとJSで文字列の大小の扱いが違っていてその違いを理解していないことで意図するように動いていないので、仕様理解をおろそかにしてはいけないと学びました。 aiwaf(web) aiwaf.tar.gzを展開するとnginxで作られたWebアプリケーションが入っていました。 app/app.pyの内容は以下の通りです。 import uuid import openai import urllib.parse from flask import Flask, request, abort # from flask_limiter import Limiter # from flask_limiter.util import get_remote_address ################################################## # OpenAI API key KEY = "****REDACTED****" ################################################## app = Flask(__name__) app.config["RATELIMIT_HEADERS_ENABLED"] = True # limiter = Limiter(get_remote_address, app=app, default_limits=["3 per minute"]) openai.api_key = KEY top_page = """ <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8" /> <title>亞空文庫</title> </head> <body> <h1>亞空文庫</h1> AIにセキュリティの物語を書いてもらいました。<br> 内容は正しいかどうかわかりません。<br> <ul> <li><a href="/?file=book0.txt">あ書</a></li> <li><a href="/?file=book1.txt">い書</a></li> <li><a href="/?file=book2.txt">う書</a></li> <!-- <li><a href="/?file=book3.txt">え書</a></li> --> </ul> ※セキュリティのためAI-WAFを導入しています。<br> © 2023 ももんがの書房 </body> </html> """ @app.route("/") def top(): file = request.args.get("file") if not file: return top_page if file in ["book0.txt", "book1.txt", "book2.txt"]: with open(f"./books/{file}", encoding="utf-8") as f: return f.read() # AI-WAF puuid = uuid.uuid4() prompt = f"""\ 以下の{puuid}に囲まれた部分のURLクエリはパストラバーサル攻撃でしょうか? そうである場合Yesを、違う場合Noを返してください。 ../やflagという文字列が含まれていた場合もYesを返してください。 {puuid} {urllib.parse.unquote(request.query_string)[:50]} {puuid} """ try: response = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[ { "role": "user", "content": prompt, }, ], ) result = response.choices[0]["message"]["content"].strip() except: return abort(500, "OpenAI APIのエラーです。\n少し時間をおいてアクセスしてください。") if "No" in result: with open(f"./books/{file}", encoding="utf-8") as f: return f.read().replace(KEY, "") return abort(403, "AI-WAFに検知されました👻") if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=31415) コードを読むと 以下の{puuid}に囲まれた部分のURLクエリはパストラバーサル攻撃でしょうか? そうである場合Yesを、違う場合Noを返してください。 ../やflagという文字列が含まれていた場合もYesを返してください。 {puuid} {urllib.parse.unquote(request.query_string)[:50]} {puuid} というプロンプトをAIに投げて帰ってきた値がYesだった場合、ブロックする仕様になっています。 プロンプト部分を見ると urllib.parse.unquote(request.query_string)[:50] となっており与えられたURLの50文字目までしかAIによる検知を行っていないことがわかります。 これにより、パラメータに適当なものを追加し file=../flag が50文字目以降となるように設定することでAIによる検知を抜けてフラグを得ることができました。 Flag : ctf4b{pr0mp7_1nj3c710n_c4n_br34k_41_w4f} 学び OpenAIは文字単位でお金がかかります。そのため、コストを下げようと途中で文字列を切ってからプロンプトを生成してしまうなどすると切り取った以降の部分に攻撃が含まれている可能性があり、攻撃が成立してしまう可能性があります。文字列を切る場合は、以降の処理も切ってから行うなどしないといけないと感じました。 Half(reversing) Half.tar.gzを展開するとhalfという実行ファイルが入っていました。 このプログラムを実行すると入力待ちになり、入力されたフラグの正誤判定をしてくれます。 この実行ファイルを strings コマンドを使って可読部分を表示して得られる結果が以下の通りです。 $ strings half /lib64/ld-linux-x86-64.so.2 libc.so.6 strncmp __isoc99_scanf puts printf strlen __cxa_finalize strcmp __libc_start_main GLIBC_2.7 GLIBC_2.2.5 _ITM_deregisterTMCloneTable __gmon_start__ _ITM_registerTMCloneTable u+UH []A\A]A^A_ Enter the FLAG: %99s%*[^ Invalid FLAG ctf4b{ge4_t0_kn0w_the _bin4ry_fi1e_with_s4ring3} Correct! :*3$" GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0 crtstuff.c deregister_tm_clones __do_global_dtors_aux completed.8061 __do_global_dtors_aux_fini_array_entry frame_dummy __frame_dummy_init_array_entry main.c __FRAME_END__ __init_array_end _DYNAMIC __init_array_start __GNU_EH_FRAME_HDR _GLOBAL_OFFSET_TABLE_ __libc_csu_fini strncmp@@GLIBC_2.2.5 _ITM_deregisterTMCloneTable puts@@GLIBC_2.2.5 _edata strlen@@GLIBC_2.2.5 printf@@GLIBC_2.2.5 __libc_start_main@@GLIBC_2.2.5 __data_start strcmp@@GLIBC_2.2.5 __gmon_start__ __dso_handle _IO_stdin_used __libc_csu_init __bss_start main __isoc99_scanf@@GLIBC_2.7 __TMC_END__ _ITM_registerTMCloneTable __cxa_finalize@@GLIBC_2.2.5 .symtab .strtab .shstrtab .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.got .plt.sec .text .fini .rodata .eh_frame_hdr .eh_frame .init_array .fini_array .dynamic .data .bss .comment この出力を見てみると20行目にFlagがあります。 Flag : ctf4b{ge4_t0_kn0w_the_bin4ry_fi1e_with_s4ring3} 学び 文字列は、実行ファイルにそのまま保存されるため、秘匿情報を文字列にしたまま実行ファイルに入れてしまうと容易に見れてしまうので、秘匿情報を載せないことを徹底しなければいけないと感じました。 終わりに 今回は、私は初参加ながら全てのbeginner問題を解くことができたので大変満足しています。 しかし、medium・herdあたりが全く解けなかったのでもう少し精進していきたいと感じました。 CTFに参加することで今まで知らなかった脆弱性などを知る機会になり、 セキュリティへの意識が高まるので是非皆さんも参加してみてください。 投稿 【CTF】SECCON Beginners CTF 2023 新卒チームWriteup は マイナビエンジニアブログ に最初に表示されました。
アバター
こんにちは。 2023年にデータサイエンティストとしてマイナビに入社をしたH・Hです。 この度、イギリスのダービー大学で開催された国際学会である自然言語処理学会に登壇をして来ました。 今回は参加の経緯と参加レポについて記載をさせていただきます。 主な流れ 時間 内容 2月上旬 国際学会提出に誘われる 3月30日 論文提出 4月25日 査読通過 5月23日~6月19日 スライド作成+発表練習 6月19日 イギリスへ! 6月21日 発表! 6月25日 日本に帰国 自分の研究について 概要 元々、Web上のデータはなかなか解析が進んでいないと思っていました。様々なデータがある中でWeb上ではオープンに学ぶことが出来ます。機械学習をさせることで精度が高い解析ができるのではないかと考えました。 自分の研究テーマは[機械学習によるTwitterユーザーの性別予測]です。 X(旧:Twitter)で投稿されたテキストや画像をもとに投稿したユーザーの性別を予測していきます。 例えばある商品について「いいね!」をしている人や自分をフォローしている人の性別を知ることで今後のマーケティング戦略につながるといった社会的目的も叶えることが出来ると思いました。 その中でも新規性として、性別をTwitterの外のサービスを用いて自動にラベル付けを行うことで、機械学習する際に人の手間を排除した方法を行い、十分な精度を出しました。 具体的には日本人では約2万人いると言われているX(旧:Twitter)のフォロワー数1万人以上の人に対してWikipedia等Web上の情報を用い、ラベル付けをすることができた6000人~7000人を学習させていきました。 大変だったこと ラベル付けについてなかなか精度を上げることが出来ず非常に苦労をしました。 画像の添付が有るときと無いときのデータに対してどのような対応をすべきか?等考えることが沢山あります。 最初に作ったモデルだと上手に行かず、いろいろなモデルを作っては試し、また作っては試し…と何度も繰り返しました。 また、データ数も非常に多く、1回の取得に2週間以上かかるものもあり回収が非常に難しかったです 参加のきっかけ 最初は卒業年である2023年の1,2月ごろ、研究室内で自分の研究内容を発表したときに助教授の方から「君の研究内容は面白い。近日、君に当てはまるテーマでの学会発表がイギリスであるから提出してみたら?」と提案を受けたのがきっかけです。 自分は英語がかなり苦手であまり積極的ではなかったのですが、サポートをしてくれるという言葉から提出に踏み切りました。助教授のアドバイスの元、卒論や、国内学会発表とは内容と差別化を図るように注目する点を少し変えて、結論をまとめていきました。 追加実験や論文をまとめ上げ3月30日に提出をしました。 査読が通った後 提出を終えたのち大学院を卒業し、はれてマイナビに入社し新入社員研修をしていた4月25日に査読が通り、掲載されることが決まりました。その時は研修と発表準備の両立への不安と、英語が本当に苦手という意識から、自分はイギリスにはいかず、発表は助教授に任せようと考えていました。ただ同期の仲間に背中を押され5月の中旬にようやく学会発表をすることを決意しました。 イギリスへ そこからはスライド、発表資料の作成を行い、複数回のミーティングと元研究室のみんなにも協力してもらいながら発表練習を複数回繰り返しました。(と言いつつもカンニングペーパーを作成しそれを間違えないように発音することで精一杯でした…) それから、初めてのヨーロッパということで移動、宿泊の準備もしていきました。 イギリスに到着してからもぎりぎりまで内容の確認を行い発表に臨みました。 学会発表 正直緊張して何も覚えていません(笑) 博士課程の方や大学教授レベルの方が非常に多く、ほぼ最年少での参加でした。 自分は、言葉を間違えないように必死で、ほとんどスライドを見ていました。 質疑応答の場面では周りの助けもありながらなんとか返答することができました。 中でも、「性の多様化が進んでいるなかで男女のみに絞ったのですか?」という質問に対しては「先行研究と比較するため男女のみに絞りました。」としか答えることができず、性別に関する認識を甘く見られていた点を突かれてしまいました。 他の人の発表を聞いて自分では考慮しきれなかった絵文字を含んだ文章解析など独自の視点による解析が多くあり視野が広がりました。 振り返り 結論として、とても楽しかったです!参加して本当に良かったと思います! 最初は英語が苦手で、発表もけして大成功とはいえない結果でしたが、文化的にも、技術的にも多くの経験をさせてもらいました。特に、多くの国籍の方が発表していたので、注目する視点や、問題の定義にも個性が出ており、多様な物事の視点を獲得できた気がしています。 また、よく見ていた論文サイトで自分の論文が見れるようになっていてとても興奮しました! もっと時間があれば性別だけでなく年齢や出身地も予測したいなと思っていました。ただ研究をしていくうちに「データ」そのものへの興味が湧いてきたのです。なので、これからマイナビでデータサイエンティストとして活躍できるよう、頑張っていきたいと思います!! 投稿 【23卒】初めての国際学会体験記【自然言語処理学会】 は マイナビエンジニアブログ に最初に表示されました。
アバター