【IT業界面接対策】面接への「心構え」と「よく聞かれる質問と回答例」

こんにちは、スタルヒンです。新卒の方の面接の準備をそろそろし始める時期ですよね。いまからIT業界へ就職や転職を考えられている方向けの面接時のアドバイスのブログとなります。ご活用いただけましたら幸いです

私はインターネットが世に普及する前からプログラミングの世界で生業を行ってきました。40年の経験があります。若い時から教わる方がいない環境でしたので、20年は入社面接官の経験があります。役員経験も長くあります。いまは58歳にしてフリーランスでいまだ現役プログラマーです。会社側の考え方もわかってますので皆さんへ有意義なアドバイスができるかと思います。

はじめての就職や転職を考えているかたは以下の不安や疑問を抱えていませんか?
エンジニア転職したいけど面接でどんな質問をされるかわからないなー
エンジニア面接でどんな回答をしたらいいんだろう?

面接内容がわからず準備が出来ないと不安になりますよね。今回は面接にのまれないためにも、相手を知り心づもりをおこなってから、面接で聞かれる質問や回答例について、私が会社役員の時の良く行った質問やそれに対する相手にとっては興味ある回答例を考えてみました。実際の例ですのでみなさんが実践できるように解説していきます。

最近の面接の傾向【IT企業側にまず立ってみよう】

大幅に質問される内容が変わったわけではありませんが、コロナの影響でリモートワークが流行りはじめたことでリモートワークに関する質問が増えています。特に社内SEはリモートワークを提供するためのシステムや仕組みを担当しますので、リモートワークをどのように受け入れて、どのような改善をしていくべきかを聞かれるケースが増えています。リモート作業でも十分コミュニケーションが取れるかどうかと、リモートワークでのセキュリティの考え方をしっかり持たれているかが、採用側では知りたいことなのです。

働き方について

面接官)
出社とリモートワークどちらの働き方を希望しますか?

リモートワークについては正解はありませんのでどちらの働き方を希望するか正直に話せば問題ありません。もしリモートワークを認めない企業であれば、そもそも入社したいかちゃんと考えたほうがいいと思います。そのような企業は考えが古く、IT技術に関してもレガシーな可能性が高いので、自身のキャリアアップに繋がらない恐れがあります。

ゼロトラストについて

https://www.nri-secure.co.jp/service/zerotrust

面接官今はVPNを使用してリモートワークしてもらっていますが、ゼロトラストを実現したいと考えています。ゼロトラストに向けての経験や実績はありますか?

回答例)
最初は出社することにより会社の方たちとのコミュニケーションを行った後にコミュニケーションが可能で仕事ができるようになった時点でリモートワークへ切り替えさせていただければと思っております。その際に経験はありませんが、ゼロトラストには注目していますので実現に必要であるSaaS統合認証基盤のOktaとAzureADについてセミナーに参加したり、書籍を読んだりしていつでも参加出来るように準備をしております

社内SEの界隈ではやはりゼロトラストがリモートワークに必須のセキュリティモデルと考えられていますので質問される可能性が高いです。何かしらの経験があれば回答できるように整理しておくとよいでしょう。もし経験が無くても上記の回答のように事前に勉強していることをアピールするのもいいですね。

コミュニケーションについて

面接官入社後はリモートワークになり、対面でメンバーと会う機会が少ないと思いますが、他のメンバーとの関係性構築に不安はありませんか?

リモートワークでの関係性構築はなかなかと大変です。自分も案件受託で新メンバーとコミュニケーションを意識して対応しております。現職や学生間でもリモートワークをしているようであればその経験を語るのがよいでしょう。もし経験が無く不安であれば、その会社ではどのような取り組みをしているかを聞いてみるのもいいかと思います。

面接官)
リーダシップを発揮した経験は?

回答例)
私が考えるリーダーシップは、各メンバーが責任を自覚できるように働きかけることです。

高校生のときにテニス部に所属していましたが、思うような結果を出せず、部員もやる気を失って練習を休みがちでした。それを見て私は、顧問の先生と部長にミーティングの場を持つよう提案しました。

やる気を出すにはどうしたらいいか、結果を出ために何をするべきか意見を求め、それぞれが責任を持つことを話し合いました。このミーティングで部員みんなが責任感が持つようになり、練習に打ち込んで大会でも上位入賞を果たすことができました。

この経験は、入社後にチームで仕事に取り組むときにも活かせると思います。

その他のよく聞かれる質問と回答例

自分は数千人も面接してきましたが基本的に聞く質問はほぼ同じです。面接官が何故この質問をするのか考えて、そこから回答を準備出来るとよいでしょう。以下に質問と回答例をまとめていますので面接前までに頭の中で整理してみてください。

自己紹介

面接官)
あなたのこれまでの経歴を教えてください

回答例)
〇〇〇と申します。宜しくお願い致します。私は大学卒業後から現在までに〇社でエンジニアを担当しました。1社目は新卒で〇〇会社に入社し、主に×××サーバーの構築や運用保守を経験しました。2社目は・・・・
現在は〇〇会社で××グループのマネージャーとして〇名のメンバーのピープルマネジメントと××、××、××などの案件のPMを担当しております。

回答例)

私は現状に満足せずに、常に現状の構成が最適なのか、部分最適になっていないか、過剰にコストがかかってないかを考え、サーバーの価格交渉から実際の運用、他システムとの連携までを想定・検討し、ゼロベースで環境を構築することを徹底してきました。御社でも積極的に新しい技術や新システムの導入にチャレンジし、社員が働きやすい環境を実現します。

学校卒業後から現在までの職務経歴をメインに紹介と同時に自身のPRポイントのアピールを盛り込むといいでしょう。あまりに長すぎると面接官が飽きてしまいますので2~3分でまとめてみてください。

面接官)
今回のポジションでどう活躍できるか、どのような強みが活かせますか?

回答例)
現職でも〇〇グループのリーダーとしてXXX、XXX、XXXの導入や運用改善に着手してきました。入社当初、〇〇の導入を検討していたが案件を先導して進めるPMがいないことにより導入が進んでいなかったのですが、私がPMとして訴求ポイントを経営陣やグループ会社の担当者に伝えていくことで従業員側から〇〇を利用したいと声があがるようにアピールしたことで導入の合意を得ることができ、コロナ対応に間に合わせることが出来ました。御社でもコロナ対応、ユーザーの利便性向上に向けてシステム導入を率先して引っ張っていきます。

ただ実績をあげたことをアピールするのではなく、自身の長所や強みがどのようにその経験に活かされたかを盛り込んでいきましょう。社内SEではヘルプデスク対応など受け身である人が多くいますが、自身が率先してシステム導入や改善を進めたことをアピールできると面接官の印象がいいですね。

転職理由、志望動機

面接官)
今回の転職理由を教えてください

回答例)
全体を俯瞰、全体最適を意識したシステム提供を実現できる環境でよりユーザや事業に貢献していきたいと考え転職を決意しました。その一手段として例えば・・・

