建立資料表

CREATE TABLE 資料表名稱 (欄位 欄位類別);

PostgreSQL 實際撰寫SQL有點不相同

PostgreSQL

CREATE TABLE IF NOT EXISTS scores (
   id serial PRIMARY KEY,
   grade INT NOT NULL,
   name VARCHAR(50) NOT NULL,
   score INT NOT NULL,
   PRIMARY KEY (id),
);

MySQL

以下建立一個年級、姓名、分數資料表

CREATE TABLE IF NOT EXISTS `scores`(
   `id` INT UNSIGNED AUTO_INCREMENT,
   `grade` INT NOT NULL,
   `name` VARCHAR(50) NOT NULL,
   `score` INT NOT NULL,
   PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

參考

https://www.postgresql.org/docs/13/sql-createtable.html

https://www.postgresqltutorial.com/postgresql-create-table/

2021 面試紀錄-2

草稿

這間有載明不能分享邏輯題目,但其他的應該可以 所以我也打算不載明哪間公司

基本上就是紙本測驗邏輯,邏輯這種東西,我今天才知道不能有自己的意識,要依照他前面的敘述判斷他的對錯,只是側邏輯,不要加入自己的認知。

PHP機上考試 面試通知只有說PHP但還是有考SQL 但對我來說還蠻簡單的,但沒有辦法實際執行確認。

PHP題目基本上就是基本的兩題實作提,依照敘述完成還算簡單,但有一提我沒有答因為我沒寫完,但我已夢到的方式稍微修改一下在下面簡單實作一次

接著就是一些問答題,主要就是設計模式,還有資安方面的簡單答覆

PHP 問設計原則SOLID,這本書在 使用LARAVEL 8 PHP主流框架打造RESTFUL API(IT邦幫忙鐵人賽系列書) 有簡單提到 SOLID ,基礎在於新手入門,說已只有簡單提一下,這邊寫一片SOLID 簡單敘述給大家看 https://www.vnewin.com/solid-introduction/

資安方面問常見攻擊 XSS以及SQL Injection之前有買過資安線上課程,所以有一點印象

主管的面談的方面,我覺得都還不錯,主要都是花時間在找你想做什麼,並且在他們腦袋裡想要把我放在哪

人資的部分面談主要就是希望可以認識我,並了且擬人資表上面填寫的內容,發表他的疑問請盡情跟他聊天

後來又有一個主管,主要想問我為什麼前一份工作為什麼要離職,離職原因,聊的過程中我找到了真正的原因,還不錯。

但說老實的在徒步環島的過程中,我遇到一些人,他跟我的建議我現在決定在好好思考一下。

這次面試有很多對於面試的心得,我先準備接下來安排的面試 ,日後再看看哪些有拿到 入場券

Laravel 輔助函數 – Array篇

以下對每個方法做自我理解的解釋,皆會擷取官網範例,更佳釐清方法用法。

陣列

Arr::accessible 檢查參數是不是陣列或Collection

use Illuminate\Support\Arr;
use Illuminate\Support\Collection;

$isAccessible = Arr::accessible(['a' => 1, 'b' => 2]);

// true

$isAccessible = Arr::accessible(new Collection);

// true

$isAccessible = Arr::accessible('abc');

// false

$isAccessible = Arr::accessible(new stdClass);

// false

Arr::add([array],[key],[value]) 陣列中如果第二個傳入參數key值,如果「不存在」或 key 的值為 null 寫入陣列

use Illuminate\Support\Arr;
use Illuminate\Support\Collection;

$isAccessible = Arr::accessible(['a' => 1, 'b' => 2]);

// true

$isAccessible = Arr::accessible(new Collection);

// true

$isAccessible = Arr::accessible('abc');

// false

$isAccessible = Arr::accessible(new stdClass);

// false

Arr::collapse 將多個陣列合併成一個

use Illuminate\Support\Arr;

$array = Arr::collapse([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);

// [1, 2, 3, 4, 5, 6, 7, 8, 9]

Arr::crossJoin 這叫笛卡兒積,返回所有陣列

use Illuminate\Support\Arr;

$matrix = Arr::crossJoin([1, 2], ['a', 'b']);

/*
    [
        [1, 'a'],
        [1, 'b'],
        [2, 'a'],
        [2, 'b'],
    ]
*/

$matrix = Arr::crossJoin([1, 2], ['a', 'b'], ['I', 'II']);

/*
    [
        [1, 'a', 'I'],
        [1, 'a', 'II'],
        [1, 'b', 'I'],
        [1, 'b', 'II'],
        [2, 'a', 'I'],
        [2, 'a', 'II'],
        [2, 'b', 'I'],
        [2, 'b', 'II'],
    ]
*/

Arr::divide 陣列返回一個二維陣列,將key 以及 value 拆成兩個陣列,如下範例

use Illuminate\Support\Arr;

[$keys, $values] = Arr::divide(['name' => 'Desk']);

// $keys: ['name']

// $values: ['Desk']

Arr::dot 函數會把多為陣列中的key 平鋪成一為陣列,新的陣列將使用「.」符號來表示階層

use Illuminate\Support\Arr;

$array = ['products' => ['desk' => ['price' => 100]]];

$flattened = Arr::dot($array);

// ['products.desk.price' => 100]

Arr::except 移除某個鍵值元素,如下範例將price刪除

use Illuminate\Support\Arr;

$array = ['name' => 'Desk', 'price' => 100];

$filtered = Arr::except($array, ['price']);

// ['name' => 'Desk']

Arr::exists 如下所示,檢查陣列中是否有 name 或 salary 鍵值的存在

use Illuminate\Support\Arr;

$array = ['name' => 'John Doe', 'age' => 17];

$exists = Arr::exists($array, 'name');

// true

$exists = Arr::exists($array, 'salary');

// false

Arr::first 返回陣列第一個元素

use Illuminate\Support\Arr;

$array = ['name' => 'John Doe', 'age' => 17];

$exists = Arr::exists($array, 'name');

// true

$exists = Arr::exists($array, 'salary');

// false

Arr::flatten 將多為陣列的值全部取出,並且平鋪成一維陣列

use Illuminate\Support\Arr;

$array = ['name' => 'John Doe', 'age' => 17];

$exists = Arr::exists($array, 'name');

// true

$exists = Arr::exists($array, 'salary');

// false

Arr::forget 傳入一個陣列以及字串,字串使用「.」的方式表階層,將陣列中的對應階層移除。

use Illuminate\Support\Arr;

$array = ['products' => ['desk' => ['price' => 100]]];

Arr::forget($array, 'products.desk');

// ['products' => []]

Arr::get 傳入一個陣列以及字串,字串使用「.」的方式表示階層,用這樣的方式方面取出對應的值以可以指令預設值。

use Illuminate\Support\Arr;

$array = ['products' => ['desk' => ['price' => 100]]];

$price = Arr::get($array, 'products.desk.price');

// 100

$discount = Arr::get($array, 'products.desk.discount', 0);

// 0

Arr::has 函數使用「.」方式表示陣列階層,確認陣列中是否有存在該階層的值,可以一比對兩個,「皆存在」才會顯示 true。

use Illuminate\Support\Arr;

$array = ['product' => ['name' => 'Desk', 'price' => 100]];

$contains = Arr::has($array, 'product.name');

// true

$contains = Arr::has($array, ['product.price', 'product.discount']);

// false

Arr::hasAny 如上檢查陣列是否有對應的鍵值存在,「任一個」存在就回傳 true

use Illuminate\Support\Arr;

$array = ['product' => ['name' => 'Desk', 'price' => 100]];

$contains = Arr::hasAny($array, 'product.name');

// true

$contains = Arr::hasAny($array, ['product.name', 'product.discount']);

// true

$contains = Arr::hasAny($array, ['category', 'product.discount']);

// false

Arr::isAssoc 判斷陣列的key 有設定自訂鍵值,如果為預設的鍵值將回傳false

use Illuminate\Support\Arr;

$isAssoc = Arr::isAssoc(['product' => ['name' => 'Desk', 'price' => 100]]);

// true

$isAssoc = Arr::isAssoc([1, 2, 3]);

// false

$isAssoc = Arr::isAssoc(["0" => 'a', "1" => 'b', "2" => 'c'])); 

// false

$isAssoc = Arr::isAssoc(["1" => 'a', "0" => 'b', "2" => 'c'])); 

