擔任產品經理這三年,從無到有製作的三個產品共賣出四千多萬。而這三年,產品的改版更是達到20多個版本,並且灑在二十幾家客戶機房內。
底下分享一些實務經驗:
很多時候意見被反應到產品經理這邊,第一時間是沒有辦法立刻決定要怎麼做,平時實在太忙,需要一個記錄軟體把所有的需求給記錄下來,像我自己是用PivotTracker平時把意見先建立到列表,等排定的時間到了再一同看全部需求,且將這段時間維運、建置、使用者到維護的反饋,來決定哪些需求要排定下來。如果沒有這種ICE BOX來收集寶貴的回饋,是一定會忘記的。
依照我產品的特性,因都在客戶端機房內所以作業環境是沒有網路,且需要人員實際到場。在這嚴苛環境中,改版需盡可能輕鬆且有標準SOP,以利現場作業能順利完成,不然損耗的是寶貴的人力資源,因此改版最重要的一點就是要讓第一線人員好做事。
在規劃上要有一套標準的升版SOP,這仰賴架構規劃與程式設計師在一開始就把這件事情納入考量,有看過一些系統於每次更新版本時要做的事情都不一樣,為一些該版本特殊的tip需做,甚至全部都是tip。當然特殊tip有時無法避免,但應該降到最低,怎麼做下一步就會說。
在工具上可採用Docker把運行環境打包其來,讓環境標準化、可管理化,可以很有效降低維護管理與執行成本。
大部分的版本應該避免讓開發人員做除了標準升版流程外的事情,但總會有幾個版本中某些變動需要手動調整,此時就需要在Readme裡獨立一個Section於更版時需要額外手動調整的事項列表,這樣做能讓現場部署人員更容易且清楚知道自己需要做哪些動作。
資料庫的變動是一件嚴肅重要的事情,確保讓程式自己handel自己需要的版本,一種做法是把每個版本的變動寫成shell,並在程式執行時確保這些shell會被執行,如圖示:
絕對避免讓維運人員要自己去操作SQL,會做一些特製Shelll,這樣風險太高了。
我做的軟體產品有個特性,就是系統都灑在客戶的機房內,隨著建置時間的不同,版本會不一治。而通常情況客戶舊版本用的好好的,是不會想配合變更版本的,所以也不能透過日常維護去變更版本,而且這樣維護成本也會過高。所以可能的升級時間點就是客戶遇到新需求需要更版的時候,而最新版的時間點可能已經過了好幾版,所以要讓維運人員好做事,就是在每次版本更新時都注意要能夠從向下相容,讓維運人員只要負責一次就升級到最新版即可,比如從v1直接升級到v8。
有些問題是已知但沒有排在該版本去解決,或是release後才發現的問題,這些都要補在Reademe裡面,如果有客戶反應有問題,維運人員去看Reademe就可以第一時間跟客戶說只要升版即可解決這個問題,或支援這個feature,這個已知問題的Section也是需要被獨立出來的。
所以綜合上述所說,每次釋出版本後READEME應該要有以下章節,重要性由高到低
一套產品系統能否成功,長期能否維護是關鍵,而如果在設計上這個產品的維護與改版難度是成指數成長,很快的就必須要放棄這個產品,因為改版的成本已經大於帶來的效益了。所以這篇文章都只是在盡力做一件事,降低長期維運成本。產品系統才能活下來。
]]>業務應用系統為什麼要導入新架構微服務與Container?這些技術具備怎樣特性去解決以往哪些較難克服的情境問題?而當我們在設計一個Container時又有什麼原則我們該考慮才能真的解決上述的情境問題呢?我們可以先把一個Container想像成機械公敵裡面的單一機器人來理解:
而微服務架構Container設計原則的另一端就可以想像成是環太平洋裡面的巨型機器人:
以上幾點,最重要的就在於沒遇過的挑戰。現在的業務應用發展非常迅速,變化的幅度也相當大,面臨的挑戰多樣化,有的可能是流量上的挑戰,有的是服務介面或流程上的多樣性調整或其他各式各樣不同應用情境下面臨的新挑戰。
而微服務架構下的Container最大優點即是容易因應變化。引用反脆弱
這本書的想法來解釋,未來的變化越來越不可預測,而因為事前的預測不可行,所以避免被未知變化打敗的策略不是變得更堅強(ex:造巨型機器人),而是變得可以因應變化(ex:透過各種容易打造,靈活改變與量產的微型機器人)
以Netflix全球線上影音播放龍頭來說,它們每日面臨的流量變化是無法預估的,服務遍及全球,所以哪個地方的網路突然不穩定也是不可預測的,但只要透過微服務架構,流量一大即可透過立即增加微服務數量來彈性因應,服務預期外下線只要讓其他服務Fail-over接手即可。
引用到金融業,為來可能與APP業者合作推出行銷方案,因活動所帶來流量的不確定性與方案的多樣性就很適合用微服務架構來因應。
所以今天不管海底冒出什麼變種怪物,都可以透過靈活快速改變迭代微型機器人的功能與增加數量來對付。
在談實作之前要先釐清,Contaienr本身不能夠決定自己容不容易快速啟動、是否具備消耗品特性、與scalable,要具備以上能力不僅Container設計時要考慮,更重要的前期階段整個微服務基礎設施架構設計上就要考慮進去。也就是說如果沒有一個良好在背後運籌帷幄自動調配的為微服務基礎設施架構,Container是沒有辦法發揮1+1>=2的效果。
打個簡單比方,前方戰線吃緊但後方的大本營卻狀況外,遲遲不開啟新機器人出去應戰那也是沒有用的。
典型的Container設計對外是透過RestAPI來提供服務,所以內部是一個Web Service,其中包含了必要的業務邏輯,啟動後會有systemd自動把服務帶起並運作,啟動後Container加入Service Discovery就可以開始處理業務請求了。
整個啟動時間以Tomcat應用來說是可以在1秒內啟動完成。而一但這個Container不再需要即可透過微服務基礎設施進行刪除來結束生命週期。
每個Container都要盡可能避免自己出現Fatal Error,也就是會出現導致服務中斷不回應的例外錯誤。systemd在這裡可以發揮適當的進程守護機制,如監控Tomcat健康狀態如發現進程掛掉自動重啟等。
而微服務基礎設施也有責任透過協調好的Health Check API或Ping去發現回應不如預期的Container,並作出適當回應機制如Fail-Over。畢竟不能夠相信有 100%1不會掛掉的Container存在。
一但發生錯誤,第一時間的錯誤復原很簡單可讓基礎設施透過Docker特性,重啟整個Container來達到恢復狀態。但這個事件必須要被Log給記錄下來。包含呼叫的Container與Image版本、呼叫的AP、時間、帶入的參數等等。在事後才能透過以上資訊來找出Root Cause並升級Container Image來防止再次發生。
Contaienr通常是會不斷迭代的
因為不同類型的Container常會以功能劃分並模組化管理,而隨著不斷迭代,基礎設施與Image版本也幾乎必定會有向下相容的議題產生,特定版本的基礎設施要搭配特定幾版以上的Image。所以長期來看版本控制就特別重要。所以導入Git與做好文件是系統能不能長期穩定提供服務與發展的重要關鍵。
而如果基礎設施版本與Image版本之間有Dependence的關係一定要特別註明。
Container能夠快速重起的特性帶來一個重要議題:重啟後Container內的資料是會不見的。所以如果Container內的資料是很重要的,如資料庫檔案等請參考Docker Volume把重要的資料掛載一個鏡像在Host。這樣一但程式有問題,重啟後資料還在,才可以繼續維持服務。
這部分典型應用如把MySQL做成Container,這時候MySQL版本進行升級只要替換Image版本,就可以在資料保存不丟失的狀態下升級MySQL。
一開始從談論導入微服務架構與Container對業務的好處是什麼開始,因為IT能夠長期有效並從容迅速的去解決未來可能面臨的各種業務需求問題,才能最大化IT價值。接著從此架構的特性來談為甚麼能解決上述問題,最後再跑過一次整個細部技術實作上會遇到的議題。
實務上除了微服務基礎設施一定要自己全部掌握與了解,其實就Container單一服務只要考慮好:
上述幾點考慮好其實就單個特定需求的Container服務來說是可以透過外包的方式來實作也沒有問題的。
可以發現的是Container設計起來相對於微服務基礎設施簡單,需要考慮的議題除了版本控管與Scale之外都偏向於單點技術的實作。而這也是符合避免打造一台巨型機器人的原則。
附錄裡介紹Netflix在全球有上萬Container去服務數百萬觀眾,而這只需要10多個維運工程師,令人印象深刻。
]]>想像一下來到一個陌生國度,你既沒有地圖也不會說當地語言,你不知道要買生活用品要去哪家店,你也不知道餓了哪裡有餐廳可以吃飯,什麼事情也不能做。
沒錯,一個沒有Service Discovery機制的微服務架構就如上面的情境,什麼事情都做不了,可以說Service Discovery機制是談微服務架構必備的基礎設施也不為過。
簡而言之,一個微服務架構底下可能有數十到數萬個微服務,彼此之間是解耦合的,不會留存各自的組態資訊,所以需要一個熟門熟路的總機,要找誰、需要什麼問它就對了。
它要解決以下情境:
而為了以上情境問題,一個Service Discovery透過實現以下兩個邏輯層來解決問題
要維護一份可用服務的清單。可以想像成一個數位電話簿,可以回答這件事情現在誰可以做。
不過這裡先留個伏筆,注意剛剛提到的兩個字眼維護與現在。這兩個字眼代表現在的清單需要知道當下所有微服務的狀態,有沒有服務其實已經掛掉了?這部分是由另一個邏輯層Registry負責提供接口,等等會提到。
Query這裡具體實現可以用資料庫的方式來實現清單的保存。一般來說單一MySQL就已足夠應付數千同時查詢請求,透過實體橫向 Read Scale來擴展。如再進一步有效能方面要求,可引入Cache機制,但狀態一致性就會增加空窗時間,這時候就是與業務需求之間的Trade off了。
而如果有多個微服務可提供要Pass給哪一個呢?簡單做法就是Round-robin,所以Service Discovery也會有Load balance角色存在。
這裏就是用來維護當前裝態了。大致上會有Registry與Unregistry。
Registry,以Docker實現的微服務來說,就是紀錄Container IP與 ID等資訊。還有這個Container能夠提供那些接口API Path可使用。
Unregistry則就是把這個服務標示為無效,讓查詢時不要把這個Service也列入可用名單內做挑選。
而實際在實現註冊功能時會遇到一個問題,是Service Discovery主動對新服務做註冊,還是新服務來主動對Sercice Discovery做註冊。
Service Discovery主動對新服務做註冊有以下優點
但缺點就是
而新服務來主動對Sercice Discovery做註冊的優缺點,把上面反過來看就是了。兩個比較起來,新服務來主動對Sercice Discovery做註冊
以長期來看則會是一個較好管理彈性也較高的做法。
這裡大致上分主動與被動做法:
主動作法如既然已經有一份清單,就可以定期對每個服務發送健康狀態檢查的請求,粗略的可以是Ping,而如果對於Container掌控度較大,則可以協調出一個專門的API接口來進行狀態檢查。
被動做法則是當選出一個服務並對其呼叫時,如果沒有回應則標示此服務為下線並報修,同時在從其餘可用服務中挑一個出來呼叫,依此類推一直到沒有服務可用為止。
兩種做法各有優缺點。主動做法來說,Service-Discovery責任已經很重,再加上要定期對眾多微服務做定期檢查責任已顯吃重,如要採用主動方式,建議切出一個獨立邏輯的服務運行。主動式的優點當然就是發現故障服務的時間會迅速許多,尤其當微服務增多時更明顯,不會有服務已經掛掉卻躲在那裡的情況產生。
兩種方式宏觀上來說,被動是可用的方案,而主動則算是好還可以再更好的方案。長期而言應在架構上選擇主動方式,而被動可應用在初期應用系統或規模較小微服務數量低於100的自建系統。
Service Discovery這個主題其實還有分Server-side Discover(下面簡稱ssd)y與Clint-side Discovery(下面簡稱csd)。不過絕大多數方案如k8s都採行ssd作法,而我認為csd只是做了一半的ssd,實在也沒有什麼非用不可的應用情境,所以就沒多做介紹,想了解可參考附錄。
只要談到微服務架構就必定會談到Service Discovery,這算是整個架構的核心基礎設施了,在上面幾個Section大致上把幾個實作時需考慮的架構問題談過一輪,看下來會發現在註冊Registry那一塊,Service與微服務不管採行什麼做法都是需要有幾個共同溝通的API來合作,如服務可呼叫的API Path與健康狀態檢查API,所以需要考慮兩者之間溝通的標準Protocol如何制定與導入,長期來看可能還有向下兼容的議題,而對外查詢方面則須考慮效能需求來決定服務清單儲存方式,而上面所說也全都要建立在業務需求上來做最後設計決策。而業務需求會一直變,架構上也就會一直演進。
所以全面了解Service Discovery的眉角可以才能依據業務需求設計架構,讓微服務系統達到容易使用維護與擴充升級的架構目標,最後更好的去支持業務面的需求。
安德魯的部落格-微服務基礎建設 – Service Discovery
]]>談判的目標即是達成合作,要達成合作就必須雙方都同意接受,這時候如議價即是找出雙方對某物價格的交集區間,也就是ZOPA(Zone of Possible Agreement)。
比如合約議價這件事,甲方預算上限如果是100萬,乙方最低賣價為80萬,則議價上ZOPA即為80~100萬,乙方要盡可能逼近100萬合約價,甲方則是能盡可能逼近80萬合約價。
這邊有一種策略叫做錨定:人在估計數值時,容易將他人提供的數據當作起始值來進行推測,也就是身為乙方,一開始可以開出自己底價的150%,來讓雙方的起始談判價從120開始談起,爭取40萬的緩衝空間給對方殺價。同樣策略甲方也可以開出低於自己預算的50%從50開始出價,來讓整個談判起始點從50萬開始談。
一但錨定對方成功,就是所謂的立於不敗而後求勝了,因為無論怎麼退,你都是贏的,贏多贏少的問題。但當然人在江湖飄哪有不挨刀,有一天你被錨定了?其實要找出對應方法,從另一個角度看問題答案就呼之欲出了:你為什麼會被錨定?不外乎以下幾點:
這裡就是說當對同一個議題沒有交集ZOPA時,比如錢與天數,嘗試引入其他資源進入這個局,來突破僵局。比如議價上有可能對方的底價跟你的預算真的沒有交集,那是不是嘗試用保固或者產品特色公司特色,未來折扣等方式來讓交易能談成。
這裡則又帶入了一個新議題,我該如何帶入正確的外部資源?這可以靠事前做功課,也可以透過對對方提案來遲是了解。比如工程師說期限內無法完成,但假設工程師缺錢,那很有可能可以為了錢來替你加班趕工縮短工期,那這時候加班費與專案獎金就是可以拿來交換工期的其他資源。
]]>年終又到了,過去一年你是如何評價自己的工作產出?
今天你是一位專案經理,你在一場同業聚會上自我介紹上說:『我平時會協助客戶進行需求評估,給予專業之專案規劃說明書,並且跨部門溝通協調專案在時間內完成』。ok,這樣乍聽之下沒有問題,但盲點在於如果這時你的另一位同業說:『我今手的專案總金額達3000萬以上,客戶皆為台灣知名銀行,並且都能提前交件,節省成本達10%,其中60%為人力成本。處理過10個專案,並且都成功如期結案』。如果你是老闆你要用那一位呢?
第一位只是敘述了他的職位說明,任何一位差不多年資的專案經理,工作內容應該都是差不多的,大家都做了差不多的事,你有什麼不同?而第二位則把重點擺在具體的亮點與實際的貢獻,比如知名公司、專案規模大小與總結案金額等。Let me put it in this way,讓對方自動從你做過的豐功偉業中去得出你有能力且很專業的結論。
這讓我們學到什麼呢?平時工作上要一直問自己,我正在做的事的實際貢獻是什麼?成果、績效 、里程碑。對業務來說就是你的業績與合約金額、成交數與客戶數等。對技術來說就是你的專案規模、複雜度與金額。這些都是可以用數字很明確的衡量出得價值。
定期的去把這些事情記錄下來,比如負責某專案,其時間、金額與你在這個專案中貢獻等。能數字化就數字化。如果你整理不出來呢?那就要好好檢視一下自己是否能去主動爭取相關機會,如爭取有實際可量化貢獻或成就的事情來做。
又到了實際行動的時間,從現在開始定期盤點自己的職涯成就吧,2 month basis。格式就如以下,一筆一筆的記錄下來:
公司現在正在進行產業升級,要從硬體跨足軟體平台,老闆很重視軟體,認為是未來提升營收的成長動能,也是公司在市場攻城掠地擴大市佔率的重要戰略工具,但合作的同事或底下的部署尚不清楚公司目標,把軟體研發的工作視為‘額外’的工作,認為原本硬體工作做好就好,學習軟體的部分是多餘的,為什麼我要學?
但是硬體部份其實賣出去剩下都是維護,在老闆眼中只是例行性工作,就算出狀況要聯絡原廠也只算是緩衝工作,把大部分時間挪去聯絡原廠解決問題,然後覺得自己不被重視(可能硬體維護的錢公司常常公開說很重視,導致認為此事在老闆眼中很重要,但老闆只在意業務有沒有談高維護合約的錢而已,技術部你處理維護好只是領薪水份內的事)。
上了課之後,學會以後跟部署說明工作有分緩衝工作跟核心工作,不要只是把時間都拿去處理緩衝工作,高風險低報酬,然後覺得自己明明努力在做維護,公司還虧待自己。
老闆常常說維護很重要,是指維護的錢老闆覺得很重要,所以在業務部那是核心工作或根本是形象工作,在技術部,維護偏向緩衝工作。
所以大家要把時間跟精力,放在研發新軟體上,這樣老闆對你的態度自然會變,會重視你。薪水 職位 尊重那些自然會來。
自己之前常常搞不懂老闆一直逼我們pre-sales出去簡報的時候,為什麼要積極的去換名片?不就簡報完叫業務去問有沒有興趣就好了,真的出問題再找業務去聯絡技術窗口,接著我們再來接手。我們技術人員就還是趕快簡報完回去開發程式比較重要。
跟我有同樣想法的技術人員幾乎是全部,都覺得跟客戶換名片沒什麼意義。但上了這次課之後搭配以前的情境恍然大悟,也知道以後怎麼跟同事講換名片(搞懂title, 搞懂對方在這個案子力扮演的角色)的重要性了。
就技術面來說,產品賣出去真的出問題,第一時間要是可以找到working-level的人,那就能很快地了解狀況。說不定對方還能幫我們現場做一些除錯,問題就直接解決了。
業務面來說,而我們pre-sales成案也是有獎金,如果我能搞懂可能那些人是真正要使用的人(常常業務對口只是負責採購設備的單位),並與他建立關係,會後直接附上更多參考訊息,並且看對方的回饋態度,其實有沒有機會成案搞不好很容易就觀察出來,不用事後還白忙很多場,甚至因為主動聯絡真正要使用的人,成案的機會都會提升。
以後我就完全知道出去換名片的意義,因為能對整個局更加了解,找出真正重要的關係人!以後部署出去做pre-sales也才好說服他們換名片,知道出去簡報重點在哪裡,搜集問題,搜集人的資訊,搞懂局!
我也可以分享給老闆怎麼讓底下的人了解交換名片認識人的重要性,這樣他們才會實際去做!
常常老闆會莫名其妙跑出不可行的idea,我都會直接說為什麼不可能,雖然老闆事後會理解不可行(應該吧…因為沒再提了),但當下都會有一些爭論。
了解應該去滿足老闆有效掌控的慾望後就知道,先思考老闆背後動機是什麼,比如業績提升(感覺是TOC核心目標),他心裡面想被滿足什麼,產品支援度提升,自己得意見被思考(感覺是TOC內心需求),然後第一時間不急著反駁老闆的對外訴求,表示對於大方向,比如支援度提升認同,然後再說我們會去研究老闆的對外訴求。
上完課後第一個工作日老闆來跟我產品應該增加A功能,我就學乖了,先說『沒錯,應該要提升對於這個功能的支援度,這樣才有辦法做xxx,我們會去研究看看A功能整合上有沒有問題』,當下老闆就沒有再打斷我們工作了。事後我們再提其他解法就可以了(如果老闆還記得…),畢竟滿足內心需求有很多種做法!
自己對於工作與產出是個很有責任感的人,對於專案的輕重緩急因為有上過專案管理啟蒙也有判斷力,公司業務都很喜歡與我合作。但有時日常生活的消耗時間,專案或技術或市場推行碰到阻力,一陣子沒有進展,或是不明原因,有時會有種好像不小心庸庸碌碌不知道自己在幹嘛的感覺。
像今天在猶豫要不要跟大家出去買飯吃,平常大家會揪但我心裡是不太想的,中午時間喜歡快速解決,然後繼續工作。但今天轉念想到老師上課三不五時就會指的『你想從工作中獲的什麼』的那面牆,馬上就覺得我有我的理想與目標,不是來這裡交朋友,而是在工作上能與人愉快的合作建立自己得專業品牌才是我要的,這時候心裡立刻就不猶豫,自己去買飯火速解決。
以後又有不知道自己在幹嘛的感覺時,就會提醒自己那三個目標,幫我做出較為正確的選擇。真的很實用。莫忘初衷。
還有很多的情境,但不算是問題,但依然可以應用課程的知識去做強化。比如對於客戶安全感的管理,之後定期主動的提供消息(明確計畫與專業態度),主動去管理他們的不安全感。並且之後比如產品如何上線等情境也都提供選項,一方面我們可以收斂想法,一方面可以滿足客戶的掌控慾。
至於適度地提供壞消息並隨後擺平之,我把它定義為先說這個功能很難,要花多功,但我們可以做到,之後再完成,讓客戶提升安心感與風險免疫能力。
最後謝謝姚老師Bryan把這麼抽象的知識概念系統化的傳授給我們!
]]>大家學了這麼久的英文,一定有個願望是可以說英文。第一份工作時我擅長看國外的技術文章,簡單英文書信往來也沒有問題,但我就是無法用嘴巴說。問題在於如果我們今天認識了火星人,我們想學學看怎麼說,最有效的方式應該就是去偷聽他們對話,並且去模仿他們如何說,但我們通常不那麼做。
要說這堂課對我的影響,很簡單。如果我現在要說英文,流程不再是想法->中文->翻譯->英文。慢慢的我有感覺到中間的過程不見了,變成是想法->英文。
我其實不把這門課定調為『英文課』,而是定義為如何改變自我日常行為,進而達成有效提升英說能力的日常習慣改造課程。
我認為學英文需要時間,也需要方法。但大部分的方法無法讓時間在學習說英文上成為朋友,這門課珍貴的地方在於有能力讓時間變成你學習英文的盟友,but,同時也需要耐心與毅力。
這就我最愛的部分,因為我很清楚知道,能夠與人拉大差距能讓人稱羨的事情,一定需要時間耐心和毅力。所以我知道我走在對的路上。
最後謝謝Joy老師囉,也就是上面照片集美麗與智慧於一身的女神! 英文說得練習做到現在也邁入第三個月了,就如健身一樣,這需要時間,但方法對了堅持下去成果就很驚人, we will see.
]]>這個月初因為朋友建議去上了孫治華老師的
【SmartM 菁英商學院】成功提案!打造商務簡報說服力
課程。上完課後火速改了簡報內容並去跟客戶簡報,真的發現客戶聽得異常專心,對於我要表達的重點也能夠真的抓住,實在是又驚又喜。在這裡把一些實戰後的心得記錄一下,以供自己與別人參考。
做簡報的第一步想的不是自己的產品有什麼優點,或自己產品的任何事情,而是想想看別人可能會問我們什麼問題?針對這些問題我們的產品有那些優點可以來解決對方的疑惑。
第一階段重點在於要讓對方有興趣。而要讓對方有興趣你的簡報就要有吸引力,吸引力來自於讓對方感覺這個簡報真的跟我有關係。立即針對對方的痛點提出解法是一個好的開場。
想像兩個圓,分別是對方的問題,還有我們產品的優勢,中間交集的地方就是我們要讓對方一開始就清楚知道的。所以做簡報前先開一個會前會,業務與技術一起加入,主題就是猜想對方現階段遇到的前三大問題。並且針對這三個問題提出我們產品的對應解法。業務負責依照在客戶端搜集的情報來提供問題,技術負責共同提出可行的解法。
而在開場部分你所提出的解法,不要太囉唆,這裡解法著重在結果,也就是效益的部分WHAT。至於技術的細節比如你如何做到的HOW,在這裡先不要提。比如客戶擔心效能問題,就先展現出強大的壓測數據,至於你如何做到,開場這邊先不用提。
其實只要你有辦法一開始就說出對方心中大部分的疑慮,你就可以初步贏得對方的信任感,因為對方會覺得你懂我。
第一階段說了一大堆效益,開了一堆支票,那這時候一般人都會想真的嗎?
所以在這個階段你要證明你不是在唬爛。有可能你已經有實際上線成功案例可以拿來講,可能你有數據可以顯示,重點在於這個階段因為前面你說了太多的好,人性會不自覺懷疑,所以這裡需要透過幾頁來證明你有經驗有能力試做得到的。
再來就可以談談技術面的細節,比如你如何做到你前述的那些優點,這裡你可以依照自己的狀況,用自己的方式來讓對方瞭解,如果你有讓對方上了一課的感覺那更好,更能增加聽者對你的信任。這裡的難處會在於一般技術細節表達上會過於死板生硬,所以需要小組腦力激盪用流程圖、對比圖或是表格等讓聽者容易了解。
這時候依照對方的狀況加上時間以及做法,給對方一個藍圖去知道接下來要怎麼做。這裡如果是系統可以分批分階段汰換,如果是元件開發則可以列出從需求分析到驗收的時間表。
這裡重點在於讓對方理解你有執行這方面的經驗,可以依照他們的需求帶領他們。
曾經聽過一個笑話
女大學生晚上會去酒店陪酒 →社會觀感不佳。酒店小姐白天堅持去大學聽課 →充滿正面能量好勵志!
當然上面這個笑話聽起來不一樣單純是因為語意關係,而簡報順序換個順序說服力道會不一樣是因為我們順著人被說服時的邏輯去編排簡報順序。嘗試依照吸引、專業、執行三個階段去簡報內容,更能夠抓到重點說服客戶達成簡報目標。而且依照問題導向去製作簡報,時間真的也短很多,也證明好的簡報不要花太多時間做,通常會花太多時間都是在空想。
]]>要上線一個系統,或更新一個系統的版本,首先最重要的就是系統穩定度。有些系統比如在銀行,上線後出了問題都是非常緊急的,一但系統上線開放給別人來使用,背後需要考慮的完善,才不會上線之後一直在救火救不完。
底下從底層的Exception的機制、Log的紀錄方式、整體功能的完整性驗證、系統如何維持總是不死的狀態,到最後如果還是發生持續性錯誤如何處理,依序來談談資訊系統上到Production前,需要先考慮到的議題。
最重要就是有錯誤產生就一定要在程式碼有catch到,並請定義好這個狀況搭配的錯誤代碼為何。有時會看到工程師在catch裡面不做任何事情,這是不被允許的,一旦出了問題大家都一頭霧水無法在第一時間了解狀況,影響到處理問題的黃金時間。而設計系統架構時就把錯誤回傳方式定義好,比如以下例子,後端程式只要判斷result為0,就可以知道有錯誤產生,並且讀取errorCode做相對應的處理。
1 2 3 4 |
|
Log最終是要拿來分析的,不管是程式分析還是人眼分析,都需要一個清楚固定的格式,尤其是第一時間往往要靠人眼去分析,這時候Log寫的工整與完整,絕對有助於除錯。一個好的格式必定要包含時間When,是誰Who,發生了什麼事What,錯誤代碼或錯誤訊息。
上線或更版之前,必定要做兩件事,功能性驗證與壓力測試。功能性驗證我常用的做法是寫自動測試,把所有預期狀況都寫成一個case,上線前的版本都要掃過並驗證功能正常。再來壓力測試就是測試針對大量併發連線,大量持續呼叫,服務是不是依然回應正常。
服務如果持續回應,但是回應一樣的錯誤怎麼辦?這時候系統要能判讀錯誤並自我修復,比如re-try機制,如果socket連線斷掉等等,系統要能夠自我偵測並且主動重新連線。另一種狀況則是如果系統遇到fatal error,要使用守護進程,讓作業系統保護這個程式,一但偵測到結束訊號,要主動重啟服務。
第一時間要通知維運人員,常見做法是發送Email,並包含足夠的錯誤訊息資訊,如果環境開放一點的可以串接Slack API。因為這個時候已經發生系統沒有考慮到的狀況,才會導致服務停擺。第一時間常是手動重啟系統,再來看Log找錯誤,加入開發排程,緊急的話開一個Hotfix branch出來,修正後把錯誤的狀況寫入文件中把狀況、原因、如何處理寫清楚,避免再次發生。
如何開發一套系統能在各種狀況下穩定的提供服務,是需要開發團隊透過敏捷開發方式加上完善的文檔與強烈的責任感共同來達成,不是一個容易的目標但一但達成是非常有價值的經驗也能提供很高的自我成就感。以上僅是列出部分議題,還有更多HA機制比如多台互為備援等,等待日後去實踐。
]]>長期開發並維護一個產品跟短期衝刺生產出一個專案,最大的差別在於開發流程。負責小元件或小專案在開發上是同步進行的,而產品或大系統在開發上是異步進行的。開發元件可以用土法一路衝到最後,但開發系統沒有完善的基礎設施,案子很快就會出現許多問題導致開發窒礙難行。
如果以往是開發小系統,但突然有一天有機會接觸大系統的開發或規劃,沒有這些概念先Keep in mind,開發路上就會很辛苦了。
小專案需求訪談後產生工作說明書然後簽字畫押好,只要規格寫的好範圍是可以被確定的,也不可以隨意亂改,改了可以再收錢。所以開發者一開始就能清楚界定專案的範圍,大部分未知的風險比如技術瓶頸可以被事先預知,開發時間可以被事先規劃。所以實務上從撰寫規格書界定專案範圍,再來實際開發最後到測試與驗收,流程上是以同步(sync)的方式進行。
而大部分產品會給多個客戶使用那就會有多重意見和偏好,再來因為想做的功能多,甚至很多功能是要做但現在還沒辦法做,一開始也就是先畫出WBS圖來大略上界定範圍,很難一開始就寫好完整版規格書,界定所有API。而是隨著時間發展,常常是先寫好幾個客戶緊急需要的模組,然後就出貨給客戶,之後陸續再Release新版補給客戶其他沒有那麼緊急或重要的功能。而一但把時間因素拉長並考慮進去,開發上很多問題就會浮現了。
有緊急狀況發生比如出貨的產品臨時被要求在上線前要提供弱掃報告與修正,那這時後原先預定的下一個版號要新增的功能就要被置換成修正弱掃缺點。原本要被Merge回來的Feature支線就要暫緩,並且火速開一個Feature來修改弱點並發布成一個版本。
如果有很多新功能都接近完成,這時候要Release那些到下一版?通常第一個要考慮的是客戶的安心感。比如新功能要犧牲效能來換取穩定度,這時候要犧牲多少效能?這數字是客戶可以接受的嗎?客戶搞不好寧願犧牲穩定度來換取效能?如果客戶有多個有的可以有的不行呢?
上述沒有考慮到就貿然Release出去,如果驚嚇到客戶,讓客戶對我們信心感和安全感下降這都是很嚴重的損失。
隨著時間迭代,A客戶是0.8版,B客戶是0.9版,這時候怎麼從0.8升級到0.9?兩個版本之間又有什麼差別?如果是好幾10個版本分散在各地有辦法處理嗎?如果沒有搭配文件、程式碼版本控管、環境印象檔化,不用多久整個案子就會無法維護。
文件記錄各版本的Release note,並且要有規範,標明新功能和已知問題等。版本控管Git要有Git Flow如Release branch在程式標明版本號,和Tag標註方便切換不同版本。運用Docker把運行環境標準化Infrastructure as Code,除了確保開發時與上線的反應相同,也避免環境升版降版時遺漏了設定造成的錯誤。
Product version control document、Git、Auto test、CI Server、Project Management Know How(WBS etc…)、Document Guideline、Issue tracking等,以上這些就像是現代產品開發所必備的基礎設施,少了這些要開發大型系統或隨著時間迭代成長的產品是不可能的事情,沒有這些整個技術Team無法持續成長,也會欠下一堆技術債,累積到最後整個產品開發寸步難行,而對風險的忍受度也會異常的低,比如一個關鍵開發人員走了整個產品開發就無以為繼了。
從開發元件與小APP到現在開發產品,遇到的問題很多已經不是單一技術面,更多是如何管理這堆技術生老病死的問題,僅記錄一些最近遇到的實際問題與想法。
]]>與其繳錢給盈利CA,現在你有更好的選擇-letsencrypt,免費開源自動化更新的CA。
網路上的教學文章不少,而我這邊整理幾個好用的tip,主旨在於自動化與降低維運的難度。
因為自己的Server是用這樣的環境,加上這個環境也非常普遍可靠穩定,所以本文章就以這個環境當做基底。
1 2 3 4 5 6 7 8 9 10 |
|
你必須向letsencrypt證明DNS指向的這台server是你host的,等等letsencrypt會去你domain下的/.well-known/acme-challenge/
path查找文件,如果找得到就能證明是你host,也才能簽發證書給你。
而這裡統一指向/var/www/letsencrypt
是因為有可能你現在用單純的html環境,有可能之後換成proxy_pass
反向代理到node.js等,這都會使得/.well-known/acme-challenge/
這個url路徑指向的檔案在你host的server上產生變動,這種業務上變動跟HTTPS是無關且可以切開來降低兩邊的耦合度,而隨著日後的domain變多,統一指定路徑這樣的做法也能夠降低後續維運的難度。
去下載官方的驗證tool certbot並安裝,下面例子自行把abc代換成你的domain
1
|
|
成功的話會出現包含Congratulations!一大段話,憑證會被存在/etc/letsencrypt/live/abc下
。
/etc/nginx/conf.d/abc.conf
1 2 3 4 5 |
|
/etc/nginx/nginx.conf
1 2 3 4 5 |
|
以下為更新腳本,我是命名為renewCerts.sh,並存放在/etc/letsencrypt/下
1 2 3 4 5 6 7 8 9 |
|
打開crontab設定檔
1
|
|
加入sh設定每日自動執行然後儲存
1
|
|
如果Micro Service在不同的實體機器中,則可以透過run
指令裡的-p
來把Container與Host的特定給對應起來。
比如以下指令就是啟動一個Web Container並且把Host的Port 3000與Container的Port 80給串連起來
1
|
|
那接下來就可以在Host用127.0.0.1:3000來訪問Web Container的Port 80。
而當Containers都在同一個Host,比如一個是Web一個是DB,Web要如何連上DB呢?其實每個Container在run的時候預設都是走bridge模式,這裡就是docker會創建一個veth interfaces,讓該host的Containers都跑在同一個network。
只要用inspect
指令就可以查到該Container的詳細資訊,而裡面的KeyIPAddress
就會有IP資訊。
1
|
|
在同個veth環境下,有了IP,Container之間就可以彼此溝通了。
https://docs.docker.com/engine/reference/run/#/network-settings
]]>Docker的Container有個重要的原則是不儲存資料。為什麼呢?比如你做一個Web Service的Image,你把NPM,前端分流Nginx等軟體都安裝好了,這時候要把網頁的檔案放進去,一種做法是在Dockerfile
裡面用COPY
把網頁檔給複製進Image裡面,然後再Run起來。
可是這種把不斷變動的資料檔案存在Image裡的做法會帶來許多問題,我如果改一行Code我不就要重新Build或新Commit一個Image嗎?我如果有好多個網站要跑在不同的Container上,我不就要做好多個Image?如果是DB的Image,把DB File放在Image裡面,那不就隨著時間過去Image就要一直更新了?
所以在製作Image上,常見的best practice是把執行環境打包成Image,而時常會修改的檔案比如網頁檔案或資料庫檔案這些資料
就另外掛載在Volume上,也就是Mount在Host機上的資料夾。這樣就可解決上面所提及的問題。
底下我們就以網頁服務常見的/var/www資料夾與資料庫常見的/var/lib/mysql為例,操作如何把這兩個存資料
的地方給另外存在volume上。
1
|
|
這裡的-v用法就是用來掛載volume的,去mount一個host資料夾為container的data volume。並且把這個container指名為dbdata,這種container又稱作為data volume container
。
這種container特別在於本身只是用來記載那個host資料夾對應mount到container的那個資料夾,所以container本身是不用啟動(run)的。
PS. 如果Host的dir沒有指定,則docker會在系統的某個陰暗角落建立一個新的資料夾。可以用docker inspect container-id
指令回傳結果裡keyMounts
的Dictionary裡找到那個陰暗角落。
有了data volume container後,只要以後在run container時透過--volumes-from
參數,就可以直接把指定的data volume container
的volume給掛載進來。
1
|
|
這時候新產生名為mysqldb的container,cd到/var/lib/mysql
就會發現與host的absolute/path/to/host/dir
資料夾是連動的,也就是mount再一起了。
舉個實用情境,假如資料庫版本要升級,只要在Dockerfile
裡面升級資料庫版本,然後把新的container啟動時掛載dbdata,資料就還是一樣。而如果當初沒有把資料
從Image分離出來,是要不原本DB的資料給匯出,再匯入新Image,非常麻煩,而不這麼做DB的紀錄就消失不見囉。
這裡的效果也就是官方介紹的volume主要用途,把資料
與container分開,達到data persistence的目的。
Data volumes are designed to persist data, independent of the container’s life cycle.
一但建構好基本環境,比如NPM, PM2, Nginx…etc,打包成一個Image後創建Container,以後Run這個Container只要搭配以下參數,就可以在本地修改,然後在container裡面實際測試了。
1
|
|
比如以下指令就是啟動一個已經安裝所需運行環境的image(npm-ready),然後指定Host資料夾(/Users/shih/Desktop/lab/PSControlCenter)掛載到Container的/var/www上。
1
|
|
最近Micro service火紅,大型服務被切成一個一個小模組,減少彼此耦合,個別跑在各自container上,方便重複部署,且彼此互相用Rest API或socket溝通。這樣帶來的好處在於可以在開發上減少後續迭代的困難,減少維運的難度,增加系統穩定性。
但要獲得這些好處,軟體在最初開始設計架構的階段就要拆分服務,一開始設計不好之後就算有docker工具那也只是把所有服務丟到同一個Container上,沒有辦法發揮docker切割服務的優勢。
所以想成為架構師,當然不能不了解這個工具。而從程式開發上來看,能夠把CI Keep in mind,有新Commit Push到develop branch,CI Server就自動執行下面步驟
能夠協助開發者確保最終程式碼在Production環境是可以正常運行,有問題可以立即發現與處理。
Docker對比傳統VM優點在於所消耗資源很小,啟動速度很快,並且兼具傳統VM打包成Image擋可以Anywhere都快速建立起一樣的Service等優點。
這篇文章主要就以上面幾點依序從包含如何製作Image,產生Container,利用Container啟動我們要的Service,最後如何匯出部署到另一台機器等一系列記錄下來。
要導入的Service是由三個部分組成
之前做法是把Node.js專案都放在同台Server,但因爲HA需要,所以也有一台Hot standby的實體機並排在HAProxy下。這裡帶來第一個問題是當要重新build環境時靠Install Guide手動安裝很不方便,解決方法便是用Dockerfile
,把Install Guide所需的環境與步驟打包成一個Image。
1&2專案相同部分是Node.js專案,用Express作為Route Framework
,所以可以Build一個Base Image來當基底環境,之後只要分別把/var/www
置換成對應的專案檔即可。
1 2 3 4 5 6 7 8 |
|
有了Dockerfile後就可以Build Image了
1
|
|
之後會得到一個Image ID,因為是只安裝npm基底就取名為npm-ready
1
|
|
現在打docker images
應該可以看到類似npm-ready latest 43c671f848fd 22 hours ago 405.6 MB
的資訊
這時候我們已經有一個Image檔,包含npm與必須的tools,只缺express專案檔。所以接下來就以FROM
指令,指定以npm-ready:latest
為底,用COPY
指令把我們需要的專案檔複製到Image中。
這裡要注意第三行的PSControlCenter/
這個目錄必須與Dockerfile同一個目錄(docker build
後面會加上的path我們是打./),不然會出現找不到此目錄。
1 2 3 |
|
得到新Image ID後幫它補上名字方便識別
1
|
|
至此我們已經有一個包含全部所需要檔案的Image檔control-center
了。現在只需要利用Image去產生一個Container,並且執行這個Container就行了。
本來產生create
與執行start
是兩個指令,這裡可以用run
來代表連續執行上面兩個指令。類似git裡面pull
是連續執行fetch
和merge
。
1
|
|
這裡要注意的是-p
,每個運行中的container的網路環境與host是完全分離的,所以我們要從外部去訪問container,就要用這個指令來指定port的相依關係。
這個例子裡我們在host輸入127.0.0.1:9453就會訪問到container的3000 port。
建立完container後,這時可以透過下面指令拿到Container ID
1
|
|
運行container後,想再得到運行狀態中的container的bash shell可執行
1
|
|
exec指令就是對該運行中的container下達指令。
到這裡我們已經利用Image去產生Container,並起啟動了Container,指定了Port的映射關係,最後取得該Container的Shell。這時環境已經建立起來,我們就可利用PM2把service給run起來:
1
|
|
然後在Host瀏覽器訪問127.0.0.9453,就可以看到服務啟動了。
把control-center這個Image用save
指令匯出成.tar檔
1
|
|
接著在另一台的Dokcer instance上用load
指令,指定tar檔路徑匯入成image
1
|
|
再來用docker images
來確認是否有成功匯入Imagecontrol-center
。
之後我們便可以把該Imagecontrol-center
打包匯出到其他機器,短短的兩行幾秒內就把服務給建立起來,非常輕鬆寫意的部屬方式。
1 2 |
|
下次介紹另一個Docker的重要概念:Volume。Container與Image有個很重要原則是裡面不要存Data,也就是不要把MySQL的資料給存在Image裡,所以在資料庫相關的Container裡有關Data的部分會採用另外掛載的方式。
大家都有這樣的經驗:辛辛苦苦絞盡腦汁,經歷無數夜晚暴肝打word,期末滿懷信心交出報告後,換來的是又一次的失望。
如果說一般考試把時間與心力砸下去結果就會好,皇天不負苦心人,那期末報告真的是一件令人頭大的事,時間心力砸下去只怕教授也不領情。那有沒有什麼方法保證最高分?有!很簡單,就是你不能只是把報告做完,你要做到一半就把報告拿給教授看,甚至要拿最高分你有必要寫個一兩頁就傳給教授看。
一開始比如說:「我想要從這家公司他們幾個創辦人的背景開始介紹,你覺得好不好?」,教授可能會說:「我覺得不好,因為xxx是個無趣的人,你不需要介紹他….」,這時候你就改麻,然後再問他:「這樣好不好,那你覺得我哪裡可以再加強?」,教授如果說:「那我覺得你可以再focus在這上面…」,那就再回去加加加,增加篇幅之後再問…這樣一路反覆執行,到學期末,保證你絕對最高分!但是為什麼呢?
注意!答案不是”最常跟教授接觸”,那比較像是諂媚,這裡絕對不是教你諂媚。這背後有一個原因為什麼會最高分,因為你這個報告等於是老師幫你做的阿,如果你真的定期跟老師update一些東西,這東西根本就是老師幫你做的阿。那讓老師幫你做這件事情是什麼意思?
剛舉的例子,老師就是那個消費者,你一直去推這個產品、一直去測試消費者,一直修改,直到消費者買單為止麻!你可以一直測試一直測試、一直修改一直修改,不要悶著頭一直寫、不要怕被指出錯誤,這個過程,不管是做報告也好,或是做事情也好,是你最該擁有得一種態度。
不要把所有的事情都堵住到一擲上面,如果你在最後一個禮拜要發表的時候才讓教授知道你的全部想法,看到你的全部東西,你仔細想想,這不是一件在賭樂透的事情嗎?你之前完全都沒有回應耶!也都完全不知道教授對你報告的想法,猜牌算牌都不想做,就在最後一刻突然翻出你的底牌,你根本就是在賭樂透。
跟老師溝通,肯定你的作品,這中間要懂得清楚跟老師表達你做了什麼、清楚理解並記下老師希望你做些什麼、配合老師時間、反覆溝通記錄、鍥而不捨的修改、抓到老師口味、持續的update…這些都很難耶,這也都是你真正的價值。這些東西比你待在家裡、不用接觸老師、照著自己意思做,那樣最簡單!
不只”完成報告”,運用這個來回溝通的方法”完成老師滿意的報告”。而出了社會以後,面對上頭交辦下來的事情,別人埋頭苦幹而你會善加利用這點完成事情,成果老闆上司都滿意,你跟別人自然就立分高下。
]]>UISearchController
,只要把屬性searchResultsUpdater
指定物件在updateSearchResultsForSearchController
這個方法中實作filtering and updating就可以了。非常方便。
從Server抓取資料,這裡我們用originalDatas
這個instace variable存JSON陣列資料。注意Retain Cycle即可。
1 2 3 4 5 6 7 8 9 10 11 12 |
|
利用NSPredicate
制定陣列搜尋規則,這裡是指定陣列內有包涵searchString
。
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 29 30 31 32 33 34 35 36 37 38 39 |
|
這個APP是做公司內部通訊錄的,而如果陣列裡面包涵員工ID,或到職日期等數字資料,就可以在NSPredicate
字串比對完之後,搭配Sorting來對數字做排序。
潮一點的搞個數據應用,可以把搜尋歷史用SQLite記錄下來,把搜尋後而且點擊
這個元素加入到Sorting的條件中。這樣一來使用者越長搜尋的排序就會越前面囉。
最後也可以做成讓iOS系統搜尋Bar也可以找到APP內的資訊,不過這樣就要把通訊錄存在本地端DB,而不能只是In-Memory JSON處理了。
]]>成吉思汗的館長說他開館就是相信台灣應該擁有更好健身房,所以要持續的提供台灣一個高水準的健身聖地,提升台灣人健身運動的專業風氣。討厭看到市場上充斥的都是直銷與只想賺錢的商業健身房與似是而非的健身觀念。
之前去過其他健身房,別的可能就是放很養眼的美女帥男圖,可能也會放勵志標語,比如今天得努力是為了什麼。但我特別喜歡成吉思汗該怎麼做就怎麼做的實幹精神,健身就是會苦,有苦才有收穫。每個人來這裡都是在跟自己比賽,而不是只是來打發時間。我們選擇在此時此刻來到這個健身房,是要互相見證彼此在痛苦中成長,我們能互相體會別人在力竭時努力的叫喊,猙獰的臉龐,而不會阿呦,這是在幹嘛。在這裡大家都在玩真的,真得都在健身,很有熱情想法的在看待這件事!沒有再跟你害羞,沒有再跟你玩半套。在這裡許多地方標語就是no pain no gain。
在這裡密集的上教練課,與教練聊天中知道這裡教練對於定期的考試大家都十分重視,不只是玩玩只求過就好,大家都追求好成績,互相幫忙當捕手教學對方不足之處,這裡教練是真心在追求身體上的進化與突破,跟著這樣的教練才能有學不完的東西,而我相信能夠不斷自我要求的環境這就是好的環境。
成吉思汗直接把台灣制霸印在門口,器材真多超多超齊全,妥善率也都很好,深蹲架排開就是六台,而全年保證不休息,想練隨時都可以來練,就連年過年除夕都不打烊,教練師資真的也專業又敬業。
之所以打這一篇是因為跟一位熱愛運動但在考慮上健身房的朋友聊天,偶然聊到為什麼這麼多健身房我選擇了在三重沒有離我家很近的成吉思汗,我突然發現儘管我十分認同喜歡這裡,但我卻完全沒有辦法引起別人的共鳴。後來思考,這應該跟Simon Sinek那個演講想表達的是一樣。
我都是從WHAT跟HOW來開始跟別人講解,提陳吉思汗優點從有大量專業的器材,很壯的教練,口碑也都不錯的點切入,但我從WHAT跟HOW切入,結果就是聽的人不能感受成吉思汗特別得地方。我試著從WHY這個角度切入,也希望下次我再推坑其他的人的時候能更引起別人共鳴,推坑成功。
]]>談一本重要的書,超級智能時代,這本書裡談的議題對每一位讀者都絕對切身相關。人類剛經過一波的資訊革命,最近幾年資訊技術的成熟發展,包含移動網路與終端設備如手機的成熟,帶來資訊大爆炸。資訊大爆炸後有了足夠的數據量,收集起來嘗試找出某些規則,並運用這些規則來使人類生活更方便,也賺取了大把財富。
但從工業時代以來的每一波革命都是先造福一小部分群眾,過了許多年後全人類才能享有革命帶來的好處。這一波大數據與人工智慧的革命帶來的影響與衝擊非常之廣,人工智慧就是想解決以往人類才能解決的問題,會取代許多既有的勞動力,再疊加上一波資訊革命帶來的影響,根據歷史可以想見需要長達半世紀來消化過剩勞動力帶來的負面衝擊。
以往人類學習的方式是習慣先假設某種道理,之後再去累積數據去證明出這種道理;我們習慣先假設因,才去驗證結果。上幾個世紀人類都習慣這套思考模式,稱之為工業時代思考模式。而當時間來到現在,容易尋找的真理幾乎都被發現完了,我們要面對的是不確定性越來越高的問題,往往我們連問題該怎麼定義都沒有頭緒,所以藉由累積數據來說故事,從資料裡發現道理,便是為了回答現代越發複雜,且不確定性極高的智慧型問題的新思考模式。
其實大數據不是用來解決人工智慧的唯一方法。最早其實科學家是想模仿人類思考模式來製造人工智慧,但發現難以解決不確性高的問題。而隨著硬體如儲存技術得成熟,連結技術如移動網路的成熟,處理能力如資料中心的成熟,這三者技術同時準備好了,使得人類發現與其讓機器造著人類的想法走,不如餵給機器一堆資料,讓它從中自己試著回答問題,結果比之前的方法就結果來說都更好。
逆推方方法論變成資訊時代的方法論。
順著這個思考模式可以發現。掌握數據,更嚴格來講是大數據的人在未來才有可能回答現代社會中越發複雜的問題。大數據顧命思議就是大量的資料,而大量的數據加上多維度,便能從中去試著找出規律,總結成智慧。
所以從人工智慧方向往大數據的逆推方法論走後,『人類在人工智慧領域的成就,其實就是把各種智慧問題轉化為消除不確定性的問題,然後再找到能消除相應不確定性的資訊』。
下圍棋人類依靠經驗與眾多棋譜來學習如何取勝,而只要能把棋譜轉換成電腦可懂的規則,電腦就可以大量的去讀取歷史棋譜,能比任何人類一輩子讀的都還要多,最後轉換成數學模式,採用依照大量數據訓練加上統計知識所做出來的模型來回答問題。雖然棋的變化是無窮的,但機器總能找出勝率較高的步法。
AlphaGo在比賽中走出許多令人類專家跌破眼鏡的走法,但最後又能贏。這裡重點在於機器不必像人一樣思考,只要能夠解決人的問題就好了。在大數據中得出的智慧是數據加上統計的及果,是有可能出乎人意料外的,而且能做的更好。能不照常規行事其實就是超級智慧的表現。
而AlphaGo知道自己在下棋嗎?當然不知道。只不過把智慧問題轉換成數據問題。用統計方法搭配大數據解決智慧問題後機器從此無敵。
所以對於行事有特定SOP的技能,也就是非創造性工作的從業人員,大數據加上人工智慧是大有取代的勢頭。比如基金操盤手、醫師、會計師、司機、護士、農夫等。
在未來掌握大數據與運算能力的少數巨頭,目前來看如Google, FB, Apple, Amazon, Netflex和大陸的bat,這些公司如果和公權力結合,那就是全面監控了。CIA要來台灣抓人其實不用跟台灣警察打交道,透過你使用的手機說不定還比台灣警察更知道你的所在地。免費的服務往往是用自由換來的。你提供時間與數據,巨頭提供免費服務。在未來隱私的保護是重要議題。
技術帶來的各命常常是憂喜參半,喜的是改善人類生活,讓一些處在浪尖的人發揮更大的作用。但因為技術進步而被取代的人力,往往沒有辦法在學習新技術,所以只好『養著』,耗上兩代就解決問題了。
這次的超級智能最重要的影響是人類會發現自己能做得比機器好的事情不多了,很多人會在技術進步的途中發現自己被拋下了,新技術的發展不是每個人的機會都會變多,許多人反而是機會變少,如全自動化工廠之於生產線工人,計程車司機之於自動駕駛技術。這些大量勞動力該如何解決?書中其實沒有提出解決辦法,只能接受接在未來的幾10年會有越來越多事人類贏不了機器人。而之後所做的決定也都要依照這個大前提去行動。
看完這本書心中是興奮與恐懼,興奮的是對未來人類生活充滿正面積極的想像,恐懼的是害怕自己是對這未來至少50年影響人類最深遠的領域一無所知,最終被拋下,在自己的工作生涯毫不自豪。幸好我是相關科系相關產業,也還年輕肯學有興趣,往後推10年的努力都要與人工智能領域有關,投入在相關領域是我對自己未來的規劃。
以下是Youtube連結,台大教授林軒田老師的機器學習基石 FYI。
]]>說到無線藍芽耳機我也是重度愛好者,早在前年就花了5位數大洋買了Sony的藍芽耳罩耳機MDR-1RBTMK2
,那時候最麻煩的地方在於配對的不穩定和麻煩,都要先按鈕換醒耳機等待手機配對,有時找不到還要自己去連線。還有麥克風根本是雞肋,完全不能拿來講電話收音非常差,一有電話打來常常是手忙腳亂拔耳機選擇本機的Mic等等…好在上述的問題在AirPods都被完美的解決了。
常常戴耳機遇到一個情況是別人突然來找你講話,這時候拿掉一邊耳機另一邊都還播著歌,有時還是要手動把音樂關掉,而AirPods你只要拿掉其中一邊耳機,手機立即就會停止播放歌曲,真的是很實用的功能。
再來重點當你講完話,把耳機再放回耳朵時,音樂又會聰明的自動開始播放了!一切真的就是方便到成自然。想像你帶著耳機在電影,突然有人打擾!你帥氣的拿下單邊耳機電影立刻自動暫停,講完之後再戴回去電影立刻繼續播放!Magic~
你的下一個動作都預先被做好了,對我來說這就是智慧型產品,就叫方便!
以前我用過的藍牙耳機當你兩邊都拿掉之後,你可能就是回到家不需要他們了,這時還要去手機裡面把輸出模式切換為原本的喇叭,多此一舉。而AirPods會自動偵測到你把兩邊耳機都拿掉了,iOS Device會自動把輸出切換回本機的模式。日常使用起來也是非常方便。
真的很神奇,明明麥克風不在你嘴邊是在耳朵旁,可是你講出來的話還是很清楚的被收音了。使用AirPods後講了很多電話沒有人跟我反應不清楚。最後如果特別有問都會說我這邊收音很清楚很清晰。不管在捷運上或大馬路或安靜辦公室裡都OK的。
搭配iOS Device很穩,就是穩。我想這是基本的啦。
高音感受與有線一樣,低音感受比有線好蠻多的,至少我有感啦。音質很主觀,很在意的還是親耳聽聽吧。如果可以接受原廠有線的,那AirPods這個應該沒問題。
AirPods本身支援快充,你聽到剩4%快沒電了,放回AirPods case(就上面那個方形小盒子),約不到15分鐘就充超過一半了。充滿一次可以聽大概5個小時。實際使用上跟官方給的數據都很相近。自己用起來完全不擔心缺電。
這個就不用太在意吧,音樂是自己在聽的,而且也不是什麼新設計,就是之前有線的長相呀,只是沒有線。真的很在意的就等多一點人戴再買吧,哈哈。按照官網購買要排到6個禮拜後的情況,我想以後路上會很常看到的。
什麼意思勒?我帶著AirPods慢步,重訓(有時需要躺著),出門坐捷運加上走一大段路,尖峰時刻搭捷運有時難免跟路人碰撞,以上情況都沒有掉過!有線的反而常常搭捷運太擠線勾到還會被扯掉。
唯獨有一次搭客運睡著頭往一邊肩膀倒,然後客運晃阿晃抖阿抖的,那邊的AirPods就掉了…嚇出一身冷汗,還好那天穿帽T醒來之後AirPods還在我肩膀上。所以,如果你快睡著又剛好身體會晃來晃去就要注意一點了。
如果你同時有Macbook, iPhone, iPad,而且都使用同一個有線耳機,常常插拔真的頗麻煩。AidPods只要Device都使用同一個Apple ID,每個裝置都不用再額外配對就可以很快速的連接上你的AirPods。
我常常很賭爛Macbook上的耳機孔,真的很難拔,常常只是要上個廁所我就要拔下來再插上手機,回到座位上又要Repeat這個動作。有了AirPods之後就超方便的,只要手機帶著就自動會有AirPods選項讓你選,點一下就切換到手機上了。
使用下來真的沒有感受到什麼缺點,對比有線耳機只有更方便更智慧的感受。真要說的話就是AirPods上面沒有按鈕可以按,也就是說沒有傳統有線上的上下首與大小聲按鈕。AirPods現在只能感應點兩下這個動作,點兩下來叫出Siri或是點兩下暫停/播放。
雖然說是缺點但我的習慣是出門手上都會拿著耳機,基本上手機不離身,所以要上下一首或調音量,把畫面喚醒就可以直接操作了,實際使用上其實也沒有感覺到不便。
毆對了!還有價錢。5000多大洋就是考驗每個人用錢價值觀的時刻了。上面舉了那些優點還有缺點,我只能說差不多的錢就功能上還有方便性智慧性等,目前市面上我認為還沒有競爭對手。
對我來說,耳機是我每天必用到的東西,如果每天都能少那麼一點煩惱,比如花時間解開那一坨線, 插拔的動作, 有時會扯到, 原廠有線用久其實真的很容易接觸不良還是要買新的等等,加上上面提的優點,OK 我買單。
我不算盲目的果粉,近期Apple的產品包含iPhone 7跟新Macbook如果有人詢問我意見我都會叫他們再等等,但這個AirPods真的很推,Apple近期難得好作品,預算夠我都會推薦買Der~。
]]>iOS版YouTube把Tabbar加上去了。前陣子流行的各種想取代Tabbar導航方式的方案又改回來了。
Tabbar是固定出現在下面的(除了播放影片時)。而看了些文章,最主要還是用戶真的太太太太懶,多一丁點步驟都懶得按,所以就乾脆固定在那裡。這樣努力做的各種功能的使用率比較高!
不過Uber是個有趣的例子!Uber用漢堡是因為其他功能的點擊率高不是goal,所以可以用Hamburger menu。
Youtube跟Spotify決定從原本側邊欄轉移到Tabbar都是因為測過A/B Testing,用結果數字來說話。
這其實也牽扯到如何設計A/B Testing?一個APP最關鍵的不是他介面看起來炫不炫,而是最終用戶能不能持續地用你想讓他用的功能。記住If ,Then ,Because___.
如果你的變因錯誤的把畫面好看當成目標,那你甚至會覺得隨著畫面滾動把Tabbar隱藏起來是好的。那這樣一來或許畫面變好看,可是面積變多,但你APP整體功能使用率是下降的。
]]>