転職理由は必ず聞かれる質問です。本来の理由であれば「収入をあげたい」「残業を減らしたい」「有名企業で働きたい」などでしょうが(自分もそうです)、ここはもっと掘り下げて何故転職を考えたのかを考察していきましょう。
例えば「収入をあげたい」が本音であれば、「収入をあげたい」→「もっと給与をもらえる技術がある」→「技術を活かしたい」と掘り下げることが出来ます。「技術を活かしたい」ことが本質であればそこに肉付けをして「自身の技術を活かせる環境で社会や事業に貢献したい」となり、これが転職理由となります。

面接官)
弊社の志望動機はなんですか?(なぜ弊社がよいか、弊社でどうなっていきたいか)

回答例)
現在の会社での課題や悩みの解決のために情報を検索したところ、御社では既に対応している記事を多くみつけました。例えば〇〇〇の記事を拝見し、技術力が高いことはもちろんですが、ユーザーの潜在的な課題を導き出し、それに対してスピード感をもって仕組みを創り上げてきたことで他社よりも2歩も3歩も進んでいると感じました。また、単一のシステムでの対応ではなく色々な検索の仕組みに対応するためにこの仕組みを導入していることに自身が目指している全体を俯瞰して部分最適ではなく全体最適を意識した仕組み創りに既に着手していることを感じ取りました。私も同じ思想のもとで従業員が自身の仕事に集中できる仕組みを作り上げていきたいと強く思いました。

志望動機もかなり頻度が高い質問です。転職理由と同様に本音を掘り下げていき、志望動機を考えていきましょう。ここで重要なのはちゃんと企業研究を行うことです。その企業の現状や強み、大事にしていることを理解出来ていなければ別の企業でいいんではないかと思われてしまいます。私が企業研究する場合には、その企業のTechブログや記事などを読み込み、どんな課題に対してどのような技術を用いて対応したのか、その対応によりどのような効果が表れたかを確認することで、その企業が何を重視しているかを知ることが出来ます。

例えばSlack関連の開発や改善の記事があるのであれば、この企業はコミュニケーションについて課題を感じ、コミュニケーションを活性化させたいと考えていると推測できます。つまり社員間の情報共有を大切にしている企業であるということです。このようにその企業の情報からニーズを確認し、それを盛り込んだ志望動機を考えることが重要です。

キャリアプラン

面接官)
入社をして何をしたいと思っていますか?

面接官3~5年先にこうなっていたいというイメージを教えてください

回答例)
社内システム全てを把握し、個別最適ではなく全体最適を自らが先導して進めていける人物をイメージしています。システム投資は、経営戦略を実現するもので、それが構築できるのは複数の現場を俯瞰する情報システム部門が最も適していると考えています。自分の○○○という強みを発揮して現場のヒアリングから潜在的な課題を導き出し、従業員が自身の仕事に集中できる仕組みを作り上げていきたいです。

面接官はこの質問でどのチーム(プロジェクト)にもっとも適しているかを判断したいと考えています。まったく経験の無いことをやりたいとアピールすると面接官もイメージがしづらいと思いますので、章立てて「まずは○○の経験を活かして、△△に携わりたいと考えています。そちらで実績を積み、2〜3年後にはマネージャーを目指したいと考えています。」といったようにまずは即戦力として活躍できるポジションをアピールし、そこで実績を積んだうえで数年後に目指したい姿をアピールできると面接官もイメージしやすいと思います。

目標が高すぎる(社長になりたいなど)となれなかった時に退職のリスクがあると思われてしまいますし、逆に低いと入社しても成長しないのではないかと思われてしまうので、現実的な目標をイメージするようにしましょう。

今までの経験

面接官)
今までの業務の中での成功体験をお聞かせください

回答例)
システムやグループ会社毎にセキュリティルールがバラバラだったものを現状のリスクを洗い出し、それをリスクヘッジできるようにするために基本となるセキュリティポリシーを設計(IP制御からデバイス制御)しました。それを経営陣やグループ会社に説明することで今のままではリスクがあること、それをルールを定義することでリスクヘッジ出来ることを理解してもらい、セキュリティポリシーを刷新することが出来ました。これによりセキュリティを強化したうえでリモートワークへシフトすることが出来ました。

面接官は成功体験を聞くことでどんなことに気をつけて、何を重視してやり遂げたかを確認したいと考えています。ただメンバーとしてプロジェクトに関わっただけでは弱いので、自身が主体的にどんな役割を担ったか、どんなことを工夫したかを盛り込むようにしましょう。

面接官)
現職での失敗体験があれば聞かせてください

回答例)
グループのメンバーと案件を進める際に案件の進め方から注意ポイントまで細かく指示を出して案件を進めたことがあり、案件自体は問題なく完了まで進めることが出来ましたが、同様の案件の際も自分が指示をしないとメンバーが進められなくなってしまった経験がありました。メンバーの成長も考え、あえて1から10までやることや意義、目的を言わずにメンバー自身が考える能力を身に着けられるようにマネジメントのやり方を変えました。これによりメンバーが成長し、メンバーに安心して案件を任せられるようになっただけでなく、メンバーが私から認められていると感じたようで私への信頼感もあがり、グループのパフォーマンスが向上しました。

面接官はこの質問で失敗から何を学んだのか?どのように乗り切ったかを確認したい考えています。ただ失敗の話をするだけでなく、なぜ失敗したのかを考察する能力もみていますので、ちゃんと失敗の本質について向き合うことが大事です。失敗の原因がわかればそこに対してどのように対処すればいいかが見えてくると思います。

一番ダメなのは他責にすることなので、「○○のせいで」や「自分のせいではない」といった回答はしないように気をつけてください。

こちらからの質問も用意しましょう

面接では最後にこちらから質問する時間があります。質問が無いと回答してしまうと「うちの会社に興味がないんじゃないか?」と思われてしまう可能性がありますので、事前に聞きたいことを2〜3つ用意しておきましょう。

質問例)
御社のHPブログで〇〇に取り組んでいるという記事を拝見しました。○○に課題を感じ、取り組んでいると感じましたが、リモートワークに対してはどのような取り組みを検討されているのでしょうか?

質問例)
○○様の目から見て、現状の社内システムの課題は何でしょうか?

質問例)
これから導入予定(導入を検討している)のシステムはありますか?

質問例)
〇〇様のお立場だからこそわかる御社の魅力や、今後強化していくべき点を教えていただけますか?

質問をすることでよりその企業の理解が深まり、企業を選定する情報が増えるだけでなく、面接官へ志望度をアピールすることにもつながります。回答例にある通り、Techブログを読んで、自分はこう考えているがいかがでしょうかといった質問であれば、ちゃんと企業研究をしていることが伝わりますし、物事の本質を捉える能力があることもアピールできます。

絶対にしてはいけない質問は以下の通りです。

  • 給与や福利厚生について聞くこと
    →お金にしか興味がないと思われる
  • 残業時間を聞くこと
    →定時しか働かないと思われる
  • 企業のホームページなどに情報があることを質問すること
    →企業研究が足りないと思われる
  • 回答しづらい内容の質問
    →回答ができなく、雰囲気が悪くなる

まとめ