// true

$isAssoc = Arr::isAssoc(["a" => 'a', "b" => 'b', "c" => 'c'])); 

// true

Arr::last 回傳滿足指定條件的最後一個元素值,如下所示200與300接大於等於150回傳最後一個符合結果300,已可指定預設值,如果沒有找到回傳預設值。

use Illuminate\Support\Arr;

$array = [100, 200, 300, 110];

$last = Arr::last($array, function ($value, $key) {
    return $value >= 150;
});

// 300

$default = 0;

$last = Arr::last($array, function ($value, $key, $default) {
    return $value >= 301;
});

// 0

Arr::only 處理陣列是如果只要某幾個元素,可以一個陣列,並且帶入需要的key值即可得到只有這幾個結果的陣列

use Illuminate\Support\Arr;

$array = ['name' => 'Desk', 'price' => 100, 'orders' => 10];

$slice = Arr::only($array, ['name', 'price']);

// ['name' => 'Desk', 'price' => 100]

Arr::pluck 這個Victor我還蠻常使用的,可以在複雜的階層陣列中,找出某個位置的值,如下找出developer底下的name的key值,回傳全部的陣列。

use Illuminate\Support\Arr;

$array = [
    ['developer' => ['id' => 1, 'name' => 'Taylor']],
    ['developer' => ['id' => 2, 'name' => 'Abigail']],
];

