Josh Lockhart
我分享一些生涯中比程式碼更重要的經驗給你 希望有幫助
我寫了一本書 Modern PHP
Slim Framework ; 微框架
可以打造小型 API、service
其它框架例如 Symfony, Codeigniter
Ruby, Sinatra
Slim v3 可以更容易與 ZendFramework 整合
PHP The Right Way 你應該看看
有許多社群分享的資訊
關於 Testing 你可以關注像是 PHPUnit 之父的分享
為什麼要聽我分享?
2000 年開始學 PHP
2003 Freelance
2007 join NMC
2011 Slim Framework
Today Author & Team Leader
但今天我不太談 PHP
你可以參考這些我的著作:Modern PHP、PHP The Right Way
我要談談關於你 - 開發者
你有經驗、書籍、時間
我常聽到的問題是:我如何成為資深開發者?
知識? 也許?
也許是年齡?
也許是職稱頭銜?
我不知道
但我可以分享一些幫助我成為資深開發者的課題
一、PHP is only a tool - 只是個工具
二、Work smart, not hard
三、People are your best asset - 你的團隊是你最好的資產
四、Keept it simple -
五、Share your knowledge - 分享你的知識
Do not devote yourself to a single PHP framework - 不要只投注心力在單一特定框架
One size dot NOT fit all
單一規模的框架無法應付所有需求
如果你只想要打造一個小東西,可以試試看 Slim 這類微框架
different tool to different jobs
選對的工具應用於對的工作
Macro frameworks
Micro frameworks
Indiviual components
PHP may not be the best language for the job
Bash may be easier and faster for repetitive or async tasks
PHP can run one the CLI with STDIN, STDOUT, STDERR
沒有 UI 的 CMS 讓你能容易打造很棒的 CRUD 管理後台
Drupal, 匯出 JSON 給 前端網站運用
I DO NOT work because I love PHP
I work to make money so I can
9am - 5pm
Maintain a work / life balance
i dont't always have the answer. Many in this audience know more than me
Humility is an important trait
I don't know is a valid answer
as a senior developer, your job is to facilty …
適當的把任務委派給你的團隊成員
take advantage of your team's specialization. regardless of seniority or job title.
Improve efficiency by using team's comparative adventage
Give new/junior team members investment in the project
避免職業倦怠,要相信你的團隊
Give Praise
A little bit goes a LONG way!
Do not punish mistakes
別懲罰錯誤
Anticipate them and learn from them
它們犯錯是預期的,從中學習較重要
鼓勵良好的 coding 實踐
Lead by example
以身作則給好的範例
PSR 1 and PSR2
follow coding style
Gradually increase enforcement with CI tools
weekly team demos
It is NOT obvious (Obviously)
Welcome feedback
There is always room for improvement
Write simple code
Easy to understand and debug
choosing tool
use boring & reliable for client projects
use new & shiny for internal projects
Start simple
Do not abstract, optimize, or scale until they are needed
別過早抽象化、最佳化或延展,直到它們真的需要
Do you need design patterns?
Developement at NMC
git commit
git push origin master
cap staging deploy
幫助你的同事進步 indivi..
Nomadphp twitter
You will never find the perfect Sr. Dev for your proj. You can however, hire a Jr and train them to be the perfect Sr. Dev. :)
https://twitter.com/nomadphp/status/783720937464197120
twitter @codeguy
Do you need to extract …
sed -n '101p;203p;300p' < input > output
Do you need to extract certain lines from a text file? To get lines 101, 203, adn 300:
sed -n '101p;203p;300p' < input.csv > output.csv
https://twitter.com/codeguy/status/785476315570905089
So. remember!
Sebastian Bergmann
德國人
38 歲
26 年前開始寫程式
跟其他兩人一起開公司 thePHP.cc
最近寫了一本書 PHP7explained.com € 39.00 (~$1300 TWD)
DISCOUNT: PHPCONF2016
PHPUnit 3.7 於 2012/09 釋出
第一個可以被 Composer 安裝的版本
PHPUnit 4 於 2014/03 釋出
第一個不再提供 PEAR 套件的版本
PHPUNIT 釋出流程
PHPUnit 4.8 support in PHP 5.3+
PHPUnit 4.8 不支援 PHP7
PHPUnit 5 於 2015/10 釋出
PHP 7 變革快速理解
perf stat php7-binary ../phpunit blahblahba
PHPUnit 有 450k 個測試案例、710k 個斷言, no I/o - 無檔案讀寫
速度改良顯著
UNIFORM VARIABLE SYNTAX 差異對照: PHP 5 v.s PHP 7
$$foo['bar']['baz'] blah blah blah
請不要這樣寫 (雙錢號語法)
如果看某段code超過10秒鐘無法理解,代表你該刪除它。
略
PHP 7 被棄用的功能
PHP 7 的 type-hint 支援 scalar (string, int, float, etc.)
PHP 7 嚴格模式
declare(strict_types=1);
啟用後,傳入的 scalar 如果型別不對就會噴 FATAL ERROR
PHP 7 return type declaration
可標明function return的資料型態
PHP 7 Null coalescing operator
example:
$username = $_GET['user'] ?? 'nobody';
與下面是一樣的
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
即有$_GET['user']的話就取值,沒有就回傳??後面的值。
PHP 5: 97.2%
PHP 7: 1.7%
數據來源:https://w3techs.com/technologies/details/pl-php/all/all
PHPUnit 5.1 於 2015/12 釋出
PHPUnit 5.2 於 2016/02 釋出
PHPUnit 5.2: 測試例外
PHPUnit\Framework\TestCase is now an alias for
PHPUnit_Framework_TestCase
$this->createMock(Foo::class);
等效於以前的
$this->getMockBuilder(Foo::class)
->disable()
...
..
->getMock()
PHPUnit5.5 2016/08 release
partialMock
PHPUnit5.6 2016/10 release
fucntion m(): void
{
return 'foo';
}
FATAL ERROR!
function f (?int $x)
{
}
f(null) // ok
f(1) // ok
f() // 爆炸
return type也可以為nullable type,ex:
function answer(): ?int {
return null; //ok
}
function answer(): ?int {
return 42; // ok
}
function answer(): ?int {
return new stdclass(); // error
}
try {
...
} catch (FooExcepton|BarException $e) {
...
}
PHP 7.1: async signal 處理
<?php
pcntl_signal(
SIGALRM,
function () { ...},
true
);
##PHPUnit 5.7 的支援只到 2018/02
Karl
flyingV 擔任技術長
flyingV 為台灣最大群眾募資平台
Envoyer為Laravel官方做deployment用的。
flingV –> 早期用Java的play framework做,後來打掉重練,變成Laravel
vEvent –> 建立活動,讓大家參加活動的服務
vDeomocracy –> 為社運做的網站,學運之後沒在維護,沒再上架。
vSHOP –> 購物平台,已收掉
vStory –> 用wordpress做,最大問題,他的資料庫很雜亂,要直接從資料庫取資料不容易。工具: Corcel
以前伺服器架構主要在AWS上面,很貴。
搬離AWS,目前伺服器架構在linode上,原因: 便宜
用Laravel的seeder來搬資料庫。
使用chunk匯入可以避免記憶體炸掉
Capistrano用ruby寫的
自動化從Jenkins移到GitLab的CI上,原因: 覺得Jenkins設定複雜。
用rollbar來做error monitoring
Matryoshka是一個可以幫view logic提供Russian-Doll caching的laravel的package
flyingV 幾乎所有的專案都是Laravel
用php7,效能好很多
從memcache轉到redis上
Legacy code:沒有測試的程式
目標:為重構想一個方法
用健康的心態面對問題
參考 Nginx Blog
Client -> legacy code
類似 Proxy pattern
Miles: 會覺得是 Proxy Pattern 是因為 Router 預期的行為 (interface),會跟 Legacy code 的行為一樣,我個人覺得這跟 Proxy Pattern 的 UML 比較像
參考 The Twelve-Factor App: 1. Codebase
Client -> Proxy -> Legacy Code
Test -> -> Refactoring
1.Test -> Proxy -> Legacy Code
2.Test -> Proxy -> Refactoring
3.Client -> Proxy -> Refactoring
4.remove Legacy Code, Proxy
利用 Slim routing 載入 legacy code (require SomeOldFile.php)
ZF (或其他有 entrypoint 的 framework ) 也可以這樣使用
範例
// 我是驗收測試人員
$I = new AcceptanceTester($scenario);
// 我想要測管理頁面順便測登入功能
$I->wantTo('test admin page and test login');
// 我打開了管理頁面
$I->amOnPage('/admin');
// 我看到了 Password 的字
$I->see('Password');
// 我把我的密碼填入 input field
$I->fillField('password', '0000');
// 我按下登入
$I->click('登入');
// 我看到登出的字
$I->see('Logout');
若有測 JS 的需求就改搭配 Selenium (預設是 PhpBrowser)
Miles: 我對前端不熟,我記得 JS 會產生 DOM ,這些是 PHPBrowser 測不到的,所以需要有能 run JS 的 driver 如 Selenium
實作方式 :
usage 1
$toggle = false;
define('ENABLE_REFACTORING', $toggle);
ENABLE_REFACTORING and $app->get( routing ) { ... }
usage 2
$toggle = getenv('enable_refactoring');
// print something
true AND print('true line');
// do nothing
false AND print('true line');
即早整合
即早發現與治療
很久才 merge 一次的話容易採到多個問題 不容易追到根源
Miles: 我後來忘了說「用 feature toggle 的好處?」,我覺得它可以強迫提早整合。當然這是雙面刃,但 feature toggle 跟 Git 的用法都很自由,大家都可以針對自己的需求去做調整,只是要記得 CI 「即早發現即早治療」的概念是不變的。
導入後可以用 Composer,例如用 monolog 、等等套件
PSR 4 autoloading, etc.
導入後開始寫測試,實踐 CI
快快樂樂 重構
平平安安 上線
thanks
閃亮亮
KKbox 工程師
如何把PHP寫得跟SQL一樣簡潔好懂
我不想知道我不需要的事情,在PHP上使用OOP實作封裝+抽象化
物件的基礎:資料 + 行為 -> 職責
利用closure來封裝
可多多利用Laravel的map, filter,使得程式碼便簡潔(也可使用php的array_map, array_filter)
使用Collection和OOP-Fluent style
composer require illuminate/support
大澤木小鐵
KKbox工程師
網頁即時資訊的定義: 系統資料更新時,不用重整頁面就可以獲得更新的資料
###即時資訊的做法
它戳你
你戳它
它戳你
一分鐘或數秒鐘去戳api(當然要帶api token)
用Laravel的queue和jobs
Queue driver使用redis
你戳它
以google calendar為例
如何將資料傳給客戶?
Laravel本身不支援pub/sub機制
有提供Pusher可使用,但是要$$$$
有什麼不要錢的?
Redis pub/sub server + laravel echo server
Laravel-echo-server適用node寫的套件,故要用npm安裝
laravel-echo-server init
會要你輸入server的host名稱
port預設6001,但是可以改
會問你要用什麼db
以燃盡圖舉例如何在有限時間內講完投影片
http://blog.jobbole.com/45756/
走了兩小時後…
變化
速率
時程
延至下下週日
走了十二小時後
變化
無法正常休息
第二天睡過頭
工時
今天只能先走10小時
明天再走14小時
承諾
還在控制範圍內
不用改期
士氣
無奈
幾個小時候
變化
腳鈕到
須花費45分鐘繞到村莊治療
速率 (24 英哩 x)
今天只走六英哩
承諾
還是不必說 趕路要緊
士氣狀態
逃避現實
第三天
變化
風路、此路不通
速率 (24 x)
找路繞路 迷路兩次
大半天只前進一英哩
工時
決定不睡覺 走到大半夜
承諾
不再打電話
士氣
燃燒生命
第四天
變化
過度加班的返效果
速率 (24 英哩 x)
完全無法行動
今天進度為 0
第五天重新檢視進度
速率
四天只走40英哩
一天只有10英哩
範圍 (400英哩)
至少 600 英哩
時程
原本的時程太天真
保守要七十天
提議
只要一天16小時 舊可補進度
第六天
士氣
沉沒
最後團隊成員就會跳槽
實務上怎麼幹?
你會灌水 PM 就會砍你
所有的預估都是在畫芭樂票
預估就是用你個人的經驗去猜
預估跟推估是不一樣的
推估是用一些科學根據的方法去推算
預估通常都找資深的來判斷
其它的層級就跟著乘
拳王泰森
每個人都有一個計畫 直到他被貓了一全就沒用
今天要講兩個重點
第一個重點
相對估算 Dog point
第二個重點
估算模型 (範圍 = 速度 x 時間)
好的估算方式:SPA
三大特徵
When: 決定誰做之前就估算
Who: 做事的人一起估
Team - 8.0 / 7.5 / 5.5 / 10.0
PM
大家一起估就有開會成本、溝通成本
所以估算方法要簡單
雞跟豬說 我們來賣火腿蛋三明治吧
雞只要生蛋 豬卻要割肉 豬當然不要啊!
會得到很多答案 不大 30cm 很小 28.5cm
估算牠是不容易的
換個問法
哪一支狗比較大?
吉娃娃 v.s. 哈士奇
一旦兩隻放一起比你要知道哪個比較大是簡單的
這個基本概念就叫做 相關估算
我不管你有多大 我只管他是他的幾倍大
大家想折一架紙飛機你要多久時間做?
大家通常不會超過 30 分鐘 合理吧?
可是一架戰鬥機你要做多久?
通常誤差就會很大 而且不知道從何估起
哪一個估算你比較有信心
老闆問,怎麼答?
1分鐘 ?兩年?
為什麼?
因為兩年後你還會不會在 不知道!
正常人都覺得一分鐘比較準
你看到了什麼?
怎麼減少浪費?
挪資源
由左至右 夠簡單吧?
比較大的狗放右邊
每個人輪流 pm 除外 一次移動一張狗的圖片
吉娃娃在最左邊
右邊得狗要比左邊得大
可挪動既存得狗圖片 右邊仍要比較大
該狗無法比較時 請放到最右邊
覺得不需要調整時 可以 pass
四個人 peter 是 PO
Peter 先把吉娃娃放上來
Alice 問 這一支臘腸狗幾歲?
回:三歲成犬
我覺得臘腸狗比吉娃娃大
Bob 我覺得西施犬比臘腸狗大
cindy: 是一支還兩隻? 是兩隻大單
cindy: 光一支就比其他的大了
David 西施只是毛長 應該比臘腸小
ok 每個人都有權力去決定順序
主持人很重要 有可能每個人吵不停
當今天每個人都 ALL PASS 就進入下一階段
1 2 5 8 13
吉娃娃為 1
按照狗大小比例 每個人放一張撲克牌
可以挪動既有的撲克牌
0 0.5 1 2 3 5 8 13 20 40 100 ?
實際估算 我們會抓出來團隊
假設四個人一起估 我覺得這個任務是吉娃娃三倍大 他覺得五倍 他覺得五倍 他覺得十三
最小的是三 最大的是十三
兩者差兩倍以上 合理嘛 OK
所以請兩個人說出為什麼會差兩倍以上
例如 我比較菜 他比較熟 這是一種
另外一種是 資訊落差 我知道什麼細節 但他不知道
團隊在討論過程中會發掘很多你不知道得東西或他不知道得東西
例如有個 open source project, plugin 所以他估算的時間短
不管誰做 我們都獲得資訊
你的資訊才會透通
也有可能是這些人都很天真
例如申請憑證 機器
所以我的假設是這樣 才會估這麼大
他可能把 code review, automate testing 都算進去了 但其它人沒有
就我的經驗沒有第四輪以上的
可是我希望每個人的想法都被尊重
e.g. 我是菜鳥耶 所以我估 13
不需要因為別人來改變
就算倒楣估算最多的你最後真的領到任務 你也知道要去找誰求助 例如估算最短的人
一支大單應該有二十被了 兩隻就是四十被
假設 一要花 0.5 小時 二大概就是一小時 … 以此類推
把全部的狗加完 就得出推估時間
這個叫推估
重點永遠不是放在準不準
相關估算 recap
SPA 三特徵
估算兩準則
定義吉娃娃是什麼
一場比賽有四節
一節12分鐘
每節休息5分鐘
60秒暫停
中場20分鐘
…
一開始沒經驗 大家達成共識 一天只估四小時就好
工程師覺得開心 PM 覺得有點賭懶 老闆不開心
這件事情發生在最一開始的時候 大家要磨和
有插件
要研究很多東西
要溝通
原本估要做 200 story point
結果兩週後只做了 105 個 story point 沒有人說得出為什麼
影響評估
範圍 速率 時程 三循環
一旦你推 PM 去死,PM 就讓你去死
因為你沒有提供足夠的資訊給 PM 他就只能非 0 即 1 他就只能 fit 老闆的需求
PM 有足夠的資訊才能保護 team
爸 我想當工程師
喔 那你先做100人份的餅乾
為什麼?我一個人怎麼做?
這應該很簡單吧 二十分鐘要搞定
時間也太短了吧!
還有不要餅乾了 改蛋糕 你還剩下5分鐘
要求也變化太多了吧!
兒子啊 我看妳不是當工程師的料
需求異動
作法異動
人員異動
軟體業的特色 你沒有辦法阻止這個事情發生
實際成果 2015 Q1 Q2
六個月完成八個月的專案
插件兩個月專案
其中一個專案提前一個月上線
其它專案準時上線
不加班
code coverage > 75%
時時 review 調整決策
持續改善
不是廢話嘛? 我們來這邊聽一小時
範圍 = 180 pts
怎麼來?我們用 t-shit size 去估
轉換成 story points
因為 pm/po 根本就不懂怎麼做 所以他估不出來
所以他需要簡單方式 讓他自己比較出來
分成 S L M 三種大小
讓團隊挑 S = 10 個 pts 之類 的數字基準設定
經過試驗後 blabhalh
時程 = 3 sprints
不是 run 了敏捷就沒有時程這件事
假設 1 sprint = 2 week
期望速率 = 60
共 180 pts
斜率 180 / 3 = 60
你一定要有實際數字 不是算芭樂票
用上次完成的數字參考來算
你的資料越多 他會越來越準
假設實際速率=50
代表你要延後到 6/24 改 due date
實際要花 3.6 sprints
預估時程 = 3 sprints
推估 = 3.6
當你希望時程不變 你只能修正範圍
團隊的開發能量就是那樣 不會一夜加速
經過 Spkie 試驗後 L 為 40 ,M 為 20, S 為 10
PM 說不行 這個某功能很重要 一定要在某時間點內做完
這時候他就有足夠資訊來做優先權
如果沒有足夠資訊他就會跟你說 都很重要 都要在時間內做完
e.g. 出貨跑檔可以先做嘛? 可以 多給我兩天 再砍其它的
假設你是 po / team lead
有個案子需求你們要花多少時間
只有你講得出來 就是妳做得不錯
老闆期望佑可以插件佑不影響時程
要快要便宜要好是不可能的
怎麼辦呢? 加班
這張圖講技術債 會變怎麼辦
加快斜率就可以 那塊面積就是技術債
如果沒清掉 未來加班就會更多
開快車分兩種
拼得過 快兩分鐘回家 拼不過 晚七天回家
個人經驗 治標- 檢視 優先權
有些東西真的沒那麼重要
一開始估就是 7-11跟全家都要做
哪個重要?都很重要!
預計做六個月
有個計畫插件
所以決定先做全家 延後 7-11 優先權
六月做完之後 7-11沒做
因為在其它專案的優先權比較之下 他就沒那麼重要了
所謂的優先權會不斷改變的 他會隨著時間空間變化
如果你一開始不管他就先做 他就是浪費
所以為什麼軟體有很多功能都沒啥用
治標 - 調整作法
鋼鐵人例子
你要評估 must have 是什麼
只有挺你的 PO 讓他可以交差 才有談判籌碼
治標 - 有計劃的欠債
覺得不能有技術債 - 初階
專業的工程人員是有計畫的欠債 還得掉
經驗是拆兩段 must have, nice have
專業的價值在於有計劃性的欠債
治標 - MVP
做車子
NOT LIKE THIS (X)
先做輪子 … blah
LIKE THIS (O)
先做滑板車 再做腳踏車 .. 機車 汽車
對老闆來講商業價值完全不一樣
三天就拿到一版可以 work 的
很重要的概念, 十三天的專案 第五天可以第一版就可以賺錢
如果第五天發現做了一個垃圾 後面就不用做了
所以啊 我還沒有做到這台車子過!
是因為我有更多的前面 (滑板車/腳踏車) 要做!
治標 - 提昇硬體效能與人員士氣
與其找顧問還不如升級工程師的硬碟為 SSD (舉例)
治本 - 持續改善
循環是 持續 review 設 check point
持續的取得 feedback
持續的改善
比較空泛一點
最後做個 demo
我可以再五分鐘吧?
T-shirt size 的平均 story points
持續更新: 加權平均數
PBI 推估範圍
交給我這個團隊做大概要多久 多少時間
就算不準 , PO 也比較好跟老闆吵
平均 Velocity
平均 sprint 產出
79
123
98
…
第一條 - 延長時程
第二條 - 縮減範圍
如果老闆還是要走第三條 調整類型 - 增加生產力
記得跟他說加人力是沒有用的 記得孕婦的故事吧
介紹 excel 表格
示範被要求一定要完成某幾個功能 需要多加幾天
速率 -> 持續改善
優先權 MVP
範圍 時程
很多東西都是可以調整的
範圍最糟糕的是 PO 無法取捨 或是他只是個 302 PM
老闆講什麼就 喂 … blahbalh ..
最糟糕的就是加班
你要他加班 他隔天就請假了 因為他壞掉了 人不是機器
結論
依據變化 調整決策
艾森豪的名言:“Planning is everything. Plans are nothing!”
我們通常不用改變這個字眼
我們在意的只有改善
改善 > 改變
演進 > 革命
做好 > 做完
自動 > 手動
溝通 > 文件
團隊 > 個人
成效 > 規範
補充 sprint commitment
有人預計請假
開會
生病
失戀
電腦壞掉
Q: 時程跟 MVP 可以多講一些嘛?
A: 時程通常都是最難僑的
因為有可能是對外記者會 發表會等
那怕只是 workaound 讓他看起來是正常的
區分哪些東西是 demo 過程中一定用的到的
你會聽到敏捷講到一些名詞例如延遲最佳化
還是有最佳化 MVP 不是永遠交付個爛貨
你要去橋 例如多給我三天我可以多給你什麼東西
只要到非不得已你才要以卡借卡 也就是欠技術債