面接でよく聞かれる質問を回答例をもとに解説していきました。1番大事なことは自分の経験や思いについて深堀をすることで何をそこから学んだのか、何が自身の強みなのか、それらを活かして会社に貢献できるかを面接官に伝える準備を行うことです。就職・転職を考えているエンジニアの方々の参考になれば幸いです。

プログラミングの心構え、若者よ努力してプログラムを好きになれ!【他人にやあされている練習を努力とは言わねだろう by メジャー吾郎】

プログラミング歴40年の田舎在宅プログラマーが感じたことを発信していきます

アクティブ・ラーニングについて https://menta.sutaruhin.com/?p=3242

メジャー公式サイト https://www.shopro.co.jp/tv/major2nd/

デスノート http://www1.ntv.co.jp/deathnote/character/index.html

Re.ゼロ公式サイト http://re-zero-anime.jp

一部抜粋いたしましたが、上記をクリックし詳細をご確認ください

2016年から6年間CodeCamp講師でしたが本日解除されました。くそお世話になりました【サンジ風】

悲しいお話ではありません。プログラミングスクールへの参画を数社とこちらのCodeCampさんにお世話になっておりました。最近はCodeCampさんの生徒さんが著しく少なくなってきましたので、またコンビニ並の単価だったのでここ数年は幽霊講師でした。先月アンケートで「昨年度の運営利益の用途」と「カリキュラムの問題」の指摘をさせて頂き、対策案をご意見をさせていただきましたところ契約続行しないということになりました。致し方ないかなと感じております

しかし、いきなり講師間の連絡であるslackが閉鎖されたのでご挨拶も行えず、継続講習の問題発生時の相談窓口も閉鎖されたので触れてはいけないことだったんだー。と切羽詰まっている現状を知ることができました。

本当に先生方や、生徒様いままで大変お世話になりました

がんばって躍進されてください。ご健康をお祈りいたします。

CodeCamp様も益々のご発展をお祈りいたします。お世話になりました。

※数年前までは、時給を倍にするからこの時間は講師をお願いしますと言われていたのですが。懐かしい思い出です(当時はびっくりしてました)

マンツーマン講義はチケット制度ですが、若い先生が多くはいられてますので是非、下記クリックより無料相談を行ってご検討ください。

マルチ認証の実現方法【Laravel6:User/Admin分離ログイン】

前提知識

  • Laravel6が使える
  • LaravelのAuth認証を実装した事がある

php artisan make:authは別記事を見てください

参考ソース:Laravel6-Multi-Login

ログイン機能を実装

Migration

まずはMigrationとModelをartisanコマンドを使って作成していきましょう
今回はサボらずに実戦でよく用いられるModelsディレクトリを用意します。

php artisan make:model Models/Admin -m

元々用意されているcreate_users_table.phpの中身をコピーして
作成したcreate_admins_table.phpに貼り付けましょう。database/migrations/2020_02_01_123456_create_admins_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateAdminsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('admins', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('admins');
    }
}

Migrationを実行しておきましょう

php artisan migrate

これでテーブルの準備は出来ました。

Seeder

UserAdminでログインの検証がしたいので、ターミナルからコマンドを叩いて、それぞれテストユーザーを予め作っておきましょう

php artisan make:seeder UsersTableSeeder
php artisan make:seeder AdminsTableSeeder

Userdatabase/seeders/UsersTableSeeder.php

<?php

use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('users')->insert([
            'name'              => 'user',
            'email'             => 'user@example.com',
            'password'          => Hash::make('12345678'),
            'remember_token'    => Str::random(10),
        ]);
    }
}

Admindatabase/seeders/AdminsTableSeeder.php

<?php

use Illuminate\Database\Seeder;

class AdminsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('admins')->insert([
            'name'              => 'admin',
            'email'             => 'admin@example.com',
            'password'          => Hash::make('12345678'),
            'remember_token'    => Str::random(10),
        ]);
    }
}

同時に実行出来るように元々用意されていうDatabaseSeeder.phpで設定します。database/seeders/DatabaseSeeder.php

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call([
            UsersTableSeeder::class,
            AdminsTableSeeder::class,
        ]);
    }
}

Seederを実行しておきましょう

php artisan db:seed

これでテストデータの準備は出来ました。

Model

先ほどのmigrationを作る工程のコマンドでModelsというディレクトリが作成されているはずなので、
最初から用意されているUser.phpModelsにぶち込んでおきましょう。

namespaceを変更するのを忘れずに!!app/Models/User.php

namespace App\Models;

別ファイルでUser.phpをuseしている箇所があるので、そちらも抜けなく変更しましょう。

下記ファイルのApp\User部分をApp\Models\Userに変更します。

  • app/Http/Controllers/Auth/RegisterController.php
  • config/auth.php
// App\User
App\Models\User

では管理者用のAdmin.phpも作成しておきましょう。

extendsがModelからAuthenticatableに変わっているので注意しましょう

app/Models/Admin.php

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class Admin extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

認証方式の追加(Guard)

それじゃAdminの認証方式を追加します。
この記事を読むと良いです。

Laravel の Guard(認証) って実際何をやっているのじゃ?

config/auth.php

<?php

return [

    // デフォルトの認証をwebからuserに変更
    'defaults' => [
        'guard' => 'user',
        'passwords' => 'users',
    ],

    'guards' => [
        'user' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        // Admin用の認証を追加
        'admin' => [
            'driver' => 'session',
            'provider' => 'admins',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
            'hash' => false,
        ]
    ],

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],

        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Models\Admin::class,
        ]
    ],

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
            'throttle' => 60,
        ],

        'admins' => [
            'provider' => 'admins',
            'table' => 'password_resets',
            'expire' => 60,
            'throttle' => 60,
        ]
    ],

    'password_timeout' => 10800,

];

Controller

さて下の構成にするためにまずはControllers配下にAdminUserディレクトリを作成しましょう。

controllers
   ├── Admin
   │   ├── Auth
   │   │   ├── LoginController.php
   │   │   ├── RegisterController.php
   │   └── HomeController.php
   ├── User
   │   ├── Auth
   │   │   ├── LoginController.php
   │   │   ├── RegisterController.php
   │   └── HomeController.php
   └── Controller.php

作成できたら以下のコマンドをターミナルから入力してファイルを作成しましょう。
HomeControllerはLogin後の画面を出力するために使用します。

Admin

php artisan make:controller Admin/HomeController --resource

User

php artisan make:controller User/HomeController --resource

….完了したら元々あるAuthディレクトリをそれぞれの階層に設置してください!

Adminapp/Http/Controllers/Admin/HomeController.php

<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class HomeController extends Controller
{

    public function __construct()
    {
        $this->middleware('auth:admin');
    }

    public function index()
    {
        return view('admin.home');
    }

}

Userapp/Http/Controllers/User/HomeController.php

<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class HomeController extends Controller
{

    public function __construct()
    {
        $this->middleware('auth:user');
    }

    public function index()
    {
        return view('user.home');
    }

}

Routing(ルーティング)

作成したControllerとパスを紐づける&Auth認証をそれぞれ指定します。routes/web.php

<?php