$names = Arr::pluck($array, 'developer.name');

// ['Taylor', 'Abigail']

也可以如下範例所示將developer的id設定對應的key值。

$names = Arr::pluck($array, 'developer.name', 'developer.id');

// [1 => 'Taylor', 2 => 'Abigail']

Arr::prepend 元素存入陣列的第一個位置

use Illuminate\Support\Arr;

$array = ['one', 'two', 'three', 'four'];

$array = Arr::prepend($array, 'zero');

// ['zero', 'one', 'two', 'three', 'four']

亦可指定鍵值並插入陣列的第一個位置

use Illuminate\Support\Arr;

$array = ['price' => 100];

$array = Arr::prepend($array, 'Desk', 'name');

// ['name' => 'Desk', 'price' => 100]

Arr::pull 取得需要的元素,並刪除元陣列的該元素,如下所示,將key 等於name回傳,並將陣列內的name元素刪除。

use Illuminate\Support\Arr;

$array = ['name' => 'Desk', 'price' => 100];

$name = Arr::pull($array, 'name');

// $name: Desk

// $array: ['price' => 100]

$value = Arr::pull($array, $key, $default);  // 可以設定不存在時,返回預設值,原陣列不改變

Arr::query 將陣列的內容,轉為查詢的字串,就是網址後面常常看到的query。

use Illuminate\Support\Arr;

$array = ['name' => 'Taylor', 'order' => ['column' => 'created_at', 'direction' => 'desc']];

Arr::query($array);

// name=Taylor&order[column]=created_at&order[direction]=desc

Arr::random 隨意取出陣列中的一個值

use Illuminate\Support\Arr;

$array = [1, 2, 3, 4, 5];

$random = Arr::random($array);

// 4 - (retrieved randomly)

Arr::set 傳入三個參數,預計修改的陣列、字串、值,可以在陣列中,依照中間傳入的字串,格式使用「.」的方式再多維陣列中加入元素。

use Illuminate\Support\Arr;

$array = ['products' => ['desk' => ['price' => 100]]];

Arr::set($array, 'products.desk.price', 200);

// ['products' => ['desk' => ['price' => 200]]]

Arr::shuffle 隨機排序陣列內的元素

use Illuminate\Support\Arr;

$array = Arr::shuffle([1, 2, 3, 4, 5]);

// [3, 2, 5, 1, 4] - (generated randomly)

Arr::sort 陣列正序排序

use Illuminate\Support\Arr;

$array = ['Desk', 'Table', 'Chair'];

$sorted = Arr::sort($array);

// ['Chair', 'Desk', 'Table']

亦可以指定使用某個key做排序。

use Illuminate\Support\Arr;

$array = [
    ['name' => 'Desk'],
    ['name' => 'Table'],
    ['name' => 'Chair'],
];

$sorted = array_values(Arr::sort($array, function ($value) {
    return $value['name'];
}));

/*
    [
        ['name' => 'Chair'],
        ['name' => 'Desk'],
        ['name' => 'Table'],
    ]
*/

Arr::sortRecursive 有點不太知道用意,稍後再補~

use Illuminate\Support\Arr;

$array = [
    ['Roman', 'Taylor', 'Li'],
    ['PHP', 'Ruby', 'JavaScript'],
    ['one' => 1, 'two' => 2, 'three' => 3],
];

$sorted = Arr::sortRecursive($array);

/*
    [
        ['JavaScript', 'PHP', 'Ruby'],
        ['one' => 1, 'three' => 3, 'two' => 2],
        ['Li', 'Roman', 'Taylor'],
    ]
*/

Arr::where 過濾陣列,寫入特定過濾條件過濾

use Illuminate\Support\Arr;

$array = [100, '200', 300, '400', 500];

$filtered = Arr::where($array, function ($value, $key) {
    return is_string($value);
});

// [1 => '200', 3 => '400']

Arr::wrap 將值轉為陣列,如果原本已經是陣列將不會有任何變化。

use Illuminate\Support\Arr;

$string = 'Laravel';

$array = Arr::wrap($string);

// ['Laravel']

如果給定的值為 null

use Illuminate\Support\Arr;

$nothing = null;

$array = Arr::wrap($nothing);

// []

data_fill 如果有對應的key值,將元素加入

$data = ['products' => ['desk' => ['price' => 100]]];

data_fill($data, 'products.desk.price', 200);

// ['products' => ['desk' => ['price' => 100]]]

data_fill($data, 'products.desk.discount', 10);

// ['products' => ['desk' => ['price' => 100, 'discount' => 10]]]

亦可使用 「*」 如下所示,將子陣列缺少 products 下一層全部的子陣列,如果缺少price並設定值200,已有的陣列則不改變。

$data = [
    'products' => [
        ['name' => 'Desk 1', 'price' => 100],
        ['name' => 'Desk 2'],
    ],
];

data_fill($data, 'products.*.price', 200);

/*
    [
        'products' => [
            ['name' => 'Desk 1', 'price' => 100],
            ['name' => 'Desk 2', 'price' => 200],
        ],
    ]
*/

data_get


data_set 函數使用「.」符號從多維陣列或物件中根據指定鍵檢索回傳值,亦可以給予預設值,在未找到的情況下回傳預設值。

$data = ['products' => ['desk' => ['price' => 100]]];

$price = data_get($data, 'products.desk.price');

// 100

$discount = data_get($data, 'products.desk.discount', 0);

// 0

亦可以在還數中使用 「*」通配符找尋所有匹配的值

$data = [
    'product-one' => ['name' => 'Desk 1', 'price' => 100],
    'product-two' => ['name' => 'Desk 2', 'price' => 150],
];

data_get($data, '*.name');

// ['Desk 1', 'Desk 2'];

head 返回第一個值

$array = [100, 200, 300];

$first = head($array);

// 100

last 返回最後一個值

$array = [100, 200, 300];

$last = last($array);

// 300