// ユーザー
Route::namespace('User')->prefix('user')->name('user.')->group(function () {

    // ログイン認証関連
    Auth::routes([
        'register' => true,
        'reset'    => false,
        'verify'   => false
    ]);

    // ログイン認証後
    Route::middleware('auth:user')->group(function () {

        // TOPページ
        Route::resource('home', 'HomeController', ['only' => 'index']);

    });
});

// 管理者
Route::namespace('Admin')->prefix('admin')->name('admin.')->group(function () {

    // ログイン認証関連
    Auth::routes([
        'register' => true,
        'reset'    => false,
        'verify'   => false
    ]);

    // ログイン認証後
    Route::middleware('auth:admin')->group(function () {

        // TOPページ
        Route::resource('home', 'HomeController', ['only' => 'index']);

    });

});

Auth

Laravel6.8以降から$redirectToのプロパティがRouteServiceProviderの定数で管理されるようになりました!今回はRouteServiceProviderの例を書いていきます!

参考
【Laravel6.8以降】認証関連のリダイレクト先の設定変更がDRYになったよ

RouteServiceProvider

ではデフォルトのリダイレクト先が/homeになっている部分を変更して、なおかつAdminのリダイレクト先を指定する定数も追加します。

Laravel6.8以下のバージョンの方はLoginControllerなどに用意されている$redirectToプロパティの値を変更してください。

app/Providers/RouteServiceProvider.php

// Userのリダイレクト先
public const HOME = '/user/home';

// Adminのリダイレクト先
public const ADMIN_HOME = '/admin/home';

Authenticate(未ログイン時の挙動)

未ログイン時にログイン認証が必要なページにアクセスした時のリダイレクト先を指定します。app/Http/Middleware/Authenticate.php

<?php

namespace App\Http\Middleware;

use Illuminate\Support\Facades\Route;
use Illuminate\Auth\Middleware\Authenticate as Middleware;

class Authenticate extends Middleware
{
    protected $user_route  = 'user.login';
    protected $admin_route = 'admin.login';

    protected function redirectTo($request)
    {
        // ルーティングに応じて未ログイン時のリダイレクト先を振り分ける
        if (!$request->expectsJson()) {
            if (Route::is('user.*')) {
                return route($this->user_route);
            } elseif (Route::is('admin.*')) {
                return route($this->admin_route);
            }
        }
    }
}

RedirectIfAuthenticated(ログイン時の挙動)

逆にログインしてる時に/loginにアクセスしてきた時のリダイレクト先を指定します。app/Http/Middleware/RedirectIfAuthenticated.php

<?php

namespace App\Http\Middleware;

use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check() && $guard === 'user') {
            return redirect(RouteServiceProvider::HOME);
        } elseif (Auth::guard($guard)->check() && $guard === 'admin') {
            return redirect(RouteServiceProvider::ADMIN_HOME);
        }

        return $next($request);
    }
}

User

ログイン

app/Http/Controllers/User/Auth/LoginController.php

<?php

namespace App\Http\Controllers\User\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    use AuthenticatesUsers;

    protected $redirectTo = RouteServiceProvider::HOME;

    public function __construct()
    {
        $this->middleware('guest:user')->except('logout');
    }

    // Guardの認証方法を指定
    protected function guard()
    {
        return Auth::guard('user');
    }

    // ログイン画面
    public function showLoginForm()
    {
        return view('user.auth.login');
    }

    // ログアウト処理
    public function logout(Request $request)
    {
        Auth::guard('user')->logout();

        return $this->loggedOut($request);
    }

    // ログアウトした時のリダイレクト先
    public function loggedOut(Request $request)
    {
        return redirect(route('user.login'));
    }
}
新規登録

app/Http/Controllers/User/Auth/RegisterController.php

<?php

namespace App\Http\Controllers\User\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Auth;
use App\Models\User;

class RegisterController extends Controller
{
    use RegistersUsers;

    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest:user');
    }

    // Guardの認証方法を指定
    protected function guard()
    {
        return Auth::guard('user');
    }

    // 新規登録画面
    public function showRegistrationForm()
    {
        return view('user.auth.register');
    }

    // バリデーション
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name'     => ['required', 'string', 'max:255'],
            'email'    => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);
    }

    // 登録処理
    protected function create(array $data)
    {
        return User::create([
            'name'     => $data['name'],
            'email'    => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
    }
}

Admin

基本的に上のuserの部分をadminに直すだけです。
なのでコメントは外します。

ログイン

app/Http/Controllers/Admin/Auth/LoginController.php

<?php

namespace App\Http\Controllers\Admin\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    use AuthenticatesUsers;

    protected $redirectTo = RouteServiceProvider::ADMIN_HOME;

    public function __construct()
    {
        $this->middleware('guest:admin')->except('logout');
    }

    protected function guard()
    {
        return Auth::guard('admin');
    }

    public function showLoginForm()
    {
        return view('admin.auth.login');
    }

    public function logout(Request $request)
    {
        Auth::guard('admin')->logout();

        return $this->loggedOut($request);
    }

    public function loggedOut(Request $request)
    {
        return redirect(route('admin.login'));
    }
}
新規登録

app/Http/Controllers/Admin/Auth/RegisterController.php

<?php

namespace App\Http\Controllers\Admin\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Auth;
use App\Models\Admin;

class RegisterController extends Controller
{
    use RegistersUsers;