以上就是Laravel操作陣列的函數,後面幾種函數有些與Arr類別相同,差別在於可以不用建立Arr類別的實體,以上提供給讀者參考,Victor使用自己的方式些一遍主要是增加我的印象,最完整的請參考Laravel 官方文件或框架原始碼 Arr類別。

Laravel Queue – 失敗任務處理

版本

Laravel 8


config/queue.php 陣列中 failed 區塊,可以設定失敗任務的連結設定。

'failed' => [
    'driver' => env('QUEUE_FAILED_DRIVER', 'database'),
    'database' => env('DB_CONNECTION', 'mysql'),
    'table' => 'failed_jobs',
],

監聽任務時如果沒有指定任務失敗的次數,任務將會一直嘗試例請在 JOB handle 函數中增加以下程式碼

public function handle()
{
    // 領取任務後的處理程式
}

當執行的時候,將會一直不斷的嘗試執行不會停止,如果指定 --tries 次數,任務會在執行指定的次數之後刪除任務並將任務放置到失敗的任務 failed_job 資料表中,等待確認問題點後,再讓 job 重新執行,確認沒問題後可以重新執行失敗 job 的指令如下,或者可以用 crontab 定時執行。

$ php artisan queue:retry all

這下好了,如果使用者收不到應該收到的信件或其他資訊怎麼辦,我們必續嘗試監聽失敗,在失敗時通知我們立即處理,有兩種方法。

閱讀更多

2021應徵紀錄

目前還在面試中,先趕快紀錄一下,以免忘記

彼利數位資訊股份有限公司

自我介紹

照實回答

技術面

紀錄一下去這邊公司面試的過程,先記下技術方面

最複雜的流程是?

empty is_null is_ set 差別

突然被這樣問我只能印象回答,這裡附上我一年前寫的文章

function 裡面要傳入參數 用什麼

use

如果要變動外面的參數希望要怎麼在變數內改

global

失敗的Queue 怎麼辦

面試時我無法回答。

因為我還真的沒有涉略 Queue 太久,加上因為是伺服器不常壞掉,所以我擺明說不會,立馬來補一下失敗以後做哪些事情比較好。

物件導向設計原則

什麼是依賴注入設計模式?

我是解釋如果 A、B兩個類別,如果A需要使用才new B 產生實體物件,這時可以說A類別沒有B不能操作,因此使用依賴注入,在A類別產生時,帶入B實體物件。

我發現我英文說的能力真的很爛 因為不知道construct 建構子怎麼唸

怎麼實作

我舉Controller Service 的舉例

Laravel 相關

wherehas有用過嗎

有,判斷關聯資料是否存在,存在的話才顯示資料

with 有用過嗎

laravel collection array 跟 php array 差別?

只有用過不太清楚兩個方法差異,一個是Laravel 寫好的類別collection

Restmodel 有點不知道為什麼他們要這樣寫

Laravel Model 可以說明一下 fillable 的差別嗎?

php artisan 指令篇

php artisan config:clear

清除建立 config 資聊夾快取

php artisan cache:clear 他會清除全部嗎?

我回答他會去清除 快取資料夾,storage/framework/cache 好像誤會面試官的意思,他補一句會清掉config,我說會,這是錯誤的喔!

php artisan optimize:clear

git相關

有用過 git rebase 嗎?

聽到那一霎那,我完全忘記這個,現在紀錄查看到字才想起來,我在寫我的範例的時候一直用到這個,但我跟面試官說我只用過 rest。

git revert ?

沒有

git stash ?

有,但後來我都使用 PHPStorm 的一個建立清單功能 (下次再來補充這部分)

git cherry pick?

有,使用GUI圖形化介面用而已,可以選自己想要的個別程式碼併入。

但說認真以上幾個指令我都很少用,趕快把它加入筆記。

phpunit 系列

用過factory?

有用過 factory 產生假資料當什麼情況…我在找一下到時候再補上

phpunit mock 有沒有用過

如何讓phpunit 進入登入狀態

我使用的是Passport Laravel套件創建一個使用者,