    protected $redirectTo = RouteServiceProvider::ADMIN_HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest:admin');
    }

    protected function guard()
    {
        return Auth::guard('admin');
    }

    public function showRegistrationForm()
    {
        return view('admin.auth.register');
    }

    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name'     => ['required', 'string', 'max:255'],
            'email'    => ['required', 'string', 'email', 'max:255', 'unique:admins'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);
    }

    protected function create(array $data)
    {
        return Admin::create([
            'name'     => $data['name'],
            'email'    => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
    }
}

View

viewは以下の構成で実装します。

views
├── user
│   ├── auth
│   │   ├── login.blade.php
│   │   └── register.blade.php
│   └── home.blade.php
│
├── admin
│   ├── auth
│   │   ├── login.blade.php
│   │   └── register.blade.php
│   └── home.blade.php
│
└── layouts
    ├── user
    │    └── app.blade.php
    │
    └── admin
         └── app.blade.php
layouts

Userresources/views/layouts/user/app.blade.php

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
            <div class="container">
                <a class="navbar-brand" href="{{ url('/') }}">
                    {{ config('app.name', 'Laravel') }}
                </a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <!-- Left Side Of Navbar -->
                    <ul class="navbar-nav mr-auto">

                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="navbar-nav ml-auto">
                        <!-- Authentication Links -->
                        @unless (Auth::guard('user')->check())
                            <li class="nav-item">
                                <a class="nav-link" href="{{ route('user.login') }}">{{ __('Login') }}</a>
                            </li>
                            @if (Route::has('user.register'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('user.register') }}">{{ __('Register') }}</a>
                                </li>
                            @endif
                        @else
                            <li class="nav-item dropdown">
                                <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                    {{ Auth::user()->name }} <span class="caret"></span>
                                </a>

                                <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                    <a class="dropdown-item" href="{{ route('user.logout') }}"
                                       onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                        {{ __('Logout') }}
                                    </a>

                                    <form id="logout-form" action="{{ route('user.logout') }}" method="POST" style="display: none;">
                                        @csrf
                                    </form>
                                </div>
                            </li>
                        @endunless
                    </ul>
                </div>
            </div>
        </nav>

        <main class="py-4">
            @yield('content')
        </main>
    </div>
</body>
</html>

Admin

こっちも基本的にuseradminに変えてるだけresources/views/layouts/admin/app.blade.php

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
            <div class="container">
                <a class="navbar-brand" href="{{ url('/') }}">
                    {{ config('app.name', 'Laravel') }}
                </a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <!-- Left Side Of Navbar -->
                    <ul class="navbar-nav mr-auto">

                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="navbar-nav ml-auto">
                        <!-- Authentication Links -->
                        @unless (Auth::guard('admin')->check())
                            <li class="nav-item">
                                <a class="nav-link" href="{{ route('admin.login') }}">{{ __('Login') }}</a>
                            </li>
                            @if (Route::has('admin.register'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('admin.register') }}">{{ __('Register') }}</a>
                                </li>
                            @endif
                        @else
                            <li class="nav-item dropdown">
                                <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                    {{ Auth::user()->name }} <span class="caret"></span>
                                </a>

                                <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                    <a class="dropdown-item" href="{{ route('admin.logout') }}"
                                       onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                        {{ __('Logout') }}
                                    </a>

                                    <form id="logout-form" action="{{ route('admin.logout') }}" method="POST" style="display: none;">
                                        @csrf
                                    </form>
                                </div>
                            </li>
                        @endunless
                    </ul>
                </div>
            </div>
        </nav>

        <main class="py-4">
            @yield('content')
        </main>
    </div>
</body>
</html>

View(ログイン)

スクリーンショット 2020-02-20 16.51.54.png

先ほどSeederで登録した情報でログインできます

Userresources/views/user/auth/login.blade.php

@extends('layouts.user.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Login') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('user.login') }}">
                        @csrf

                        <div class="form-group row">
                            <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <div class="col-md-6 offset-md-4">
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>

                                    <label class="form-check-label" for="remember">
                                        {{ __('Remember Me') }}
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="form-group row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Adminresources/views/admin/auth/login.blade.php

@extends('layouts.admin.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Login') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('admin.login') }}">
                        @csrf

                        <div class="form-group row">
                            <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <div class="col-md-6 offset-md-4">
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>

                                    <label class="form-check-label" for="remember">
                                        {{ __('Remember Me') }}
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="form-group row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
View(新規登録)
スクリーンショット 2020-02-20 16.52.39.png

Userresources/views/user/auth/register.blade.php

@extends('layouts.user.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Register') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('user.register') }}">
                        @csrf

                        <div class="form-group row">
                            <label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>

                            <div class="col-md-6">
                                <input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>

                                @error('name')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>

                            <div class="col-md-6">
                                <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
                            </div>
                        </div>

                        <div class="form-group row mb-0">
                            <div class="col-md-6 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Register') }}
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Adminresources/views/admin/auth/register.blade.php

@extends('layouts.admin.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Register') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('admin.register') }}">
                        @csrf

                        <div class="form-group row">
                            <label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>

                            <div class="col-md-6">
                                <input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>

                                @error('name')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>

                            <div class="col-md-6">
                                <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
                            </div>
                        </div>

                        <div class="form-group row mb-0">
                            <div class="col-md-6 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Register') }}
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

View(ログイン後の画面)

スクリーンショット 2020-02-20 16.53.24.png

Userresources/views/user/home.blade.php

@extends('layouts.user.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Dashboard</div>

                <div class="card-body">
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif

                    You are logged in!
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Adminresources/views/admin/home.blade.php

@extends('layouts.admin.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Dashboard</div>

                <div class="card-body">
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif

                    You are logged in!
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

ご活用ください

プログラマーがスキルアップするための「伝える力」と「質問力」

 ITの世界は同調の世界です。会社員であれば上司や先輩、同僚に、フリーランスであれば仕事のオーナーやリーダまたは同じフリーランス要員などチームでシステムを作り上げていきます。そのなかのメンバーとして自分の理解度を正しく伝え、質問することによりスキルアップできると主に全体のシステム進捗アップを行って効率よく進めていきます。よって日常は指示を仰ぐ、意見をもらうなど、職場は毎日「質問」であふれています。質問を上手に使いこなすことで、チームでのコミュニケーションが良好になったり、仕事を円滑に進められたりするなど、好循環が生まれます。逆に質問は相手の貴重な時間を奪っていることを最も考えなければいけないことなのです。そこで今回は「質問力」を磨くポイントやテクニックをご紹介します。質問力アップの参考にしてフルスタックエンジニアを目指してみてください。

「質問力」アップで得られるメリット

質問とは「わからないところや疑わしい点について問いただすこと。また、その内容」。それ以外にも、円滑なコミュニケーションによって仕事の効率が上がったり、新しい情報を知ることで自身の成長に繋げられたり、質問によってさまざまなことを得ることができます。「質問力」が持つ力を知れば、あなたもきっと磨きたくなるはずです。

メリット1. 疑問が解消されスキルアップできる

質問することで得られる代表的なものは、不明だったことが明確になったり、新たな情報を得られることです。また質問力がつけば、インフラなど専門外の分野についても質問できるようになり、それによって得られた情報を理解・習得していくことができます。さらに、頭の中で考えていることを言葉にすることで、質問した人、質問された人双方の考えが整理され、情報共有を図りやすくなります。

メリット2. 思い込みが取り払われる

誰しも、多かれ少なかれ持っている思い込み。とりわけ、ネガティブな思い込みは行動を制限してしまいます。または仕様の勝手な思い込みでチームのメンバーに大きな代償となってのしかかる危険もあります。誰かに問いかけたり会話したりすることで、その思い込みには実は根拠がないことに気づくことができます。自分の論理を他人へ話すことにより指摘で気付かされることや、自分の矛盾に気づくことで早期に悪い芽が刈り取ることができるようになっていきます

メリット3. 相手との心の距離を縮められる

質問には、質問をする側と質問をされる側をフラットな関係にする力があります。例えば、上司からの指示・命令について部下が質問することで、上司に気づきを与えるきっかけになるなど、一方通行のコミュニケーションから双方向のコミュニケーションに変化させる可能性を持っています。また、相手の得意分野や関心ごとなどについて質問をすることで興味や好意が伝わり、「私に興味を持ってくれている!」と感じてもらうことができます。大切なスキンシップなのです。

メリット4. 人脈に変えられる

このスキルならばこの人が一番詳しいや素直に質問する姿勢し理解することで仲間意識が生まれます。Aさんとチーム組むと質問の相乗効果で進捗や品質が良くなると思われるとめっけ物です。何年も間が開こうが仲間なのです。フリーランスであれば困ったときに助けてもらえます。人は宝なのです。

仕事がうまく回り出す!質問力を上げるポイント&テクニック

ちょっとしたポイントを意識すれば、誰でも「質問力」を上げることが可能です。良い質問は会話を盛り上げるだけでなく、新しい知識や情報を手に入れるチャンスにもなります。質問力を上げて、開発チーム内での良好な関係づくりやスキルアップに生かしましょう!

ポイント1.「傾聴の姿勢」を大切にする

質問する時には、相手への興味や尊敬の念が欠かせません。うなずきながら、目を見ながら、笑顔で安心感を与えながら聞く、などが質問する時のマナーです。また、何度も同じ質問をすることも失礼になるので、聞いたことをきちんとメモするのも忘れずに。

ポイント2.オウム返しを巧みに使う

相手の発言をそのまま繰り返す「オウム返し」。これにより、相手の話に関心を持っていることが伝わり、そこから会話を深めるきっかけになります。業務にまつわる話の場合は、その内容を別の言葉で言い換えて確かめることで、認識のズレやミスを防ぐことができます。ただし会話に限りますslackなどチャットツールで行うと「こいつわかってないな。仕様の根本から話さないといけないから近づくのはやめよう」と逆効果。即刻クビもありえますのであくまでも会話テクニックのみでお使いください。

ポイント3.ネガティブな質問はしない

「おっしゃっている意味がわかりません」「それは必要な作業でしょうか?」など、相手の考えや発言を打ち消すような質問はNGです。相手のやる気を削ぎ、本来望んでいる解決が遠のいてしまいます。相手の言っていることが理解できない場合は、「それはこういう理解で良いでしょうか?」など、確認する質問に置き換えるようにしましょう。

ポイント4.相手に答えを丸投げしない

「どうすればいいですか?」など、相手にだけ考えさせるような受け身の質問は好ましくありません。答えだけわかれば良い。このような考えから発せられる言葉です。調教できない人材のレッテルがその瞬間はられます。「この問題に対して、こう対応しようと思っていますが、ご意見をお聞かせいただけますか?」など、自分なりの仮説を持って、それに対する意見を聞くのが良いでしょう。また、その問題の経過や結果の報告を忘れないことも大切です。ゆとり世代は根本から考え直してください。日本人は受ける教育で育ってます。「でどうなんですか?」筆者は実際いまでもたくさん浴びせさせれてます。質問を受ける側の気持ちなど微塵も感じない人間にだけにはならないでください。このキーワードもフリーランスであれば即刻クビです。

ポイント5.クローズドな質問とオープンな質問を使い分ける

答えが限定される「クローズドな質問」は余計な話をしてほしくない場合や、シンプルにイエスかノーかだけを知りたい場合に役立ちます。逆に、相手に自由に答えてもらう「オープンな質問」は、自分では答えを予想できない時や自由な意見がほしい時に使いましょう。さらに、5W1H(※)を含めた問いかけにすると、より具体的な答えを得ることができます。2種類の質問を、上手に使い分けるようにしましょう。
※5W1HとはWho(だれが)When(いつ)、Where(どこで)、What(なにを)、Why(なぜ)、 How(どのように)を指し示すビジネス用語。

ポイント6.ネタに困ったら「木戸に立ちかけし衣食住」

初対面の人などと話す時、共通の話題がすぐに見つからない場合は、会話をはじめるきっかけに「木戸に立ちかけし衣食住」というキーワードを覚えておくと便利です。「き」は季節や気候、「ど」は道楽や趣味、「に」はニュース、「た」は旅や休日、「ち」は知人や地域、「か」は家族やペット、「け」は健康、「し」は仕事、そして「衣食住」にまつわる質問です。ただし、プライバシーに踏み込みすぎた質問には注意しましょう。

「質問力」を上げて、仕事効率も人間関係も良好に

質問というと、「分からないことを聞く」と捉えがちですが、目的を持った問いに変化させることで、得られる情報の量や質が変わります。また、相手や自分のマインドを良い方向へと導くこともできます。質問することに苦手意識がある人はプログラミの世界には向いていません。誰でも最初は苦手です。しかし、日々 “良い質問”を意識して使うことで質問する力はどんどん磨かれていきます。質問力が上がれば、今よりもっと仕事がしやすくなり自分のスキルアップで価値がアップしていきます。転職は引く手あまた。フリーランスは営業しなくてもひっきりなしに連絡が途切れなく入ってきます。成功すること間違いなし! ぜひ、今日から“質問力磨き”をはじめましょう。

2021.08.21 GitHubでhttpsのパスワード認証が廃止されました。Please use a personal access token instead.

作業中にgit pushしたところいままでうまく言っていたのですが下記エラーが発生しました。

$ git push origin main
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: unable to access 'https://github.com/名前/リポジトリ.git/': The requested URL returned error: 403

Please use a personal access token instead.
訳: 代わりにパーソナルアクセストークンを使用してください。

事件です。GitHubで2021年8月13日にパスワード認証が廃止されたそうです。
悔しいですね。個人アクセストークンを使うようにしましょう

GitHub 個人アクセストークンを作成する

GitHubにアクセスするとき必要となる、個人アクセストークンを作成していきます。

個人アクセストークンとは、「コマンドラインでのGit操作」や「Gitを使用するアプリケーション」「Gitリポジトリに直接アクセスするアプリケーションやサービス」を利用するときのパスワードの代わりになるものです。GitHubは、2021年8月13日以降、Git操作におけるパスワード認証を廃止し、トークンベースの認証を必須にする方針を発表しています。 これにより、パスワードを用いてのアクセスができなくなってしまいます。したがって、この操作は必ず行っておきましょう。セキュリティの観点から、GitHubは、過去1年間使用されていない個人アクセストークンは自動的に削除します。削除された場合は、再度作成する必要があります。

トークンの作成

1. GitHubのWebページにアクセスし、右上にあるプロフィールの画像をクリックします。

2. メニューからSettingsをクリックします。

3. 左サイドバーからDeveloper settingsをクリックします。

4. 続いて、左サイドバーからPersonal access tokensをクリックします。

5. Generete new tokenをクリックします。

6. 作成するトークンにわかりやすい名前をつけ、このトークンに付与するスコープとして、repogistを選択します。なお、選択したrepo は、このトークンを使用してコマンドラインからリポジトリにアクセスすることができる権限です。では、Generate token をクリックして実際に作成します。

7. 作成されたトークンをメモとして残しておき、忘れないようにしてください。メモを書き間違うことが心配な場合は、スクリーンショットを撮っておくと良いでしょう。

なお、この画面はセキュリティ上の理由で、別ページに移動すると、再度見ることができなくなるので、注意しておいてください。
今回作成したトークンは、ターミナルを使ってコマンドラインからGithubのリポジトリにアクセスする際にパスワードとして使用することになります。

GitHubへリポジトリを反映するための一連の流れ

GitHubへリポジトリを反映させるためには、下記の手順で実行しましょう。

  1. GitHubにリモートリポジトリを作成する
  2. ローカルリポジトリにリモートリポジトリを登録する
  3. ローカルリポジトリのブランチ名を変更する
  4. 登録したリモートリポジトリへプッシュする
  5. GitHubのリモートリポジトリにプッシュされたか確認する

GitHubにリモートリポジトリを作成する

first-gitという名前でGitHubにリモートリポジトリを作成して、公開しましょう。

まずはGitHubへアクセスし、ログインしてください。次に+ボタンから「New repository」をクリックしましょう。

GitHubへリモートリポジトリを作成します。「Repository name」にfirst-gitと入力して、「Create repository」をクリックしてください。

これでリモートリポジトリが作成されましたが、まだ中身は空っぽです。ローカルリポジトリをリモートリポジトリにもコピーして反映させるためにプッシュというコマンドが必要となります。まずはその準備のためにローカルリポジトリにリモートリポジトリを登録していきます。

ローカルリポジトリにリモートリポジトリを登録する

ローカルリポジトリにリモートリポジトリを登録するには、先ほどのキャプチャ内にあった下記のコマンドを実行します。

git remote add origin https://github.com/ユーザ名/first-git.git

このコマンドは、ローカルリポジトリにoriginという名前でリモートリポジトリ(ここではfirst-git.git)を登録するという意味です。ユーザ名には皆さんのGitHubでのユーザ名を入力してください。

これでローカルリポジトリにリモートリポジトリを登録できました。以降、このローカルリポジトリでは、originを使用してリモートリポジトリとやり取りを行うことができます。したがって、git remote add origin ...のコマンドは何度も実行する必要はありません。

リモートリポジトリの登録状況を確認したい場合は下記のコマンドで確認することができます。

git remote -v

ローカルリポジトリのブランチ名を変更する

次に、ローカルリポジトリのブランチ名をmasterからmainに変更します。これは、5.4 ブランチのデフォルトのブランチ名で解説したとおり、リモートリポジトリのデフォルトブランチ名(main)とローカルリポジトリのデフォルトブランチ名(master)が異なっているためです。

git branch -M main

上記コマンドを実行すると、これまで(master)とターミナルに表示されていましたが、(main)に変更されます。

Macの方の注意事項です

macOS キーチェーンからの認証情報を削除する必要があります

git credential-osxkeychain erase

下記は参考サイトです

https://docs.github.com/ja/github/getting-started-with-github/getting-started-with-git/updating-credentials-from-the-macos-keychain

わかりにくければ、下記のほうが簡単に書かれてます

https://zenn.dev/hayata_yamamoto/articles/github-access-key

Laravel6でのログイン失敗回数オーバでロックさせるコーディング【Throttle機能】

Throttle機能とは

Throttle機能とは、ログイン失敗時に失敗した場合、一定の指定回数を超えた場合にログインにロックを掛けて、一定の時間を経過したらロックを解除する機能です。

Throttle機能を使う

実装方法は $maxAttemptsと$decayMinutesをLoginController内に設定するだけです。

<?phpclass LoginController extends Controller{    use AuthenticatesUsers;    protected $maxAttempts = 5; // 5回失敗したらロックする    protected $decayMinutes = 30; // ロックは30分間

ロックした時にメッセージを出すようにする

しかし、$maxAttemptsに設定された回数失敗したらロックされるのですが、ロックされた旨のメッセージは設定した回数失敗した際には表示されません。
ロックしたらその時に知らせてほしいものです。そこで、ロックしたメッセージがすぐに表示されるようにしてみます。

ロックのエラー処理は、loginメソッド内でやっています。 ログイン判定前に、処理をしているようなので、ログイン判定後に改めてロックの判定を行うように追記します。

<?php
    public function login(Request $request)    {
       $this->validateLogin($request);
       if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);
            return $this->sendLockoutResponse($request);
        }          if ($this->attemptLogin($request)) {
            return $this->sendLoginResponse($request);
        } 
        $this->incrementLoginAttempts($request);
         // このif文を追記
        if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);
            return $this->sendLockoutResponse($request);
        }
          return $this->sendFailedLoginResponse($request);
    }