給我看他們公司的一些程式碼並解釋給面試官

看到什麼講什麼!

有一個地方真的還不太確定為什麼要這樣寫

https://www.php.net/manual/en/function.method-exists.php

還有一個 filter 串連的物件導向是怎麼做的?面試官問我怎麼可以不用傳參數進去就可以用?我真的還是找不到

AWS

有用過哪一種 EC2 IAM RDS S3 忘記說SQS、還有 Amazon API Gateway

有沒有用過套件

Laravel 匯出匯入資料

為什麼離職?

自己生涯規劃,想休息一下 (我跟我朋友講,他說應該跟面試官說我去徒步環島,寫書…,面試官真的會想要聽這個嗎?)

因為我有稍微研究一下公司的部分內容所以對我有興趣的提問!非常感謝面試官的很願因跟我分享!不在這打出來,者種面試久久來一次也不錯。

整個過程我覺得還不錯,難度我覺得剛好有到我的程度,有些會有些不會

現在思考一下有什麼可以改進

英文能力至少會說專有名詞,可能會更專業一點的感覺

介面(Interface)

先了解一下什麼是抽象、什麼是具象。

抽象

抽離具體的形象, 只留下可辨別的特徵,抽象畫抽象畫,我跟你說抽象畫,你只會知道他是一幅畫,但抽象畫的內容…恩…可能不好離解。

具象

我跟你說我們帥,到底有多帥,有點抽象,可以具體一點嗎,濃眉大眼(假設是目前大多數人定義的帥),那就叫做具象,你可以把上聯想出來他的實體的樣子。

舉這個例子不好認識我的人,會自動將我這個詞,聯想到我Victor 本來,正經一點,可以這麼說,我剛剛看到一個女生很漂亮!一定無法想像,只有說一個女生,你只能聯想到他有五官、手腳… 沒有法想像他具體的樣子。

介面很抽象,你可以將眼睛、鼻子、嘴巴、眉毛抽離出來,「定義」這些東西,我只跟你說眉毛,但到底是什麼眉毛,不知道只是一個定義,這就是介面的存在,再利用Class 來實作他的眉毛要細、粗、濃眉…

PHP 的介面使用方式

待補

封裝、繼承、多型的三大特性

我想開一間咖啡廳,所以我就用他來舉個例子,但還是必須要先了解 OOP 物件導向。

請先知道我的咖啡廳有三種不同的角色 咖啡師、服務生、會計。

繼承

一開始可以先當作父類別可以擁有子類別的功能,我覺得比較好記,可以達到重用程式碼的好處,但事實上我認為是一種行為的擴充。

假設我訂定一個一般員工必要的條件,這個已有的技能去做擴充,例如人手若不足必須要有點餐的方法,可以使用繼成,因此覺得可以把它想像成大範圍的統稱會比較適合。

封裝

我是這間咖啡廳的老闆,我今天視察咖啡廳,但每個員工都跟我說:如何煮咖啡、如何選豆子、咖啡豆口味是什麼風味、怎麼烘焙咖啡豆、操作Pos 機、如何有效率打掃餐桌、如何應付客人、如何結帳、帳目報表、如何報稅… 除此之外還有很多。

突然來這麼多訊息,對我老闆而言,並不是必須,跟咖啡斯說,我要一杯美式偏酸一點的風味,過程中怎麼做的我不用了解,說出我想要的關鍵字,即可拿到一杯咖啡豆品種風味偏酸的咖啡。

這就是封裝,假設你覆轍咖啡師的類別開發,對其他人來說,使用你這個類別的角度,不需要的就不要設定public 權限,讓操作的人眼花撩亂。

多型

只要是同類,但做不同的事情,我是老闆有咖啡師、服務生、會計師… 他們都是我的員工,員工都需要做事定義一個做事的方法,其他員工工作的細節,在各至繼承這個定義去實作。

  • 咖啡師的工作:煮咖啡
  • 服務生的工作:服務客人
  • 會計師的工作:算錢