これでロックしたらすぐにメッセージが出るようになります。

失敗回数はログインID毎ではなく全体での回数にする

Laravelではログインの失敗のカウントは、ログインID毎に判別しているようです。
つまり、あるアカウントはロックされても、別のアカウントならログイン可能ということです。 これを全体で失敗した回数にしたいと思います。

throttleKeyというメソッドでログインを判別するためのキーを生成しているので、これをLoginController内でオーバーライドして修正します。

Str::lower($request->input($this->username())).’|’.$request->ip()となっていて、ログイン名(通常はemail)とIPを元にキーを生成しています。 このキーを元にカウントアップするので、アカウントごとに失敗した回数が設定されるというわけですね。

なので、ここを以下のように修正します。

    protected function throttleKey(Request $request)    {
        return $request->ip();
    }

これでアカウントは関係なく同一IPからの失敗でカウントされるようになります。

以上になります。参考にされてくださいね。

プログラムオンライン学習!「教育訓練給付金制度」お金come back!できるお得おすすめ講座。

トータル費用を考えて高度な学習を受けよう

ハローワークへ事前申請すれば50%~70%戻ってくる制度があることをご存知でしょうか。最終課題までクリアーしないといけませんが、逆に頑張れるというものではないでしょうか。まず制度の内容を説明し、その後、プログラミング歴40年の筆者オススメの講座紹介いたします。国が力を入れているのはデータサイエンスとAIです。ITの世界はコロナ不況より新たな変革期に入ってきたと筆者は考えております。いち早くキャッチし自分に優位な知識を養いましょう。

「教育訓練給付制度」とは

厚生労働省が個人に向けて支援する「教育訓練給付金制度というものがあります。

教育訓練給付金とは

働く方の主体的な能力開発の取組み又は中長期的なキャリア形成を支援し、雇用の安定と再就職の促進を図ることを目的とし、教育訓練受講に支払った費用の一部が支給されるものです。
また、初めて専門実践教育訓練(通信制、夜間制を除く)を受講する方で、受講開始時に45歳未満など一定の要件を満たす方が、訓練期間中、失業状態にある場合に訓練受講をさらに支援するため、「教育訓練支援給付金」が支給されます.。
引用元:厚生労働省公式HP「教育訓練給付制度」

教育訓練給付金制度は、さらに下記3つに分かれています。そしてどれもハローワークに申請する必要があります。だいたい通算3年以上会社員として勤務し保険が給料天引きになっている方が対象です。この条件を、満たしていれば、離職後1年以内であれば利用できます。

①一般教育訓練給付金

一般教育訓練給付金は、雇用の安定と再就職を促進する目的で設けられた、雇用保険の給付制度のこと。多くのプログラミングスクールが、一般教育訓練給付金の認定校に登録されています。支給額は、支払った受講料の20%に相当する金額。上限は10万円で、受講料の20%が4,000円を超えない場合は給付金の対象外となります。

②専門実践教育訓練給付金

専門実践育訓練給付金とは、雇用保険の一般被保険者等または一般被保険者等であった方が、厚生労働大臣指定の専門実践教育訓練を卒業した場合に受講料の一定額をハローワークが支給する制度のことです。つまり、在職中・離職後にかかわらず指定されたプログラミングスクールを受講して卒業すれば返金されるということ。

指定されているスクールは、一般教育訓練給付金で認可されたところよりもハイレベルであることが多いです。支給額は受講料の50%で、年間の上限は40万円です。また、専門実践教育訓練を卒業した後1年以内に転職して雇用保険の被保険者になった場合、受講料の70%(年間上限56万円)を受給することができます。

③特定一般教育訓練給付金

特定一般教育訓練給付金は、令和元年10月に設立された新しい制度です。特定一般教育訓練給付金は対象講座が指定されており、下記の4つになります。

  • 独占資格や必置資格に関する養成課程
  • 情報通信技術に関する資格のうちITSSレベル2以上の情報通信技術に関する資格取得を目標とする課程
  • 新たなITパスポート試験合格目標講座
  • 短時間のキャリア形成促進プログラムおよび職業実践力育成プログラム

初回の給付を受けたい場合は支給要件期間が1年です。支給額は受講料の40%(上限20万円)となります。条件が合えば、申請してみてはいかがでしょうか。

経済産業省が認定する「第四次産業革命スキル習得講座」

政府が支給する給付金は、教育訓練給付制度だけではありません。教育訓練給付制度は厚生労働省が認定したものですが、経済産業省も「第四次産業革命スキル習得講座」を認定しています。国が力入れてますので今後生徒が増えていきます。先行されてみてはどうでしょうか

講座の要件
・育成する職業、能力・スキル、訓練の内容を公開していること
・必要な実務知識、技術、技能を公表していること
・実習、実技、演習又は発表などが含まれる実践的な講座がカリキュラムの半分以上を占めていること
・審査、試験等により訓練の成果を評価していること
・eラーニング等の社会人が受けやすい工夫をしていること
・事後評価の仕組みを構築していること 等

引用元:経済産業省公式HP「第四次産業革命スキル習得講座認定制度」

一番のおすすめ「 経済産業省が認定する「第四次産業革命スキル習得講座」 :AIスキル

私が、データサイエンスとAIにつきましては、豊富なメンターを集めている

AI(人工知能)特化型プログラミングスクール「Aidemy Premium Plan」

がおすすめです。

・AIエンジニア/データサイエンティストにキャリアチェンジしたい
・業務課題(研究課題)をAIを使って解決したい
・教養としてAIについて知りたい
・AIに関してのスキルを身に着け就職活動に活かしたい…

など、これらをお考えの方にマッチしております

■関連実績
・日本最大級のAI/人工知能プログラミングスクール
・「Aidemy Premium Plan」受講者総数 700名突破
・SaaS型AI学習サービス「Aidemy」会員登録者数 55,000名突破
・法人向けAI内製化支援サービス「Aidemy Business」導入企業数 120社突破
・2018年 グッドデザイン賞 (Aidemy)
・「Forbes 30 UNDER 30 JAPAN 2019」エンタープライズ・ビジネス部門 受賞(弊社代表 石川聡彦)
・計算生物学およびバイオインフォマティクスの国際会議 「ICCBB2019」ベストプレゼンター賞 受賞
・第16回 日本e-Learning大賞「AI・人工知能特別部門賞」受賞
・「HRアワード2019」プロフェッショナル部門 入賞
・一般社団法人日本経済団体連合会(経団連)加盟済

■出版
・『人工知能プログラミングのための数学がわかる本』代表 石川聡彦 著
・『Pythonで動かして学ぶ!あたらしい深層学習の教科書 機械学習の基本から深層学習まで』代表 石川聡彦 著
・『独学プログラマーのためのAIアプリ開発がわかる本』河合大 著
・『ブロックチェーンプログラミングのためのコンピュータサイエンスがわかる本』代表 石川聡彦 共著
・『現場で使える!Python深層学習入門 Pythonの基本から深層学習の実践手法まで』木村優志 著
・『図解即戦力 機械学習&ディープラーニングのしくみと技術がこれ1冊でしっかりわかる教科書』山口達輝、松田洋之 著

これらの実績も判断材料にされてください。

【給付金】他にもおすすめプログラミングスクール

  • DMM WEBCAMP —- 転職成功率98%。転職できなければ全額返金。DMM.comグループならではの非公開求人も多数
  • TechAcademy(テックアカデミー) —— 最短4週間で未経験からプロを育てるオンライン完結のスクール
  • Aidemy(アイデミー) —- ブラウザさえあれば10秒で学習スタート!3ヶ月でAI人材をめざす
  • ヒューマンアカデミーITカレッジ —- 初心者・文系出身者でもOK、人材育成のヒューマンアカデミーだから安心
  • DIVE INTO CODE —– 同期とのペアプロやディスカッションで切磋琢磨。必要なスキルがイチから身につく

お得ですので、是非ご検討くださいね

例えば 40万円の費用だと70%戻ってくると28万円が戻ってくるので実質は12万円です。助成金対象は国が進めていることもあり優遇されている点も検討内容に入れてみてはどうでしょうか。大きな自己投資です。後悔しないように無料相談を受けてから検討してください。

プログラミングでの副業・転職・就職の前にブログから始めましょう【経過がポートフォリオになります】

プログラミングを始められる方は、サービス開発後にポートフォリオ公開用としてブログを行いますが、逆にブログで学ばれたことをブログへアウトプットしましょう。理解にも繋がり人間味があるポートフォリオになりますよ。またアフリエイトで収益も入ってきてウハウハですよ。 簡単でマイドメイン名も入って800円/月程です。これもスキルの一環ですぜ!

Laravelフラッシュメッセージの使用方法

はじめに

LaravelをViewの保存ボタンや削除ボタンを押してもアクションの処理メッセージを表示するには書きを行ってみてください。次の画面だけに表示されるフラッシュメッセージが表示できます。セッションへの格納ですが自動削除なので実装が楽です。

フラッシュデータの渡し方

フラッシュデータの渡し方は主に3種類あります

flashメソッドで渡す

Flashメソッドを使うとセッションへstatusという名前のデータを保存できます。
statusの中身は処理が完了しましたです保存アクション内

$request->session()->flash('status', '処理が完了しました');
return redirect('/');

スタティックメソッドを使う

Sessionクラスのflashメソッドを使うことでも値を渡すことができます保存アクション内

\Session::flash('flash_message', '処理が完了しました');
return redirect('/');

withメソッドを使う

flashメソッドと同じようにフラッシュデータを渡せるwithメソッドもあります保存アクション内

return redirect('dashboard')->with('status', '処理が完了しました');

ビューでの表示

次にビューでの表示の仕方について説明します
Bootstrapを使えばいい感じに表示してくれます

@if (session('status'))
    <div class="alert alert-success">
        {{ session('status') }}
    </div>
@endif

以上がフラッシュデータを使ったステータスメッセージの表示仕方です。

フラッシュデータを1つ先のリクエストまで持続させたい場合

reflashメソッドを使うと全フラッシュデータを次のリクエストまで保持できます。

$request->session()->reflash();

特定のフラッシュデータのみ持続させたい場合

keepメソッドを使います。

$request->session()->keep(['user', 'email']);

参考になれば幸いです