<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blog | Chia-An Lee</title><link>https://calee0219.github.io/blog/</link><atom:link href="https://calee0219.github.io/blog/index.xml" rel="self" type="application/rss+xml"/><description>Blog</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>en-us</language><copyright>©</copyright><lastBuildDate>Sun, 24 Aug 2025 08:18:29 +0800</lastBuildDate><image><url>https://calee0219.github.io/media/icon_hu_da05098ef60dc2e7.png</url><title>Blog</title><link>https://calee0219.github.io/blog/</link></image><item><title>倫敦/倫敦近郊冰場</title><link>https://calee0219.github.io/blog/london_ice_rink/</link><pubDate>Sun, 24 Aug 2025 08:18:29 +0800</pubDate><guid>https://calee0219.github.io/blog/london_ice_rink/</guid><description>&lt;p&gt;全年&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Queen House:
&lt;/li&gt;
&lt;li&gt;Lee Valley:
&lt;/li&gt;
&lt;li&gt;Alexandra Palace:
&lt;/li&gt;
&lt;li&gt;Streatham Ice and Leisure Centre:
&lt;/li&gt;
&lt;li&gt;Planet Ice Gosport:
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;冬季&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Winter wonderland:
&lt;/li&gt;
&lt;li&gt;Somerset House:
&lt;/li&gt;
&lt;li&gt;Battersea power station:
&lt;/li&gt;
&lt;li&gt;Hanover Square:
&lt;/li&gt;
&lt;li&gt;Canary Wharf:
&lt;/li&gt;
&lt;li&gt;Hampton Court:
&lt;/li&gt;
&lt;li&gt;Westfield:
&lt;/li&gt;
&lt;li&gt;Skylight:
&lt;/li&gt;
&lt;li&gt;National History Museum:
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>愛的迫降 蘇黎世 拍照位置</title><link>https://calee0219.github.io/blog/crash_landing_on_you_zurich_location/</link><pubDate>Wed, 28 Aug 2024 08:18:29 +0800</pubDate><guid>https://calee0219.github.io/blog/crash_landing_on_you_zurich_location/</guid><description>
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;聲明：本人沒有看過愛的迫降，純粹由於這次去蘇黎世玩，旅伴要求下覺得很有趣，就紀錄了一下可能的拍攝位置&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="建議路線時間"&gt;建議路線、時間&lt;/h2&gt;
&lt;p&gt;時間安排上建議夏天早上六點半七點左右出發，這個時間還沒有什麼人又有光線是最好拍照的時間&lt;/p&gt;
&lt;p&gt;路線安排上如果從 Zurich HB 車站出發，可以沿著河岸小路走到 Lindenhof 觀景台，在下山沿著河岸走到 Münsterbrücke 大教堂橋，反之亦可&lt;/p&gt;
&lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Google_Map_Path.png" width="30%"&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;h2 id="車站"&gt;車站&lt;/h2&gt;
&lt;p&gt;Zurich HB 外面的電車總站有一張，但由於我沒有時間因此沒拍，應該就是等到 2 號電車來就可以拍到&lt;/p&gt;
&lt;p&gt;&lt;img src="https://live.staticflickr.com/65535/49649958526_05ce918c59_h.jpg" width="65%"&gt; &lt;img src="https://live.staticflickr.com/65535/49638676148_ec45f0081d_h.jpg" width="30%"&gt;&lt;/p&gt;
&lt;h2 id="坐河邊"&gt;坐河邊&lt;/h2&gt;
&lt;p&gt;首先來到女主坐在河邊的點
，拍照點大概在往河看右邊數來第二個長椅前後，要稍微開長焦特寫人像，對準後面黃色與紅色建築物中間的鴨鴨藍旗，大概拍攝者相對位置&lt;/p&gt;
&lt;p&gt;&lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Sit_Beside_River_1.jpeg" width="20%"&gt; &lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Sit_Beside_River_2.jpeg" width="20%"&gt;&lt;/p&gt;
&lt;p&gt;建築物兩邊都抓到，高度留四層樓，石板留三格，大概長這樣子&lt;/p&gt;
&lt;p&gt;&lt;img src="https://live.staticflickr.com/65535/49639477182_c08c0dc054_h.jpg" width="45%"&gt; &lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Sit_Beside_River.jpeg" width="45%"&gt;&lt;/p&gt;
&lt;h2 id="觀景台"&gt;觀景台&lt;/h2&gt;
&lt;p&gt;然後往上走到觀景台
，這裡可以抓到三張照片&lt;/p&gt;
&lt;p&gt;其中一張是劇照，被拍攝者要大概站在最右邊的長椅的左後方，相手需要蹲下，大概在噴水池與小房間中線再往後走&lt;/p&gt;
&lt;p&gt;&lt;img src="https://live.staticflickr.com/65535/49639199796_c09567ebd7_h.jpg" width="45%"&gt; &lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Main_Picture.jpeg" width="45%"&gt;&lt;/p&gt;
&lt;p&gt;相手相對位置&lt;/p&gt;
&lt;p&gt;&lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Main_Picture_1.jpeg" width="20%"&gt; &lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Main_Picture_2.jpeg" width="20%"&gt;&lt;/p&gt;
&lt;p&gt;第二張是女主單人照，老實說我忘記有這張了，不過剛好有一張路人照有接近，借來一用 (BTW，這就是下午去了話人潮的樣子)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://live.staticflickr.com/65535/49638675533_b160cbba59_h.jpg" width="40%"&gt; &lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Single_Girl_Standing.jpeg" width="45%"&gt;&lt;/p&gt;
&lt;p&gt;第三張是全景照&lt;/p&gt;
&lt;img src="https://live.staticflickr.com/65535/49649928586_78b7d19a4f_h.jpg" width="95%"&gt;
&lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Full_View.jpeg" width="95%"&gt;
&lt;p&gt;拍攝者大概要站在噴水池後面第一個圓點點旁邊&lt;/p&gt;
&lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Full_View_1.jpeg" width="20%"&gt;
&lt;h2 id="大教堂橋"&gt;大教堂橋&lt;/h2&gt;
&lt;p&gt;大教堂橋也可以拍到三張照片&lt;/p&gt;
&lt;p&gt;首先，拍攝者不要上橋，大概在 ROSE &amp;amp; BORN 門口旁邊的水溝蓋
&lt;/p&gt;
&lt;p&gt;&lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Beside_The_Bridge_1.jpeg" width="20%"&gt; &lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Beside_The_Bridge_2.jpeg" width="20%"&gt; &lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Beside_The_Bridge_3.png" width="50%"&gt;&lt;/p&gt;
&lt;p&gt;請被攝者站在右邊數來第二座路燈旁邊，這張照片需要開超長焦鏡，讓路燈剛好放在後面教堂第四根柱子前面，人則是要站在第二根柱子下面，下面記得要留下一線橋墩&lt;/p&gt;
&lt;img src="https://www.swisseducation.com.hk/wp-content/uploads/2020/03/158201616678602500_a580xH.jpg" width="95%"&gt;
&lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Beside_The_Bridge.jpeg" width="95%"&gt;
&lt;p&gt;第二張是站在橋上，往蘇黎世湖的方向拍攝，此時拍攝者大概站在第二根路燈的右側
&lt;/p&gt;
&lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_On_The_Bridge_1.jpeg" width="20%"&gt;
&lt;p&gt;拍攝過程中要留下左側建築物的一根塔樓，以及右側建築物的全貌，而被攝者則是站在路橋對面，動作隨意&lt;/p&gt;
&lt;img src="https://live.staticflickr.com/65535/49649928241_8f8936be7c_h.jpg" width="95%"&gt;
&lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_On_The_Bridge.jpeg" width="95%"&gt;
&lt;p&gt;最後一張圖也是另一個雙人劇照，拍攝者大概在靠蘇黎世大教堂與蘇黎世湖側橋尾
，拍攝時需要注意左側路燈第三根 (最靠近者) 的燈罩頂大概遮住 7 的位置 (我的位置還是太高了)，右邊建築物至少要流出一個天窗&lt;/p&gt;
&lt;p&gt;&lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Church_1.jpeg" width="40%"&gt; &lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Church_2.jpeg" width="20%"&gt;&lt;/p&gt;
&lt;p&gt;被攝者兩人站中間，有下往上的視角拍攝&lt;/p&gt;
&lt;p&gt;&lt;img src="https://live.staticflickr.com/65535/49639201186_f69336b6d5_h.jpg" width="45%"&gt; &lt;img src="https://calee0219.github.io/img/Zurich_Crash_Landing_On_You_Church.jpeg" width="45%"&gt;&lt;/p&gt;</description></item><item><title>倫敦旅遊建議</title><link>https://calee0219.github.io/blog/london_trip_advice/</link><pubDate>Sat, 20 Jul 2024 08:18:29 +0800</pubDate><guid>https://calee0219.github.io/blog/london_trip_advice/</guid><description>&lt;p&gt;
&lt;/p&gt;
&lt;h2 id="安全"&gt;安全&lt;/h2&gt;
&lt;p&gt;倫敦治安算是歐中大城市中上等級，基本上不太需要擔心太多扒手或搶劫，更不用擔心槍擊，但不要跟亞洲比，基本的不要走路滑手機 (可能會有
搶手機)、個人物品不要離開視線、包包拉鍊拉好等，基本上就夠用。唯一有可能的例外是無差別恐怖攻擊，畢竟是國際化大都市，還是會稍有耳聞。&lt;/p&gt;
&lt;p&gt;比較常見的糟糕事情基本上有屁孩/醉漢，只要不理他並且不要太畏縮(像是可以比個中指)都應該不太會被纏，另外一個常見的手法是會在比較擁擠的餐廳，跑來跟你推銷或講奇怪的話，用手上的報紙/傳單/書蓋著你放在桌上的手機再把它順走，所以比較保險還是不要把手機放在餐桌上。在高一點是飛車族，如果你走在路上太靠馬路並邊走邊滑手機，有機會被飛車族搶手機。另外一個觀光客大概不會遇到的是偷腳踏車，基本上這邊腳踏車放在外面超容易被偷 =.=。&lt;/p&gt;
&lt;p&gt;如果真的遇到事情，第一件事請趕快大聲用英文叫出來，讓周圍的人知道發生搶案/偷竊，還是會有熱心的人幫忙阻攔的 (如果做得到)。&lt;/p&gt;
&lt;p&gt;至於晚上的部分，對我來說我會說倫敦的夜晚還是很安全，我常常十一二點才回家也覺得還好，不過由於北/西倫敦刻板印象上是治安比較好，比較無聊，適合養老的地方，所以可能比較安全，東倫敦給我的感覺比較年輕活潑，是比較適合年輕人生活的地方，但我還是會覺得也是安全的，個人只有覺得南倫敦可能是相對最亂的地方，至於有沒有到不安全我就不敢講了，不過基本觀光客也不會到南倫敦。&lt;/p&gt;
&lt;h2 id="消費"&gt;消費&lt;/h2&gt;
&lt;p&gt;基本上信用卡金融卡都吃，公車/地鐵/陸鐵/(倫敦內)火車都可以直接刷卡進出站，九成九機率不需要現金，唯一機率需要現金的是路邊攤或想逃稅的店家，或是有都收但是現金會比較便宜的狀況 (尤其在 China Town，那邊 ATM 會很熱門)，因為英國的 VAT 20%。&lt;/p&gt;
&lt;p&gt;另外這邊可以刷卡的地方基本上也都可以 Apple Pay / Google Pay，aka 九成九的消費都可以數位支付。&lt;/p&gt;
&lt;p&gt;不過要注意的是，相對於美國，可能會有約四成的商家不收 Amex 因為手續費相對 master / visa 高。&lt;/p&gt;
&lt;h2 id="購物"&gt;購物&lt;/h2&gt;
&lt;p&gt;如果想要找 Outlet 買便宜精品，最有名的可以坐一個小時火車到 Bicester Village Outlet。除此之外，
有提到五家 outlet，除此之外我另外知道有 Bettersea Power Station 是最近開放的新購物商場，另外也有 Wembley Stadium 旁邊的 Designer Outlet。&lt;/p&gt;
&lt;p&gt;如果想買精品了話可以沿著 Regent Street 跟 Oxford Street 走，這兩條街是有名的各種看過跟沒看過的精品，另外 New Bond St 沿路也有個家我比較看得懂的精品品牌。&lt;/p&gt;
&lt;p&gt;如果想找 Shopping Mall，最有名的不外乎 Harrods, Liberty, Selfridges 三家，另外 One New Change 跟 Covent Garden 也可逛逛。&lt;/p&gt;
&lt;h3 id="茶"&gt;茶&lt;/h3&gt;
&lt;p&gt;如果要買茶觀光客首推 Fortnum &amp;amp; Mason，這家是皇室專供的唯一品牌，另外也可以考慮 Whittard of Chelsea 跟 The East India Company (曾經佔領過台灣（好啦不是同個國家的）並且造成美國獨立的公司還存在，不覺得很屌嗎？)。&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;h2 id="交通"&gt;交通&lt;/h2&gt;
&lt;h3 id="地鐵"&gt;地鐵&lt;/h3&gt;
&lt;p&gt;倫敦內部的大眾運輸系統是統一由 TfL (Travel for London) 來管轄，包含 underground, overground, bus, tram, DLR, National Railway, river boat 等等。&lt;/p&gt;
&lt;p&gt;可能會有很多人聽說 Oyster Card，但是身為觀光客請不用額外買 Oyster Card，因為 Oyster 只能在倫敦內使用 (TfL 系統)，而且能用 Oyster 的地方現在全部都能用信用卡/金融卡/apple pay/google pay 了，而且票價也完全一樣，因此並沒有需要另外買 Oyster。&lt;/p&gt;
&lt;p&gt;倫敦的地鐵有幾種不同的票種：
如果一天不會做幾次，最簡單的就是 pay as you go，是以 zone 幾 做到 zone 幾來算價格的，單程計算，舉例來說 zone 1 到 zone 1 是離峰時段是 2.7，尖峰時段是 2.8，可以在這個
上查詢，另外每天有金額上限，刷超過金額就不會另外扣款，另外每週也有金額上限，以 zone 1 到 zone 1 來說是每天是 8.1，每週是 40.7，在這個
上可以查詢。
尖峰時刻基本上是上下班時間，日一到五早上 6:30 到 9:30 以及下午 16:00 到 19:00。&lt;/p&gt;
&lt;p&gt;Ref:
&lt;/p&gt;
&lt;p&gt;另一種方式是購買日票/週票，基本上也是以 cover 的 zone 來買，不過細節我就不太了解了&lt;/p&gt;
&lt;p&gt;
是指特定幾條禮拜五跟禮拜六會開 24 hr 的地鐵，除了這段時間外，其他營運時間所有地鐵都一樣從早上五點開到半夜十二點，另外 Northen Line 的 Night Tube 只有開 Charing Cross 一條，沒有開 Bank。
如果沒有地鐵回家，公車通常會運營的比較晚一點，最不行就只好叫 Uber 或 Bolt 了，可以比價看看．&lt;/p&gt;
&lt;h3 id="火車"&gt;火車&lt;/h3&gt;
&lt;p&gt;倫敦內部的火車也歸 TfL 管，所以可以直接用信用卡 (Oyster 系統) 進出站，計價方式與 underground 相同，然而如果不小心坐出倫敦被查票到，可能會被要求補票+罰款。&lt;/p&gt;
&lt;p&gt;由於英國的火車是由多家公司分別運營再由市場競爭，可以用用 Trainline APP 統一資訊買票，不過下單的時候會收些微手續費，如果想省錢可以看好最便宜的票後，在下載當個公司的 app 買票。&lt;/p&gt;
&lt;h3 id="機場路線"&gt;機場路線&lt;/h3&gt;
&lt;p&gt;基本上遠東的觀光客應該都是由希斯洛機場出入，可搭乘 Heathrow Express 至市區，應為除計程車外最快之選項，然而要價不菲。近年來 Elizabeth Line 啟用後，由於所需時間僅慢 Express 些許，為最推薦經濟實惠的做法，僅需小心不要被工作人員趕上 Express 的月台即可。另外也可搭 Piccadilly Line 慢慢悠悠地晃到市區。&lt;/p&gt;
&lt;h3 id="罷工"&gt;罷工&lt;/h3&gt;
&lt;p&gt;歐洲勞權意識高漲 (which is good)，勞工對於自己的權利很願意站出來發聲，因此常常會有罷工，基本上每週五 TfL 就會寄信給大家 (if subscribe) 週末交通建議，基本上就是告知哪些地鐵線週末有罷工。不過地鐵的罷工還好，通常會是幾個車站沒開而已，但火車的罷工就比較麻煩，會減少當條線的數量，所以如果要坐火車最好先查好有沒有罷工，如果有了話，有留哪幾個 slot 還會發車。&lt;/p&gt;
&lt;p&gt;至於今年七八月的機場罷工，這次聽說是海關人員而非地勤，因此應該會在出入關上排比較多人，建議要出關時多留一點時間去排隊，入關就沒有辦法了。(有在社團裡看到政府會請軍隊幫忙分擔一些 loading)&lt;/p&gt;
&lt;h2 id="飲食"&gt;飲食&lt;/h2&gt;
&lt;p&gt;傳統英國食物可以找
Fish &amp;amp; Chips -&amp;gt; 去 Bath 吃
Sunday Roast -&amp;gt; The Ship Tavern
Afternoon tea -&amp;gt; F&amp;amp;M
Full English brackfast -&amp;gt; ???
烤鹿肉 -&amp;gt; The Pig and Butcher (季節菜)&lt;/p&gt;
&lt;h3 id="copy-from-craig"&gt;Copy from
&lt;/h3&gt;
&lt;p&gt;(標題連結還有其他地區的地圖，這邊只取倫敦部分供參考)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
:
&lt;/li&gt;
&lt;li&gt;Day2 walk:
&lt;/li&gt;
&lt;li&gt;Day3 walk:
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="茶-1"&gt;茶&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Fortnum and Mason - 皇室專供茶的噱頭，也可以去吃貴森森七十幾鎊吃到飽的下午茶&lt;/li&gt;
&lt;li&gt;Whittard of Chelsea - 台灣也有分店，應該算是最有名的英國茶品牌 (?)&lt;/li&gt;
&lt;li&gt;The East India Company - 他家的伯爵茶爆幹好喝&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ref:
&lt;/p&gt;
&lt;h2 id="旅遊"&gt;旅遊&lt;/h2&gt;
&lt;h3 id="看劇"&gt;看劇&lt;/h3&gt;
&lt;p&gt;倫敦跟紐約應該算是全世界最多藝術匯集的地方，蠻推薦來的時候可以嘗試看看音樂劇 (歌劇或交響會歐陸也有很多，而且價格應該會比倫敦便宜)&lt;/p&gt;
&lt;p&gt;如果要訂票，可以用以下幾個平台來訂，越早訂不太會比較便宜，但有比較多好位置可以選，另外每天早上十點 TodayTix 上有當天的 Rush Ticket 可以抽，可以用比較便宜的價格買到隨機的座位&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Todaytix&lt;/li&gt;
&lt;li&gt;TicketMaster&lt;/li&gt;
&lt;li&gt;TicketShare (二手票)&lt;/li&gt;
&lt;li&gt;Theatre Monkey (看每個劇院要選什麼座位比較好)&lt;/li&gt;
&lt;li&gt;官網&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一些個人推薦或想看的音樂劇&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Phantom of the Opera&lt;/li&gt;
&lt;li&gt;Les Misérables&lt;/li&gt;
&lt;li&gt;Book of Mormon&lt;/li&gt;
&lt;li&gt;Hamilton&lt;/li&gt;
&lt;li&gt;The Lion King&lt;/li&gt;
&lt;li&gt;Mamma Mia&lt;/li&gt;
&lt;li&gt;Frozen&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;BTW, 紐約的歌劇魅影常設已經關了，倫敦的明年也會關，可以把握幾會看 (還是會有巡迴)&lt;/p&gt;
&lt;h3 id="博物館美術館公園"&gt;博物館/美術館/公園&lt;/h3&gt;
&lt;p&gt;英國很讚的是大多數的博物館/美術館都是免費的，只有特展需要花錢，蠻推薦多去參觀各種博物館美術館的，另外這邊的公園也是免費的 (廢話)，天氣好時會有很多人在公園曬太陽，可以買點啤酒點心到公園，享受看看歐洲公園的氛圍&lt;/p&gt;
&lt;h3 id="導遊"&gt;導遊&lt;/h3&gt;
&lt;p&gt;我是都沒有跟過，不過網路上比較活躍的
Craig 有一起喝過酒一次，人感覺蠻 Nice 的，給的旅遊建議也都很實用&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="london-pass"&gt;London Pass&lt;/h3&gt;
&lt;p&gt;還沒買過
~~ Welcome to contribute ~~&lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;</description></item><item><title>PPPoE Line 無法連線問題</title><link>https://calee0219.github.io/blog/network_tcp_mss/</link><pubDate>Thu, 08 Sep 2022 08:46:29 +0800</pubDate><guid>https://calee0219.github.io/blog/network_tcp_mss/</guid><description>&lt;p&gt;由於曾經想把家中的 NAT gateway 全部放到 Linux server 上，做包含
、NAT、與 DHCP 的工作，同時可以自由地記憶 mac address、下 firewall 規則、架設 web proxy server 等，不需要再過小烏龜與它家 NAT 打 port forwarding，因此著手了建置。&lt;/p&gt;
&lt;p&gt;在完成 PPPoE 建置後，詐用之下並沒有什麼太大的問題，然而偶有新建立連線時速度較慢的問題。一開始我並不太在意，然而當家人反映 Line 在 wifi 下無法正常傳送訊息，只有在 LTE 網路下才可以時，便發現好像真的是我的網路架設有問題。&lt;/p&gt;
&lt;p&gt;在確認 LINE 的網頁也觸及不到後，便方便確定可以直接用 LINE 網站當 debug target。在觀察問題時發現如果使用 Linux 軟撥接，封包會止步於東京的 Router (使用 traceroute 或 mtr 測試)，但如果使用小烏龜硬撥接在過東京之後也沒有回復，但 LINE 網頁是可以 access 的，因此懷疑 LINE server 只是沒有開 ICMP response。&lt;/p&gt;
&lt;p&gt;接著試著用 tcpdump 把封包抓出來檢查，比較軟撥接與硬撥接封包差異，看起來似乎只差在軟撥接封包 MTU 為 1492，為了增加 8 byte 的 PPPoE header，而硬撥接莫名的可以放 1500 (也許上面的機器 MTU 有開超過 1500)，理論上 MTU 只有過大才會有問題，太小應該只會有效能問題而已。&lt;/p&gt;
&lt;p&gt;而後繼續細看 TCP 的封包內容，看起來硬撥接時可以做完完整的 handshark，可是軟撥接時只能做到 server hello，所以代表其實封包是有送到 LINE 的 server 上，只是在三方交握時莫名的被拒絕，而又觀察 header 內容，會發現 server hello 的 sequence number 會出錯，除錯到此懷疑要馬是 MTU 的問題，要馬就是 TCP 的問題，然而就是想不出到底 root cause 在哪。&lt;/p&gt;
&lt;p&gt;在走投無路下，嘗試詢問在 AWS 工作的大神學弟，結果學弟一比較之下馬上跟我講原因。原來是 TCP MSS 的問題，在 TCP header 裡面會有一個 MSS (maxiumu segment size) 用來告知兩端該放多少 size 的 payload。在連線到一般的 server 時由於兩方都沒有要交換的 MSS，因此照著 MTU 的大小放多可以正常工作，可是當其中一端有要求 MSS (像是 LINE server) 可是另外一端沒有時，就會以 MSS 的大小放置 payload，而常見的 MSS 是 1460 (1500 (MTU) - 40 (IP/TCP header))，然後懷疑由於 LINE 沒有開 ICMP 功能因此無法透過 Path MTU Discovery (PMTUD)，又有手動塞 MSS 1460，然而 client 又不會跟其溝通，因此永遠用大於可接受的封包大小傳送資料。&lt;/p&gt;
&lt;p&gt;解決方法是要嘗試讓 server 知道 MSS 要變小，並且我需要在 gateway (NAT server) 上設定，而不是在 client 上一台一台設。Linux 上常見做法有兩種，一種做法是在防火牆上下規定 TCPMSS: &lt;code&gt;iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN- j TCPMSS --set-mss 1452&lt;/code&gt; (1452 = 1500 - 8 PPPoE header - 40 IP/TCP header)，然而我的防火牆是用 firewalld 設定，不管寫 iptables 或寫 firewalld 例外規定都感覺很彆扭，因此用第二種作法在 route 上面設定 advmss: &lt;code&gt;ip route add default dev ethX mtu 1492 advmss 1452&lt;/code&gt;，後來發現如果改用 network-scripts 設定 PPPoE 可以直接有 &lt;code&gt;CLAMPMSS=1452&lt;/code&gt;，所以就改用 network-scripts 的設定方式了。BTW 我看網路上很多人都把 CLAMPMSS 設定成 1412，不過好像是 PPPoE 有不同種長度的 header (?)。&lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Linux PPPoE 設定</title><link>https://calee0219.github.io/blog/network_linux_pppoe/</link><pubDate>Wed, 07 Sep 2022 08:46:29 +0800</pubDate><guid>https://calee0219.github.io/blog/network_linux_pppoe/</guid><description>&lt;p&gt;Linux 在 PPP (Point to point protocol) 上面有不同種類的設定方法，不同 OS 也會習慣用不同的 package，由於我是用 CentOS，因此主要是查 CentOS 的 PPPoE 設定方法&lt;/p&gt;
&lt;h2 id="nmcli"&gt;nmcli&lt;/h2&gt;
&lt;p&gt;其中一個常見的方法是用 nmcli 來設定&lt;/p&gt;
&lt;h3 id="常用指令"&gt;常用指令&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli device &lt;span class="c1"&gt;# (或者只打 d，如果 prefix match 的到唯一 nmcli 就知道是什麼指令)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connect
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli connect up/down/reload XXX &lt;span class="c1"&gt;# 接 connection name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli c add/delete/edit XXX &lt;span class="c1"&gt;# edit 會進入互動模式，個人習慣在互動模式下修改比較簡單，不確定關鍵字也可以自動補全&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 在互動模式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli&amp;gt; print &lt;span class="c1"&gt;# 印出設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="作法"&gt;作法&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo yum install rp-pppoe &lt;span class="c1"&gt;# 需要先安裝相關的 package&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli c edit &lt;span class="nb"&gt;type&lt;/span&gt; pppoe con-name &lt;span class="s2"&gt;&amp;#34;ppp0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli&amp;gt; &lt;span class="nb"&gt;set&lt;/span&gt; pppoe.username &lt;span class="nv"&gt;$USER&lt;/span&gt; &lt;span class="c1"&gt;# 接中華給的號碼 @hinet.net (如果是 @hinet.net 是浮動 IP，@ip.hinet.net 是固定 IP)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli&amp;gt; &lt;span class="nb"&gt;set&lt;/span&gt; pppoe.password &lt;span class="nv"&gt;$PWD&lt;/span&gt; &lt;span class="c1"&gt;# 設定中華給的密碼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli&amp;gt; &lt;span class="nb"&gt;set&lt;/span&gt; pppoe.autoconnect yes &lt;span class="c1"&gt;# 自動連接&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli&amp;gt; save
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nmcli&amp;gt; quit
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli c up ppp0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="network-script"&gt;network-script&lt;/h2&gt;
&lt;p&gt;然而因為
，nmcli 的設定沒有我需要的參數，因此後來改用 network-script 的方式設定，方法如下&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;先下載所需要的 package&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo yum install ppp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo yum install NetworkManager-ppp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;/etc/sysconfig/network-scripts/&lt;/code&gt; 下新增檔案 &lt;code&gt;ifcfg-ppp0&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;DEVICE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ppp0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;TYPE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xDSL
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;ONBOOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yes &lt;span class="c1"&gt;# 開機開啟&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;PIDFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/var/run/pppoe-adsl.pid &lt;span class="c1"&gt;# 設定 pid 檔案位置，也可以放在其他地方或不寫&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;FIREWALL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;NONE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;PING&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;PPPOE_TIMEOUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;LCP_FAILURE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;LCP_INTERVAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;CLAMPMSS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1412&lt;/span&gt; &lt;span class="c1"&gt;# 設定 TCP MSS 可以不寫，不過遇到 G8 網站了話會需要用其他例如 iptables 的方式處理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;CONNECT_POLL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;CONNECT_TIMEOUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;60&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;DEFROUTE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yes &lt;span class="c1"&gt;# 是否要成為 default route&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;SYNCHRONOUS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;no
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;ETH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;eth1 &lt;span class="c1"&gt;# bind interface&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;PROVIDER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;DSLppp0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;72920266@ip.hinet.net &lt;span class="c1"&gt;# 帳號 (@ip.hinet.net 是固定 IP 需要網頁上些設定，@hinet.net 是浮動 IP)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;PEERDNS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;no
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;DEMAND&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;no
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# IPv6 設定，不需要了話也可以不用設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;PPPD_EXTRA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ipv6 ,&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;IPV6INIT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;IPV6_AUTOCONF&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;yes&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;IPV6_DEFROUTE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;yes&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;IPV6_FAILURE_FATAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;no&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;IPV6_ADDR_GEN_MODE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;stable-privacy&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;IPV6_PRIVACY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;yes&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;IPV6_AUTOCONF&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;yes&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#IPV6PPPAUTOCONF=yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然後在 &lt;code&gt;/etc/ppp/&lt;/code&gt; 資料夾下寫入密碼相關設定&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pppoe-server-options&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;require-pap
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;login
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lcp-echo-interval &lt;span class="m"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lcp-echo-failure &lt;span class="m"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;chap-secrets&lt;/code&gt; 跟 &lt;code&gt;pap-secrets&lt;/code&gt; 都寫上 (不過我覺得感覺只要寫 pap 就好)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;USERNAME&amp;#34;&lt;/span&gt; * &lt;span class="s2"&gt;&amp;#34;PWD&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>倫敦 Meta 旅記</title><link>https://calee0219.github.io/blog/2022_meta_london_trip/</link><pubDate>Wed, 24 Aug 2022 08:18:29 +0800</pubDate><guid>https://calee0219.github.io/blog/2022_meta_london_trip/</guid><description>&lt;p&gt;本篇主要是希望可以幫助尚未決定是否要出國工作的朋友，或已經簽好 offer 需要準備出國工作的一些行前準備紀錄。
同時對於經濟狀況比較差的朋友，也可以藉此衡量如果畢業即想出國工作，需要預先存多少錢 (希望看了之後可以大幅提高意願，我認為預支花費比我想像中的少)。&lt;/p&gt;
&lt;p&gt;另外敝司 (Meta) 最近重新開缺了，如果有看到有興趣的職缺，歡迎準備英文姓名、email、CV，可以找我 reference，另外我會希望能跟您約個 con-call 認識一下~ 🤗&lt;/p&gt;
&lt;h2 id="拿到-offer-後"&gt;拿到 Offer 後&lt;/h2&gt;
&lt;p&gt;在拿到口頭 Offer 後，recruiter 會希望在一個禮拜內回覆是否接受，如果接受需要提供地址 (應該是要寫在 offer letter 上) 與預期的上工日，我原本回復想說跟學生一樣九月上工，不過 recruiter 看到後回覆我簽證弄一弄平均大概要 12 周左右所以幫我訂在十月。&lt;/p&gt;
&lt;p&gt;接下來需要上 Meta career 網站填寫一些入職資訊，包含&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;簽一系列的 Offer 文件，包含像是 offer letter、FTC Acknowledgement、On-Boarding 之類的。&lt;/li&gt;
&lt;li&gt;進行背景省查，這部分 Meta 委託第三方公司 (HireRight) 進行，需要一段時間。這部分比較花時間，會需要上傳畢業證書、成績單等，最好中英文都申請，之後 HireRight 會與學校來回確認。我是 6/28 送出第一份資料，中間經過了一些資料來回確認、文件補件之類的流程，大概在 7/5 完成檢查。&lt;/li&gt;
&lt;li&gt;上傳入職文件，這部分比較特別的是 P45，這份文件是如果你有在英國工作的經驗，需要跟前一家公司拿 P45 文件，好像是用來驗證接下來這年的報稅文件。不過身為新人還是海外工作者應該是沒有所以就直接選沒有。&lt;/li&gt;
&lt;li&gt;給公司你的 FB 帳號，這個帳號會跟工作帳號連動，我後來才知道有些人會特別開一個工作用帳號提交。&lt;/li&gt;
&lt;li&gt;選擇 username，這部分會成為之後工作的信箱 prefix 並且不能跟別人重複，由於我的慣用 ID 被用過了，我花蠻多時間想一個新的說。&lt;/li&gt;
&lt;li&gt;選擇你想要的設備，筆電與手機，有手機其實還蠻讓我意外的。&lt;/li&gt;
&lt;li&gt;提供設備送到的地址，由於需要當地的地址，所以要過去之後才能填寫。&lt;/li&gt;
&lt;li&gt;提供你的員工資料，包含姓名、生日、國民狀態、國籍等等，以及聯絡資料 (給當地的，還沒到填寫辦公室地址)，另外比較特別的是要提供 NINo，不過一樣沒到當地先流空。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="簽證"&gt;簽證&lt;/h2&gt;
&lt;p&gt;由於我的護照剛好過期，所以我有先去台北外交部領事事務局更新護照。過程先在網路上預約並填寫資料，然後帶著身分證、兩吋大頭照兩張、舊護照、與護照資料表正本過去，更新手續費花了 1300 元，另外有額外花 120 郵寄護照。&lt;/p&gt;
&lt;p&gt;簽證的部分 Meta 是委託 Deloitte 幫忙處理，會是 Tier 2 D-type Skilled-worker visa，大約在接受 offer 後幾天 Deloitte 就會系統發信來請你上他的網站註冊帳號，並約第一次與 agent 遠端開會來確認事宜。&lt;/p&gt;
&lt;p&gt;Concall 大概告知接下來的流程以及跟你確認一些資訊，其中我最驚訝的是去英國要考過英文檢定 (我白目之前不知道)。之後 Deloitte 就發信提醒你，其中有三個重點，&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;上 Deloitte 網站上傳資料 (護照、CV、以及 UKVI 的英文檢定)&lt;/li&gt;
&lt;li&gt;二是要考有 UKVI (UK Visas and Immigration) 認證的英文檢定 (雅思、LanguageCert 或 PTE)，分數要超過 B1 的門檻 (雅思四分)，並且聽說讀寫都要有，另外如果之前不是考 UKVI 了話可能要重考。&lt;/li&gt;
&lt;li&gt;上英國政府網站填寫 Visa Application Form，這部分會提供一個有 cookie 的連結網址，直接使用他提供的網址填寫&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我大概在考雅思的部分卡了一點時間，我是 7/4 concall 並得知要考檢定，然後預約了 7/16 的考試，其實原本有 7/13 的考試可以約不過由於擔心沒準備考不過，所以想說多準備一點，事後事實證明我還是沒啥準備裸考幸運過了，另外考雅思花費 7900，不過可以事後與 Relocation Benefit 報銷。
大概到 7/20 我才拿到雅思成績並且繼續填寫 Visa Application Form (因為其中一項有問有沒有考過)，7/22 完成所有文件上傳與填寫，便等待 Deloitte 的後續結果。&lt;/p&gt;
&lt;p&gt;當 Deloitte 都弄好之後文件後 (8/12)，幫我預約 8/15 到 VFS 台北簽證申請中心繳交申請資料，需要帶 1. Appointment confirmation，證明你預約的是這個時段並且申請的服務 2. Document Checklist，用來確認你帶的文件 3. Online application form，就是 Visa Application Form 的最終版本，但好像最後沒用到 4. 護照 5. Certificate of Sponsorship，好像是證明有公司要你，也是唯一一個不能從 UK Visa Application Form 上下載的文件，要跟公司拿 6. 英檢成績單，大概流程&lt;/p&gt;
&lt;ol start="0"&gt;
&lt;li&gt;提早到 VFS 大廳換證上七樓&lt;/li&gt;
&lt;li&gt;等待時間到後進入辦公室，會先經過簡單的安檢並跟你確認 Appointment confirmation&lt;/li&gt;
&lt;li&gt;跟你確認身分及資料，以及你要申請的 visa 種類&lt;/li&gt;
&lt;li&gt;提供以上文件給櫃檯，專員會幫忙把文件掃描，這個服務 Deloitte 已經幫忙購買了&lt;/li&gt;
&lt;li&gt;進行生物資料採集，會拍照並收集指紋&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;由於文件掃描以及簽證費用都已經付過了，所以我只付到由於我想要護照回來時直接寄回我家的郵寄費 311 元。&lt;/p&gt;
&lt;p&gt;PS. 過程中與 Deloitte 文件交換的過程都是使用 Deloitte 的 Cobalt 網站&lt;/p&gt;
&lt;p&gt;之後護照及相關文件會被 VFS 寄送到英國移民局審查，如果遇到任何問題會 email 通知，若無便會寄回 VFS，可選擇自己臨櫃領取或直接郵寄到家原本專員預計是會花一個月到一個半月的時間，不過我在十天後就收到寄回的護照及簽證了。包裹理會包含護照及一份 A4 文件 UKVI 01，兩件都是入境時需要帶的文件，另外提醒一下簽證是指貼在護照簽證頁的一份貼紙，內容格式與護照頁類似，天真如我原本還以為簽證會是一份 A4 文件。&lt;/p&gt;
&lt;p&gt;講個笑話，由於我原本以為簽證是一份 A4 文件，同時 UKVI 01 上有特別粗體字寫 &amp;ldquo;This letter is not a permission to travel to the UK&amp;rdquo;, &amp;ldquo;Before you can travel to the UK, you will need to collect your visa&amp;rdquo;, &amp;ldquo;We will contact you when your visa is ready to collect from the visa application centre&amp;rdquo;，所以我收到包裹時還痴痴的等簽證中心聯絡，沒有主動通知 Deloitte 我拿到簽證了。是後來跟朋友聊到我還在等 visa 時，才被問說&amp;quot;不是應該已經貼在護照裡?&amp;quot; 才知道的。&lt;/p&gt;
&lt;p&gt;之後 Deloitee 要我將簽證及 UKVI 01 上傳給他們已確認是否都正確，之後便可以訂機票囉~&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;小知識1: 不像美國，英國貼在護照上的貼紙並非真正的簽證 (visa)，而是 Entry Clearance 或稱 Vignette，是一張入境許可，而申請人需要在 Vignette 有效後 90 天內入境英國並領取 BRP (Biometric Residence Permit, 生物識別居留許可)，有了 BRP 才算是真的拿到居留許可證名。&lt;/p&gt;
&lt;p&gt;小知識2: 對於 Skilled Worker 簽證，並不需要另外申請 NINo (National Insurance Number)，他會標註在 BRP 背面。NINo 尤為重要是因為你需要向雇主提供你的 NINo 才能合法工作。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;到英國後，要再去拿 BRP，才算是正式拿到 Visa，通常是去申請 Visa 時填寫的 PostOffice 拿。不過由於我是由 Deloitte 幫我申請的，到英國後 Deloitte 很快跟我聯絡，直接到他們辦公室拿就好。&lt;/p&gt;
&lt;p&gt;另外標準是建議 BRP 要保存好不要隨身帶，只有出國時回英國要帶在身上過海關，但是由於在英國買酒買刀都要出示有照片的身分證件證明年齡，在沒有其他證件的狀況下只能用 BRP 來證明。&lt;/p&gt;
&lt;h2 id="relocation-移動"&gt;Relocation (移動)&lt;/h2&gt;
&lt;p&gt;對於國外入職的員工，有些公司會提供 Relocation 的服務。以 Meta 來說有五項 Core Benefit (不用付錢，Meta 全包) 以及預算 (Meta 會給予一個金額數字) 內的 Plus Benefit (或再自費加購)。&lt;/p&gt;
&lt;p&gt;這個部分 Meta 是委託 Altair 這家公司幫忙，Altair 會在上工前 90 天左右跟你聯絡，所以之後的對接窗口都會是 Altair。&lt;/p&gt;
&lt;p&gt;首先會有 Altair 的 agent 聯絡並約 concall 的時間，介紹與澄清所有的 Relocation 服務，然後如果有需要 Shipment 的服務之後再 email 告知，不然的話基本上就是等待 Visa 下來後申請協助機票訂購。&lt;/p&gt;
&lt;h3 id="core-benefit"&gt;Core Benefit&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;搬運服務 (Shipment)，提供海運與空運各一趟，海運無重量上限但會花比較多時間 (聽說六周以上)，空運有 500 lbs 上限速度會比較快 (平均四周)，另外可以到當地後再決定使用這個服務。&lt;/li&gt;
&lt;li&gt;移動服務，其實就是幫你訂機票，由於旅程超過 50 miles，所以可以升值成商務艙&lt;/li&gt;
&lt;li&gt;暫時居所，提供 30 天暫時居所，並且不用自己尋找對方會幫忙找&lt;/li&gt;
&lt;li&gt;暫時置物空間，由於如果你有使用第一項搬運服務無須先送到暫時居所，可以使用暫時置物空間等找到長居之後才送到&lt;/li&gt;
&lt;li&gt;找房服務，提供兩天的時間帶你去看房，並且會提早與你聯絡與介紹&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="plus-benefit"&gt;Plus Benefit&lt;/h3&gt;
&lt;p&gt;有多項，這裡只羅列幾點比較有機會用到的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;寵物搬遷&lt;/li&gt;
&lt;li&gt;延長暫時居所時間&lt;/li&gt;
&lt;li&gt;原來居所的違約金&lt;/li&gt;
&lt;li&gt;額外的找房服務時間&lt;/li&gt;
&lt;li&gt;租房押金&lt;/li&gt;
&lt;li&gt;額外的行李費用&lt;/li&gt;
&lt;li&gt;語言訓練、文化訓練&lt;/li&gt;
&lt;li&gt;伴侶移動協助&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另外如果 Plus Benefit 沒有使用完畢，會在隔年的薪水中一樣付給你，不過據說已報稅來看建議盡可能多用。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;在使用 Relocation 的服務時，會需要登入使用 Altair Global 的網站，其中可以操作的包含預訂機票時間、報銷帳務、搬運服務等等，因此像是我要報銷雅思考試費，就是直接在網站上申請並上傳收據、刷卡紀錄等。另外比較特別的是機票是由 Altair 幫忙訂購，只需要告知想要出發的時間以及起降機場，Altair 便會提供你航班選項選擇以及幫忙訂票，因此在這部分無須先自己代墊金額。&lt;/p&gt;
&lt;p&gt;在拿到簽證後，就可以寄信與 Altair 通知拿到簽證與期待飛行的時間，並且上 Altair 的網頁上開需求，包含起降機場、起飛日期等，約一兩天內 Altair 會回信確認你想要的航班 (如果有多家航班可以選)，但希望可以在 24 小時內回覆，因為票價跟位置隨時會改變。agent 是沒有跟我講明確的資料，不過由於會給候選航班的飛機編號等，因此還是可以輕易地由 skyscanner 查到資訊等，回信時可以同時回復你傾向的額外選項，像是想坐靠窗、吃素食等，另外也可以累積里程數，只需要多回復 flyer number 即可。回復確認航班後，Altair 會很快地幫忙訂票並透過 myCWT 平台回復詳細資訊，由於我是選擇長榮，並且有給長榮的 flyer number，因此也可以直接上長榮的網站上確認並修改座位、餐食、登記免費 wifi 等。另外由於我們公司規定如果飛行距離超過一定程度，是可以做商務艙，因此這趟飛行也是我第一次坐商務艙。&lt;/p&gt;
&lt;p&gt;在到達英國後，也是可以跟 Altair 預先預定接送服務送到臨時居所，不過由於我耍智障沒有預定，所以到了之後叫了一部計程車，之後再跟 Altair 報帳。另外後來我才知道，在移動日當天的車馬費跟飲食費都是可以報帳的，只是預先不知道+已經被商務艙餵飽飽的，所以就沒有花到飲食的費用了。&lt;/p&gt;
&lt;h2 id="找房"&gt;找房&lt;/h2&gt;
&lt;p&gt;在到英國的前 30 天內 Altair 會幫忙找暫時的租屋處，計算時間從下飛機開始 (不會讓你有時間無家可歸)，如果你想要繼續住，可以用 Plus Benefit 的額度來續 (或自行付費)，不過公司提供的住宿都位置好、環境好，暴貴，所以都不建議自費繼續住 XD。在 Altair 幫忙訂完機票幾天後，會就手上有的一些 option 寄信來問你想住哪一個，同時當然是希望越快決定越好。以我的經驗給的兩個選項位置都蠻不錯的，在市中心到公司約 30 分鐘左右，所以短租應該是不用擔心位址或房屋狀況的問題。&lt;/p&gt;
&lt;p&gt;我最後選一個在聖保羅大教堂旁邊的旅館，超爽 XD&lt;/p&gt;
&lt;p&gt;找長期居所是自己的責任，然而幸運的是 Core Benefit 內有包含協助看房的服務，是由 Altair 內另一個 DSP 部門處理，也使用獨立的 Altair Relocation 網站，並有另外的 agent 與聯繫。&lt;/p&gt;
&lt;p&gt;第一次聯繫時 DSP 會先確認一些找房的要求，包含 是否有寵物、預算、最高通勤時間、有沒有偏好區域 等等，並大致介紹倫敦的房市、租屋流程、建議查看的區域等，然而由於離我起飛時間還久，agent 便跟我約第二次 concall 來進一步確認細節，不過基本上我到第二次聯繫的時候都還是沒有什麼想法，因此就想說到英國之後再花點時間看看。&lt;/p&gt;
&lt;p&gt;到英國之後跟朋友詢問後，朋友建議由以下幾點來看&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Agent managed or landlord managed where the landlord lives in London. (因為他深受 landloard 溝通 round trip time 很久所苦)&lt;/li&gt;
&lt;li&gt;盡量不要一樓 (ground floor，英國的樓層是 0 base)，夏天想開窗戶比較不用擔心被翻牆&lt;/li&gt;
&lt;li&gt;Prefer: Furnished with modern interior or unfurnished，避免住到太舊或甚至房東拿來當儲藏室的地方&lt;/li&gt;
&lt;li&gt;Good to have: Bathrooms with windows，避免浴室太潮&lt;/li&gt;
&lt;li&gt;Good to have: Double glazed window，隔音，英國老房子隔音通常很差&lt;/li&gt;
&lt;li&gt;另外可以考慮避免 A road 主幹道太吵&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;地點上面可以用這個網站大略看一下每個區的狀況:
，倫敦是個隔一條街就可能差很多的城市，所以實際看房時可以也多加留意附近環境。&lt;/p&gt;
&lt;p&gt;由於我來英國後一個月有一個朋友也要來，所以當初主要是以 2b(bed)1b(bath) 或 2b2b 的房型為主在找。&lt;/p&gt;
&lt;p&gt;結果公司合作的 agent 跟我說倫敦今年的房市有點太瘋狂了，他也沒有什麼房源，所以我們一起在 rightmove 跟 zoopla 上看，如果我或他有看到符合的房源就互相通知一下然後他會幫忙去與房仲溝通，不過如果是寫 OpenRent 的房源，代表房東不希望透過房仲 (雙方都是，避免被抽成)，所以要我自己聯絡。另外如果要找陌生人分租的房源了話，可以看 ShareRoom，不過這部分的房源他也不會幫忙。&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;英國租房會付兩次 deposit，一次是 Security Deposit 比較像是訂金 (好像是一個禮拜的房租金額)，是在決定要租這間房子後先付的，代表你有足夠的誠意租房，房東也會停止讓其他潛在客戶看房，接下來就會跑你的背景審查之類的東東。第二次是 Tenancy Deposit，比較像是押金，是在確定都沒問題後，先付一到兩個月 (我是付 1.5 個月) 的房租，等你退房時如果都沒問題就會全數退還，如果有問題會從裡面科扣。而 Security Deposit 會幫你從第一個月租金扣，也就是你第一個月可以少交一個禮拜的金額。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第一次看房的時候看了兩間，其實我覺得都還行，比較有趣的是第二間看完一出房子，對面房仲就接到電話有人已經交 security deposit (訂金) 了，這個房源就直接沒有了。不過由於第一次看房，還沒有太多感覺，所以就沒有定下來。第二次看房的時候只看一間，看完傍晚覺得算了就這間吧，跟 agent 講想下訂，agent 請我準備 Direct Debit (金融卡) 的資料，可是其實我那時候連開戶都還沒弄好，是想說可以直接用轉帳或跨國刷卡的方式交訂金 (我蠢)，agent 知道後有點不爽請我趕快開 monzo 或 revolut，等我辦完後 (網路銀行也真的辦超快) agent 馬上寫信問對面房仲，不過隔天房仲回信已經被訂走了 Orz。&lt;/p&gt;
&lt;p&gt;第三次看房時由於已經用掉兩天看房的扣打了，所以還是由 agent 幫忙連絡不過我自己去 (前兩次 agent 有陪我一起看，也有幫忙問一些問題)。這次看完後我大概問了一下我朋友，他也覺得還可以，於是我就跟 agent 說我可以下訂，但由於對面房仲表示有人有 compete，原本房東出 2000，似乎至少有人 compete 2100 了，我就問一下我朋友他覺得什麼價格適合，他表示 2400 他覺得都能接受，我就跟 agent 說最高 2400，想說 agent 應該會幫我壓價，結果是我想多了 agent 直接寄 2400 的價格，並且訂兩年，一年後可以提早解除合約 (有先跟我討論)，並且大概介紹了我的職業跟公司，以及收入 (好像因為英國有規定不能租超過薪水多少比例的房子)。沒過多久對方房仲就回信房東願意收我的 offer，所以需要先繳 Security Deposit，結果很誇張的是對方房仲直接大電話來請我念出 Debit Card 的所有資訊讓他 Key In，後來想想真的很有問題，可是又怕別人先付訂金而沒搶到房。&lt;/p&gt;
&lt;p&gt;在交完 Security Deposit 後就是一系列的背景審查，首先會請你提供 right to rent 證明你可以合法租屋，這部分直接到
上申請一組 shared code 給房東就可以證明了。然後有像是資產證明，由於我初來倫敦連第一份薪水都沒有拿到，想當然耳沒有在這邊有存款，請好趕快請家人匯一點錢到我台灣的帳戶提供截圖證明我有存款 (其實有點遊走法律邊緣) (然後我發現我以前真的太會花錢了 Orz)。也有寄信跟我的雇主詢問我的雇傭狀況以及薪資 (我們公司還有特別問我要跟對方講多少 XD)。在審查完我的背景後最後會請&lt;strong&gt;第三方公司&lt;/strong&gt;做屋況檢查，這也是會作為退租時能拿回多少 Tenancy Deposit 的依據，在第三方公司檢查完後當天就把鑰匙交給我了，也就是我可以直接入住了，等一個禮拜後公司會寄給我報告，如果我有認為什麼沒有注意到需要加上去的，再在一個禮拜內回信捕到文件裡。另外第一個月交的是第一個月的房租 + Tenancy Deposit - Security Deposit。&lt;/p&gt;
&lt;h2 id="搬家"&gt;搬家&lt;/h2&gt;
&lt;p&gt;如上所言，我們公司有提供搬家服務，包含 500 lbs 的空運服務以及一次的不限重量海運 (應該是一個貨櫃啦，不太可能無限)，另外是可以到英國之後再使用的，因此我就想說等我找到房子後再使用，也可以順便了解需要多帶什麼請家人幫忙放。結果上工的第二個月就遇到公司 layoff，之後又各種風聲鶴唳，都不太能確定我能不能留在英國，因此也就一職沒有用 (這又是另外一個故事了)。直到半年後逐漸穩定後才決定使用 (Benefit 可以在一年內使用)，結果搬家公司表示我離該台灣太久，會被海關稽查，需要我回台灣一趟再出境，我就只好摸摸鼻子買了個機票回台來回。&lt;/p&gt;
&lt;p&gt;在表示可以開始啟動搬家後，Altair 那邊有寄一些注意事項文件給我看，另外也有保險與我聯絡確定單位物品的單價是否不超過一個數字 (蠻高的，反正我是不會超過)，等到我回台灣後，台灣部分的搬家公司會正式跟我聯絡，有先來我家一次，確認大概要帶的東西，以及什麼東西不能帶，第二次來就是幫忙包+搬東西。比較有趣的是搬家公司建議不要自己包，如果自己包運送過程中損毀他們理論上不負責，但他們包了話就可以理賠。&lt;/p&gt;
&lt;p&gt;之後搬家公司會需要我到英國政府網站填寫報關的表單，基本上就是你大概運了什麼以及保證是你自用。約三四個禮拜後英國政府 approve 我的申請，我在回覆搬家公司，大約四五天後東西就搬到我家了 (超快) ^^&lt;/p&gt;
&lt;p&gt;然而有一點物品有受損，我跟保險反映後填寫了一個清查表單，可能是因為金額沒有很大保險沒有特別要求確認就直接匯款給我了，只是有被銀行收了一點 fee&lt;/p&gt;
&lt;h2 id="駕照"&gt;駕照&lt;/h2&gt;
&lt;p&gt;由於據說英國駕照十分難考，平均要考兩次，另外可以使用國際駕照或換照方式取得當地駕照，因此我選擇十分心虛的拿雞腿換的駕照使用。如果還沒考過駕照的，可以考慮在台灣考完再去英國換照。&lt;/p&gt;
&lt;h3 id="國際駕照"&gt;國際駕照&lt;/h3&gt;
&lt;p&gt;根據換照要求，需要在當地住超過 180 天才可換照，因此我有在台灣先申請國際駕照，申請過程蠻簡單的，只需要帶駕照、身分證、護照影本(由於申請時還沒收到送到英國的護照)、兩張兩吋照片，以及 250 規費，到離家裡最近的監理站即可申請。&lt;/p&gt;
&lt;h3 id="換照"&gt;換照&lt;/h3&gt;
&lt;p&gt;在英國居住半年後可以把台灣的駕照換成英國的駕照，理論上住在倫敦跟本不會有用車需求，國際駕照也可以租車，所以沒太多換照的需求。但考慮到一來我有經驗台灣駕照不被保險公司接受保險 (對，超扯導致那次不能租車還要臨時找其他公司租)，二來是可以當另一個有效的有照片證件，就不用把 BRP 天天帶在身上，所以我還是後來決定把駕照換成英國的。要特別注意換照完就會失去台灣的駕照，但是互惠聲明中有寫到短時間回台可以用英國駕照開車 (但不確定怎麼稽查你是短時間回台)，另外有些人會說可以回台掛失，但我是不建議做違法的事情啦。&lt;/p&gt;
&lt;p&gt;主要流程有 (參考
,
)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;申請台灣駕照的英文翻譯本 (參考
)，需要寄出
、駕照正本與影本、護照影本、£12 Postal Order (只能現金或 Debit Card 轉帳的方式跟郵局買)、以及 Special Delivery、Up to 500g 之回郵信封一起寄出，寄到 &lt;code&gt;Taipei Representative Office in the UK, 50 Grosvenor Gardens, London, SW1W 0EB, United Kingdom&lt;/code&gt;。另外由於目前還不能換機車駕照，因此只寄出汽車駕照就好。另外擔心了話可以另外寫信到 &lt;code&gt;consular.gbr@gmail.com&lt;/code&gt; 確認。建議可以先把東西準備好，直接到郵局買 Postal Order 與寄出，另外同時跟郵局領取免費的 D1 Form&lt;/li&gt;
&lt;li&gt;大約半個月到一個月間會收到翻譯本，可以同時先填寫 D1 Form&lt;/li&gt;
&lt;li&gt;到郵局購買 £43 Postal Order，連同 D1 Form、駕照正本、駕照翻譯本、BRP 正本、以及回郵信封一同寄到 DVLA (DVLA, Swansea, SA99 1BT，D1 Form 裡也有地址)。尤要注意的是這段時間沒有 BRP 是不應該出國的 (回不了英國)&lt;/li&gt;
&lt;li&gt;大約半個月到一個月會收到 BRP 與駕照，另外特別的是這兩個會分開寄，應該會先收到 BRP&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="銀行"&gt;銀行&lt;/h2&gt;
&lt;h3 id="信用卡"&gt;信用卡&lt;/h3&gt;
&lt;p&gt;出國前先確定至少有一張信用卡可以跨國刷卡，雖然盡量不要用到但若需要使用，方可應急。另外可以考慮將不常使用的信用卡剪卡，避免被盜刷等風險，非必要可自行考慮，但注意&lt;strong&gt;不要剪人生第一張信用卡&lt;/strong&gt;，因為最開始的信用額度是存在於此卡。&lt;/p&gt;
&lt;h3 id="外幣帳戶跨國提領"&gt;外幣帳戶、跨國提領&lt;/h3&gt;
&lt;p&gt;由於偶爾回國時有機會需要將錢匯回國，可以考慮申辦外幣帳戶。另外也由於第一個月出國還沒有當地銀行，可以考慮開申請跨國刷卡、提領的服務就不需要帶太多現金，不過要注意的是海外刷卡會有 1.5% 手續費，以及匯率較高的問題。另外可以考慮直接跟當地認識的朋友買些許貨幣可以減少手續費用。&lt;/p&gt;
&lt;h3 id="申請英國銀行"&gt;申請英國銀行&lt;/h3&gt;
&lt;p&gt;可以到英國後先申請網路銀行 (Wise, Monzo, Revolut, &amp;hellip;) 動最會比較快&lt;/p&gt;
&lt;p&gt;幸運的是 Altair 會協助幫忙申請銀行帳號，Altair 推薦的銀行有 HSBC, Barclays, Santander, 跟 Llyods 四家，另外又 Meta 有跟 HSBC 合作，所以應該可以審核得比較快。&lt;/p&gt;
&lt;h2 id="電信"&gt;電信&lt;/h2&gt;
&lt;h3 id="台灣"&gt;台灣&lt;/h3&gt;
&lt;p&gt;由於會有大量時間不需要用到台灣的電信，因此會有幾種考量: 1. 直接退掉門號，反正現在人基本上都可以透過網路溝通了，也不一定需要一個門號來代表自己。2. 考慮到一些過去的服務的簡訊認證要求，可能會想保留門號，根據保留門號提供幾種方法可以考慮&lt;/p&gt;
&lt;p&gt;首先要瞭解的是不同的服務，漫遊 (roaming) 指的是透過國外當地的電信 (4G, 5G)，接回國內的電信資料中心，提供的服務包含電話、簡訊，但通常不包含上網，除了特定有簽約的國家 (像是有些電信會簽日本、美國等)。VoWiFi 或稱 wifi calling 是指透過 wifi，間接到國內電信資料中心，提供服務一樣包含電話、簡訊。兩個簡單理解最大的差別是無線通訊的設備一個是使用基地台，一個是使用 wifi。想當然爾用基地台需要當地的電信公司同意所以 (國內電信公司) 需要 (與當地公司) 額外簽約，而 wifi 則不用，漫遊的好處是有基地台的地方都可以用，而 VoWiFi 你要自己想辦法接上 wifi。&lt;/p&gt;
&lt;p&gt;因此，想保留門號了話我們有幾種方法可以選擇:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;購買有 VoWiFi 的方案，目前僅有月租型方案提供，今年開始幾乎大部分電信都免費提供了。透過 VoWiFi 可以只花月租費，在國外透過國內電信的 sim 卡 + wifi 一樣能打電話、收發簡訊。然而缺點是月租費一次通常要簽一到兩年，最低方案以現在來看都還是超過 100 元/月 (188, 199 等)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;透過易付卡/預付卡，預付卡在沒使用的狀況下是不需要付錢的，所以會比上面方案省錢。然而易付卡需要每半年儲值一次 (最低 100 元)，如果忘記儲值就會遺失門號，另外目前所有電信的易付卡也都不提供漫遊、VoWiFi 的服務，簡單來說就是完全不能在國外使用。使用方法可能是將 sim 卡留在台灣，如果需要認證時再請親朋好友幫忙看認證碼。另外預付卡內的錢如果沒有用到，大多數電信應該都能退費或轉移到其他裝置使用。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;透過
(不確定被台哥大併購之後是否還會提供此方案)，最大的好處就是沒使用時不用付費，另外由於可以漫遊，因此可以在國外付費收發簡訊、電話，尤其如果只要收簡訊，是不需要收費的 (收電話是需要的)。然而此方案的唯一缺點是台灣之星沒有 VoWiFi 的功能，因此如果需要打電話、發簡訊，一定要付費使用漫遊服務。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;另外建議可以在出國前弄好電信自動扣款，這樣真的有用到就不用再手動轉帳了。&lt;/p&gt;
&lt;p&gt;我最後是選擇使用台灣之星的方案，由於之前是中華電信，因此需要解約並攜碼出去，流程是先上台灣之星官網的方案申請，然後去臨櫃領取 sim 卡，領完之後再去中華解約即可。解約當天或隔天就不會有舊電信的服務了，因此如果想要用好用滿，可以快月底時才解約，但要注意台灣之星會需要在某個天數前成功攜碼，不然 sim 卡會失效，解決方式就是在失效天前透過台灣之星給的簡訊的連結上去重啟訂單，因為還沒將舊電信解約，因此重啟操作會失敗，不過倒數計時會被更新，所以新的最後解約時間就會被再延後。&lt;/p&gt;
&lt;h3 id="英國"&gt;英國&lt;/h3&gt;
&lt;p&gt;來英國後我發現我們公司有提供 on-call 手機以及幾乎吃到飽可以保證你可以被 call 起來的電信，以及全球追殺你用的漫遊，所以就沒特別辦自己的了 Orz。不過風險就是離職時會很麻煩，因為幾乎所有重要文件都綁在公司門號上。&lt;/p&gt;
&lt;h2 id="其它"&gt;其它&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;健保: 健保可以選擇直接不保，或是繼續保。理論上英國有 NHS 在醫療上應該夠用，不過如果會需要用到牙醫或其他 NHS 沒有給付的醫療可能台灣健保還是比較方便。我個人是想說可能每年回台時檢查個牙齒，另外繳點小錢可以支持台灣的全民健保給需要的人用，所以還是有持續投保。另外可以去區公所登記自動扣款，就不需要每兩個月手動繳款了。&lt;/li&gt;
&lt;li&gt;良民證: 聽朋友說如果在美國要申請全球快速入境要用良民證，因此去美國的朋友可以考慮先申請，但英國好像沒有相對應的需求，不過我還是有跑去申請避免如果真的需要。申請方式先到網站上面輸入資料申請，然後選擇最近的警察總局領取，填好資料後兩天後再去領取，領取時需要攜帶身分證與 100 元手續費。&lt;/li&gt;
&lt;li&gt;眼鏡: 如果有戴眼鏡可以再配一副以備。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="統計花費"&gt;統計花費&lt;/h2&gt;
&lt;p&gt;臺灣 (NTD)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;雅思考試費 (可報帳) 7900&lt;/li&gt;
&lt;li&gt;護照更新費 1300 + 郵寄費 120&lt;/li&gt;
&lt;li&gt;簽證郵寄費 311&lt;/li&gt;
&lt;li&gt;國際駕照規費 [非必要] 250&lt;/li&gt;
&lt;li&gt;良民證規費 [非必要] 100&lt;/li&gt;
&lt;li&gt;來回台北的交通費 (考雅思、外交部護照、VFS 簽證) ???&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;英國 (GBP)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Security / Holding deposit: 租房下架租屋網站費，不可報帳，但可以抵押之後的房租 600&lt;/li&gt;
&lt;li&gt;Tenancy deposit: 房租押金，通常一到兩個月的房租 (可用 Plus benefit) 3600&lt;/li&gt;
&lt;li&gt;第一個月的房租 2400 - 600&lt;/li&gt;
&lt;li&gt;代墊的計程車資 (機場到住宿) ~80&lt;/li&gt;
&lt;li&gt;第一個月的生活費，都吃公司可以抓個 500 (假日不出門玩，吃便宜的，加通勤費)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="timeline"&gt;Timeline&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;6/22 拿到口頭 offer&lt;/li&gt;
&lt;li&gt;6/28 回復接受 offer&lt;/li&gt;
&lt;li&gt;6/29 陸續簽了各種文件，填寫 Meta career 資料，填寫背景審查&lt;/li&gt;
&lt;li&gt;6/30 線上預約煥發護照，背景審查要求提供中文姓名、學生證號&lt;/li&gt;
&lt;li&gt;7/1 到台北外交部領事事務局申請護照換發&lt;/li&gt;
&lt;li&gt;7/4 與 Deloitte concall、背景審查要求提供畢業證書、成績單&lt;/li&gt;
&lt;li&gt;7/5 背景審查完成&lt;/li&gt;
&lt;li&gt;7/11 約 Altair concall 但由於當天對方臨時生病因此會議延後&lt;/li&gt;
&lt;li&gt;7/16 考雅思&lt;/li&gt;
&lt;li&gt;7/21 拿到雅思成績&lt;/li&gt;
&lt;li&gt;7/22 完成所有 Visa Application Form 的資料填寫並告知 Deloitte&lt;/li&gt;
&lt;li&gt;7/25 與 Altair concall&lt;/li&gt;
&lt;li&gt;8/3 與 Altair DSP concall&lt;/li&gt;
&lt;li&gt;8/12 收到 Deloitte 回信詢問是否可以 8/15 繳交文件&lt;/li&gt;
&lt;li&gt;8/15 到 UK Visa Application Centre 繳交簽證文件、護照&lt;/li&gt;
&lt;li&gt;8/25 收到 Visa 與 UKVI 01&lt;/li&gt;
&lt;li&gt;9/6 與 Altair DSP 第二次 concall&lt;/li&gt;
&lt;li&gt;9/25 飛到英國&lt;/li&gt;
&lt;li&gt;10/3 上工&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="references"&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Coding Interview 流程整理</title><link>https://calee0219.github.io/blog/coding_interview_overview/</link><pubDate>Mon, 25 Jul 2022 15:59:25 +0800</pubDate><guid>https://calee0219.github.io/blog/coding_interview_overview/</guid><description>&lt;p&gt;這篇部落格主要著墨在 Coding Interview 的流程、注意事項，關於準備方法可以參考
。&lt;/p&gt;
&lt;p&gt;&amp;mdash; 2023 更新 &amp;mdash;&lt;/p&gt;
&lt;p&gt;如果想要找 mock interview，可以來信
詢問，想要幫忙修履歷的也可以寄來看看，但不保證有空幫忙 XD。&lt;/p&gt;
&lt;!-- Google Calendar Appointment Scheduling begin --&gt;
&lt;link href="https://calendar.google.com/calendar/scheduling-button-script.css" rel="stylesheet"&gt;
&lt;script src="https://calendar.google.com/calendar/scheduling-button-script.js" async&gt;&lt;/script&gt;
&lt;script&gt;
(function() {
var target = document.currentScript;
window.addEventListener('load', function() {
calendar.schedulingButton.load({
url: 'https://calendar.google.com/calendar/appointments/schedules/AcZssZ10EEmxfEJfyec_e-58EktYERtAOp9E-kjF7olGPJC-Qfo5KltSpAUz0qgYwDkc02mlSQuYN20v?gv=true',
color: '#039BE5',
label: '預約 Mock Interview 時間',
target,
});
});
})();
&lt;/script&gt;
&lt;!-- end Google Calendar Appointment Scheduling --&gt;
&lt;p&gt;PS. 不 qualify senior，請不要對幫助抱太大期待 XD&lt;/p&gt;
&lt;p&gt;BTW 敝司 (Meta) 最近重新開缺了，如果有看到有興趣的職缺，歡迎準備英文姓名、email、CV，可以找我 reference，另外我會希望能跟您約個 con-call 認識一下~ 🤗&lt;/p&gt;
&lt;h2 id="流程"&gt;流程&lt;/h2&gt;
&lt;h3 id="時間掌握"&gt;時間掌握&lt;/h3&gt;
&lt;p&gt;一般來說 coding interview 時長大約是 45 分鐘，不過面試官通常不會很硬性的把你打斷，所以可以來回假設個五十分鐘。在 45 分鐘的時間裡預期會有兩個題目，有可能是主題與 follow up；也有可能是兩個獨立的題目；當然還有機會是只有一題 hard。&lt;/p&gt;
&lt;p&gt;以 Google recuirter 提供的準備文件會建議第一題花 10 - 15 分鐘，其中五分鐘確認題意，五分鐘思考並表達解法，最後五分鐘實作與測試；第二題花 20 - 25 分鐘，五分鐘確認題意，十分鐘想解法與表達，最後十分鐘實作與測試。其理由是第一題通常比較簡單而第二題會比較困難。&lt;/p&gt;
&lt;p&gt;不過我個人覺得要在 15 分鐘內解決一題偏困難，另外以我對 Google 的面試經驗覺得 Google 傾向於詢問一個主題與一個 follow up，並且 follow up 有時候並不太難，因此我會比較傾向配置 25 / 20。&lt;/p&gt;
&lt;p&gt;在 Meta 的 coding interview 上面我的經驗是對方好像比較喜歡出獨立題目，並且一開始會有一題 warm up 題，盡量不要在 warm up 題花太多時間。&lt;/p&gt;
&lt;h3 id="流程簡述"&gt;流程簡述&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;自我介紹 (不計入面試表現)&lt;/li&gt;
&lt;li&gt;第一題
&lt;ul&gt;
&lt;li&gt;面試官陳述題目&lt;/li&gt;
&lt;li&gt;與面試官確認題意&lt;/li&gt;
&lt;li&gt;表達解法&lt;/li&gt;
&lt;li&gt;分析複雜度&lt;/li&gt;
&lt;li&gt;實作&lt;/li&gt;
&lt;li&gt;測試 (dry run)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;第二題
&lt;ul&gt;
&lt;li&gt;重複第一題動作&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;反問面試官問題 (不計入面試表現)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="自我介紹"&gt;自我介紹&lt;/h3&gt;
&lt;p&gt;一開始通常考官會請你自我介紹，以 Google 的說法是讓妳不要太緊張的暖身，並不算入面試狀態，面試官也不太會認真聽，當然偶爾也有面試官會直接忽略這個階段，另外在這邊要注意自我介紹最好&lt;strong&gt;不要超過一分鐘&lt;/strong&gt;，以免壓縮到後面解題的時間 (自我介紹要準備 1 / 3 / 5 分鐘的版本，如果是在 experience interview 或 behavior interver 就可以使用 5 或 3 分鐘版)。&lt;/p&gt;
&lt;h3 id="題目應答"&gt;題目應答&lt;/h3&gt;
&lt;p&gt;首先考官會陳述題目，注意考官陳述的題目有沒有什麼關鍵字，有可能就是題目最佳化的關鍵。&lt;/p&gt;
&lt;p&gt;在考官陳述完題目後不要急於作答，先與考官確認題目意思與詢問不太清楚的資訊，永遠要記得做這個步驟那怕你覺得題目超簡單，最少也可以問個 test case 的 constrain (範圍) / edge / boundary case。澄清題目的方法可以與考官詢問是否有範例測資會自己製造一個範例，並且透過範例找到解答的過程來確認理解是否正確。&lt;/p&gt;
&lt;p&gt;OK, I think I understand the problem. Please give me one minute to think out the solution.&lt;/p&gt;
&lt;p&gt;當理解完題意要開始想解法時，記得給一個 trigger word，由於 coding interview 大多數時間都是不斷的與面試官來回溝通，因此當需要一個安靜的時間可以講一下，讓面試官知道你須要想一下。&lt;/p&gt;
&lt;p&gt;I have come out a solution. I want to start to present my solution.&lt;/p&gt;
&lt;p&gt;當想到解法要開始敘述解法時，一樣可以有一個 trigger point。或如果你不太確定，也許可以說: I&amp;rsquo;m not quiet sure now, here&amp;rsquo;s what I&amp;rsquo;ve thought about the problem. 並嘗試敘述你的想法。&lt;/p&gt;
&lt;p&gt;在解釋解法的過程中，有兩種方法。其一是條列式的講出要做的步驟，並大略記錄下來，但要小心不要過於詳細到流於 pseudo code，這種表達方法的好處是之後實作時可以直接參考已經紀錄下來的流程，並且也在表達同時也想清楚要使用的資料結構，但壞處通常會花比較多時間，需要小心掌控時間。其二是直接透過 test case 來描述做法，舉例來說: 可以先排序 array (此時把範例複製出一份排序好)，然後透過 two pointer (劃出兩個 pointer) 向內搜尋 (同時移動 pointer 尋找並解釋)。這個方法的好處可以讓解釋上更具體，並且普遍上要花的時間比較少就能很清楚的解釋，不過壞處可能是之後要實作時沒有參照，我個人傾向後者。&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s all of my solution. Is it makes sense / sound reasonable?&lt;/p&gt;
&lt;p&gt;完成你的 solution 後記得跟面試官確認，也許面試官會覺得不太合理、點出錯誤，或者複雜度不是面試官要的。有時面試官會在這裡跟你詢問演算法複雜度，也有時候會是在實作結束後問。如果面試官表示 ok 便可以開始實作，這時候可能會說: So I&amp;rsquo;ll start my coding now. Is there any function template or maybe I just create a new function. 來確認是否有模板 (主要是要確認 input 的參數)。之後在實作上記得偶爾停下來敘述目前的狀態、這行 code 為什麼要寫，如果有比較重要的行數記得可以下註解，好的 coding style 也是 coding interview 的重要指標其中一環。可以多包 function 並假設 function 已經實作完成 (記得註解函式輸入出以及功能)，之後若有必要在回來時做函式細節，這樣可以有效的減少實作複雜度以節省時間。&lt;/p&gt;
&lt;p&gt;I think I&amp;rsquo;ve finished the code, should we use some example to varify it / walk though the solution?&lt;/p&gt;
&lt;p&gt;當完成實作後，一定要記得詢問是否需要驗證 (dry run)，大多數的 coding interview 不會有 compiler 但是會需要肉眼把測資餵進去驗證，大略說明在 code 的每一階段測資或變數目前的狀態。在這個階段先跑 general case，可以詢問直接拿前面的 sample case 來用 (general case)，但如果前面的 sample case 還是偏大，記得縮小後再拿來用，以免花太多時間講重複的東西。在 general case 講完後才來講 edge case，這時候可以說你知道有哪些 edge case，並且你已經在程式的 xxx 處把 edge case 判掉了。&lt;/p&gt;
&lt;p&gt;在這樣玩成一個 round 後，也許考官會給出新的 follow up，又或者希望你再把複雜度壓更低，此時只要照個考官給予的 hint，再重複上面的動作即可 (也許不用重複確認題意)。&lt;/p&gt;
&lt;h3 id="反問問題"&gt;反問問題&lt;/h3&gt;
&lt;p&gt;在反問問題這個階段同樣不計入評比，但可以透過機會多多了解公司甚至是部門或這個職缺，或者單純閒聊人生。我比較喜歡問的問題有:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is your favorite part working here?&lt;/li&gt;
&lt;li&gt;What is the team culture like?&lt;/li&gt;
&lt;li&gt;What makes a successful PE / SRE / SWE?&lt;/li&gt;
&lt;li&gt;What do you think are the most important qualities for someone to be really successful in this position?&lt;/li&gt;
&lt;li&gt;What are the common career paths in this department?&lt;/li&gt;
&lt;li&gt;What are the biggest challenges the company / team is facing right now?&lt;/li&gt;
&lt;li&gt;Can you tell one of the best part and one of the worst part of your company or team?&lt;/li&gt;
&lt;li&gt;What do you learned most in your position?&lt;/li&gt;
&lt;li&gt;What is your daily work flow? / What is the tipical days looks like?&lt;/li&gt;
&lt;li&gt;是否可以從頭到尾參與 Project，亦或 Project 容易受客戶影響而終結&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="複雜度注意事項"&gt;複雜度注意事項&lt;/h2&gt;
&lt;p&gt;在分析複雜度上可以注意以下狀況&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;stack space 是否有考慮進空間複雜度中&lt;/li&gt;
&lt;li&gt;union-find / recursive 的複雜度&lt;/li&gt;
&lt;li&gt;quick sort / hash table 等請表明是 average case 或中文說&amp;quot;均攤&amp;quot;&lt;/li&gt;
&lt;li&gt;string concate 的實做是完全複製或動態加長&lt;/li&gt;
&lt;li&gt;O(n) 的 n 代表什麼意思 (array 長度、heap 高度、tree 深度、&amp;hellip;)&lt;/li&gt;
&lt;li&gt;複雜度是只需要一個變數 n (其他變數保證比較小)，或是需要多個變數 n, m, h, &amp;hellip; (因為不保證關係)?&lt;/li&gt;
&lt;li&gt;你的 tree 是否平衡，如果未平衡會如何，此時可以詢問考官是否可以假設平衡樹，因為實踐平衡樹可能不是時間下可以完成的 (快去查 Treap 來用嘴巴平衡 XD)&lt;/li&gt;
&lt;li&gt;預處理的時間是否有考量進去&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="常用詞匯"&gt;常用詞匯&lt;/h2&gt;
&lt;p&gt;英文面試上好用的句子&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I have couple of questions&lt;/li&gt;
&lt;li&gt;Would the input always be a XXX&lt;/li&gt;
&lt;li&gt;Can I assume that XXX? Can I make sure XXX?&lt;/li&gt;
&lt;li&gt;Should I need to consider for a really large input? What&amp;rsquo;s the input constrain?&lt;/li&gt;
&lt;li&gt;What is the input. Is it the root of tree?&lt;/li&gt;
&lt;li&gt;DISTINCT?&lt;/li&gt;
&lt;li&gt;Is there always promised to be an result?&lt;/li&gt;
&lt;li&gt;How can I output results?&lt;/li&gt;
&lt;li&gt;How can I do if there is no valid result?&lt;/li&gt;
&lt;li&gt;How can I do if there are multiple results?&lt;/li&gt;
&lt;li&gt;Is the order of the output result matters? Or how should I order them?&lt;/li&gt;
&lt;li&gt;Can I assume that all the input are valid?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="注意事項"&gt;注意事項&lt;/h2&gt;
&lt;p&gt;一些在面試上可以注意的東西&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果有，自我介紹不要超過一分鐘&lt;/li&gt;
&lt;li&gt;不要動任何考官給的東西，如果需要，複製出來使用&lt;/li&gt;
&lt;li&gt;如果考官有給 hint，照著做就對了&lt;/li&gt;
&lt;li&gt;不要羞於跟面試官尋求幫助，也許可以比較委婉地敘述目前的想法以及卡關的地方&lt;/li&gt;
&lt;li&gt;注意測資是 int / float / long 等&lt;/li&gt;
&lt;li&gt;重要的地方下註解&lt;/li&gt;
&lt;li&gt;良好的 coding style、變數名稱、避免 dead code&lt;/li&gt;
&lt;li&gt;注意 pass by reference or value、string mutable or immutable、字串複製還是單純加長&lt;/li&gt;
&lt;li&gt;把實作假設成已完成的函式，詢問面試官是否可以之後若有時間再回來時做細節，並寫下良好的註解 (input / output / 函式用途)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>2022 求職心得</title><link>https://calee0219.github.io/blog/2022_get_jobs/</link><pubDate>Sat, 02 Jul 2022 08:46:29 +0800</pubDate><guid>https://calee0219.github.io/blog/2022_get_jobs/</guid><description>&lt;p&gt;由於我 2021 年剛畢業時發懶不想當兵前先找工作，於是就拖延到 2022/02 當完兵後才開始找工作，不料這個舉動同時成為了我的危機也是轉機。&lt;/p&gt;
&lt;p&gt;詳細找的公司與摘要可以參考
。&lt;/p&gt;
&lt;p&gt;BTW 敝司 (Meta) 最近重新開缺了，如果有看到有興趣的職缺，歡迎準備英文姓名、email、CV，可以找我 reference，另外我會希望能跟您約個 con-call 認識一下~ 🤗&lt;/p&gt;
&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;畢業於國立陽明交通大學資訊科學與工程研究所，研究所研究方向在於行動網路。另外大學時由於有資工系計中工作，擔任網路組組長，對傳統網路和故障排除也略知一二。&lt;/li&gt;
&lt;li&gt;GPA 並不高，大學部 3 出頭，研究所勉強超過 3.5。&lt;/li&gt;
&lt;li&gt;大一到大三有與隊友參與 ACM-ICPC 的競賽，算是在這類題目上有所著墨。不過話說回來，已經三年沒碰東西也差不多歸零了。&lt;/li&gt;
&lt;li&gt;2021 年七月研究所畢業，由於疫情緩招，在家蹲了約兩個月，大概九月才入伍，四個月兵後，二月退伍。&lt;/li&gt;
&lt;li&gt;退伍後主要花時間在刷題，另由於面試 SRE 相關職缺，有對作業系統相關知識做一些複習。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="履歷"&gt;履歷&lt;/h2&gt;
&lt;p&gt;見
，感謝朋友幫忙修改。對不同公司會加以調整，基本做成 1 page。
我是使用
的 latex 模板。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果可以，請對數字上做琢磨，與其籠統地表示你建置了什麼服務，更應該表示這個服務產生的影響範圍。&lt;/li&gt;
&lt;li&gt;有些公司會把履歷印出來，所以如果真的很想讓主管知道的連結不要只用超連結而是把完整網址列出。&lt;/li&gt;
&lt;li&gt;嘗試使用 STAR (situation, task, action, result) 方式撰寫，避免使用 we 而是使用 I。&lt;/li&gt;
&lt;li&gt;GPA 好了話放上 GPA，如果有表現突出的課程可以寫 selected course&lt;/li&gt;
&lt;li&gt;基本上寫在履歷上的內容就是在暗示 interviewer 問你其中的細節，所以放上自己熟的而不是所有有碰過的專案。&lt;/li&gt;
&lt;li&gt;課外專案沒有也沒關係，放上你做過的課程專案，所以請偶爾選一些有整學期專案的課。&lt;/li&gt;
&lt;li&gt;Skill 上可以盡可能地多寫關鍵字，兩個原因：1. 有些 career 系統用關鍵字 filter，沒寫就會沒有 match。2. recruiter 有可能不一定看得懂，但你多寫有機會讓他們覺得你有料讓你至少走到下個階段 (interview)。&lt;/li&gt;
&lt;li&gt;另外蠻有趣的是我沒有寫 cover letter，其實並不是我有自信，反而是年少無知看到 optional 覺得不用填就還真的沒去請教前輩要不要寫了 Orz&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="尋找職缺"&gt;尋找職缺&lt;/h2&gt;
&lt;h3 id="了解自己"&gt;了解自己&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;對未來想走的 career path 的想像&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;可出國 vs 不可出國&lt;/li&gt;
&lt;li&gt;對領域有興趣 vs 想快退休&lt;/li&gt;
&lt;li&gt;了解對不同種類壓力的耐受程度&lt;/li&gt;
&lt;li&gt;安穩的工作 vs 想裁就裁員的工作&lt;/li&gt;
&lt;li&gt;希望工作自主性高 vs 希望更多時候是可以有人帶&lt;/li&gt;
&lt;li&gt;產品的 life cycle&lt;/li&gt;
&lt;li&gt;work life balance / 加班 / 工時&lt;/li&gt;
&lt;li&gt;希望假多一點 vs 假期可以都換成工資&lt;/li&gt;
&lt;li&gt;對薪資的追求&lt;/li&gt;
&lt;li&gt;希望年資到就可以進到對應薪資 vs 需要自己爭取，薪資成長與個人能力相關&lt;/li&gt;
&lt;li&gt;新創 vs 中小公司 vs 大公司&lt;/li&gt;
&lt;li&gt;股票 / 本薪 / 分紅 / 績效獎金 / 簽約金&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="看-job-description"&gt;看 Job Description&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;JD 是各個職缺在開出來時描述這個職缺需要的技能以及工作上會處理的事務&lt;/li&gt;
&lt;li&gt;通常會列出 Basic Requirements / Prefered Requirements / About the jobs，並不是需要全部都會才能投，通常你只要會其中幾項就有機會申請&lt;/li&gt;
&lt;li&gt;常見的查詢方式可以在 LinkedIn 或 104 上看&lt;/li&gt;
&lt;li&gt;又或者直接搜尋 XXX 公司 + careers，比較大的公司都會有自己的 careers site 羅列需要的職缺，例如: careers.google.com /
/
&amp;hellip;&lt;/li&gt;
&lt;li&gt;其實蠻建議&lt;strong&gt;學生可以提早開始研究 JD&lt;/strong&gt;，一來可以開始形塑對 career path 的想像，二來也可以針對想進入的領域鑽研，甚至著手學習 Requirements 要求的相關技能，我也是在找工作看 JD 時才慢慢形塑出我想像中想要的 career path&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="了解公司"&gt;了解公司&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;直接在網路上尋找公司相關訊息，了解這家公司的產品 / 獲利方式 / 財報&lt;/li&gt;
&lt;li&gt;直接問在公司工作的朋友&lt;/li&gt;
&lt;li&gt;從 LinkedIn 上在公司內工作並與你有所連結 (ex. 校友) 寄信詢問&lt;/li&gt;
&lt;li&gt;Meta 甚至還有專門 Meta Connection 讓你直接與公司員工交流&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="尋找建立人脈--reference"&gt;尋找，建立人脈 &amp;amp; Reference&lt;/h3&gt;
&lt;p&gt;管道&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;找以前認識的朋友/同學&lt;/li&gt;
&lt;li&gt;在自己的 Facebook / IG / Twitter / LinkedIn 發文請認識的朋友或朋友的朋友或朋友的朋友的朋友&amp;hellip;幫忙介紹&lt;/li&gt;
&lt;li&gt;多參加各種 conference / meetup 認識新朋友，在台灣尤其推 COSCUP / HITCON 兩個我以前會去的大拜拜，PyCon, RubyCon, MobiCon 沒去過不熟，不過應該都很不錯&lt;/li&gt;
&lt;li&gt;在 LinkedIn 尋找 target 公司的校友/台灣人/類似經驗的人/相關部門&lt;/li&gt;
&lt;li&gt;在 Facebook 上找在地社團群組 (如果是投國外公司) 直接 po 文&lt;/li&gt;
&lt;li&gt;一畝三分地找 (我沒做過不確定好不好)&lt;/li&gt;
&lt;li&gt;找有部落格，寄信詢問版主有沒有機會內推他的公司&lt;/li&gt;
&lt;li&gt;平常就與 Head hunter keep in touch，有 HH 來信/LinkedIn 私訊時都多少回個現在沒有積極在找，但是希望 keep in touch in the future&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;建議內容&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有禮貌 (無庸置疑)&lt;/li&gt;
&lt;li&gt;不要害怕詢問，通常大家其實都跟你一樣很願意做這個舉手之勞的幫忙&lt;/li&gt;
&lt;li&gt;保持開放的態度，有問到是賺到，沒問到也沒差&lt;/li&gt;
&lt;li&gt;準備你的(中英文)姓名，聯絡信箱，CV，第三人稱的自我介紹 (有些公司內推要寫你認識的這個人是怎麼樣的人)，興趣跟擅長的領域，想要投遞的職缺，並且可能的話 con-call 一個口頭的自我介紹&lt;/li&gt;
&lt;li&gt;我個人首推用 email，因為 LinkedIn 不一定每個人都天天看。也可以鼓起勇氣用 messager 不過如果有前兩個先用&lt;/li&gt;
&lt;li&gt;如果你好奇為什麼前輩們會幫陌生人，我自己覺得有幾個原因 1. 認識新朋友，尤其是在國外工作交友圈有時候會漸漸有點侷限，偶爾能認識新人也是蠻開心的 2. 內推有內推獎金，何樂不為 3. 增加影響力，尤其是越往資深走，個人的技術能力會邊際效益遞減，而對團隊的影響力則是需要增加。如果你有進我們公司，也許未來我有機會請你的 team 幫忙比較好說話 4. 對人脈的投資，同樣前輩們也需要建立人脈，就像 HH 一樣，有人主動找我當然樂得輕鬆，如果我未來要跳槽也許就換我找你 5. 個人成就感 6. 飲水思源的傳承，過去前輩幫我，現在行有餘力我也可以幫後進&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="評估薪資"&gt;評估薪資&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;跟認識的朋友打聽&lt;/li&gt;
&lt;li&gt;大概了解目前股價&lt;/li&gt;
&lt;li&gt;上
/
/
查詢&lt;/li&gt;
&lt;li&gt;可能有畢業生會想問薪水應該在找工作站多大比例，當然每個人可能不同，但根據 ptt 前輩們的心得，應該算重要但不要放在第一順位&lt;/li&gt;
&lt;li&gt;我自己會說如果你不排斥的公司夠多，底線可以先放在整包 100，再根據面試的心得 (自己在人才市場的狀況) 做調整，所以絕對不要只面試一間公司&lt;/li&gt;
&lt;li&gt;薪資物價比，我自己看下來覺得其實除了美國可以給 Global Pay (XD) 之外，大部分不管歐美還是台日、新加坡都還是給 local pay，更甚至如果想存錢，難保說待在台灣其實更好存錢，去了解房租物價稅收會比只看到稅前薪水的數字還來的有意義，另外一個評估方法可以用國民平均收入與之倍數來評估&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="外商面試流程"&gt;外商面試流程&lt;/h2&gt;
&lt;p&gt;首先當然每家公司會不太一樣，不同的職位對面試的需求也不同，不過對工程師職缺應該多還是大同小異分為 Online Assessment (OA)、Phone Interview 與 (Virtual) Onsite Interview，名稱可能會有所不同但階段還是類似。&lt;/p&gt;
&lt;ol start="0"&gt;
&lt;li&gt;
&lt;p&gt;履歷: 這個階段最主要要讓你的履歷通過 HR 之手，讓 HR 覺得你是直得進到面試流程的人，有時候這個階段反而會是面試裡最關鍵的部分，尤其是對準備很充分的人，所以要如何撰寫一份亮眼的履歷其實還蠻重要的 (尤其對不太重視 promote 自己的華人工程師)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Online Assessment: 線上考試，會給你一些題組，可能是一些選擇題，也可能是幾個 coding 題，亦或是混合，請你自己規劃時間，在自己的閒暇之餘開題於規定的時間內撰寫，通常也不會抓作弊，有些公司可能會要螢幕與人臉錄影。這個階段很常是做最基本 coding / 背景知識的檢查，只用來刷掉真的不是工程背景的人，所以題目通常不會太難。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Phone Interview: 電話面試，但我還真不知道有沒有公司現在還真的用電話，應該都是 con-call 了吧 XD。常見的是一題 coding interview，題目難度介於 OA 與 Onsite。當然還是因公司而異，也有遇到這關就是面系統/背景知識，亦或者混合。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Onsite Interview: 雖然在海外求職或疫情期間的我們，這個階段與 Phone Interview 的形式沒有太大的差別，但聽說在疫情前的美國學生是可以在這個階段拿到公司發的機票旅館，直接飛到當地參加面試並瞭解公司 (感覺好爽 XD)。這個階段也許對小公司來說只有一輪，不過對 Big tech. 應該都超過一輪面試，以 M/G 來說是四到六輪 (畢業生 4 場，社招 6 場)。在這個階段會因為你的職缺混合不同形式的面試，通常至少有 Coding Interview 與 Behavioral Interview，對於更高階的工程師可能還會參入 System Design Interview，或是跟你要進入的 team 全員磨合面試。走到這個階段時，並不會因為其中一兩次的狀態不好就停止面試，而是會讓你全部走完再來透過 interviewer 的 feedback 做綜合評估，因此聽說有一點表現不好的容錯範圍。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hiring Committee: 這個階段可能通常跟你沒有關係了，公司會透過 Onsite Interview 面試官寫的 feedback 去評估要不要錄用你。直得一提的是當你表現沒那麼突出，在比較 baseline 的狀態下，recruiter 可能會再跟你聯絡提供一些有利資料，最常見的就是成績單與內推信，所以雖說成績可能不是重點，但在這個時候確實還是有可能是讓你能跨過檻的關鍵。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="準備方法"&gt;準備方法&lt;/h2&gt;
&lt;h3 id="coding-interview"&gt;Coding interview&lt;/h3&gt;
&lt;h4 id="我的準備方法"&gt;我的準備方法&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;剛退伍時透過 Study Plan 把手感練回來，一開始速度真的很慢，每天就一兩題&lt;/li&gt;
&lt;li&gt;後來知道有 daily challenge 後，也會開始每天寫 daily&lt;/li&gt;
&lt;li&gt;開始配合 weekily contest 來了解自己在 leetcode 大概狀態&lt;/li&gt;
&lt;li&gt;後來訂閱 premium 後會寫 Interview -&amp;gt; Online Assessment，對我來說 1. 強迫我坐下來兩個小時想三題，也因此開始有碰到 hard (不然以前都直接跳過 hard 2.OA 寫完會出報告，大概評估你對不同主題的熟悉程度，以及你目前對面試 FAANG 還有多少程度差別&lt;/li&gt;
&lt;li&gt;參考網路文章後，透過
這個網站，把 Blind 75 沒寫的補完，寫完 B75 後有開始碰 NeetCode 150，不過截至目前還沒全部寫完。&lt;/li&gt;
&lt;li&gt;每題解完後會去看 solution 看看有沒有其他解法，另外也會點進排名看速度最快的人怎麼寫，我比較不會看 discussion，雖然可能可以看到很棒的解法或解釋，但我覺得時間 CP 值偏低，官方 Solution 就夠了，除非沒有才會去看 most voted discussion&lt;/li&gt;
&lt;li&gt;每周固定與朋友 Mock Interview，大該一周四次&lt;/li&gt;
&lt;li&gt;後來大概一天可以解到六到八題，如果 easy 多一點也許有機會十題&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="建議準備方法"&gt;建議準備方法&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;直接在 LeetCode 網頁上寫題目，並且不要開 Auto completion 來練習面試時沒有環境的狀況&lt;/li&gt;
&lt;li&gt;直接寫 Blind 75，每題設定時間在 20-30 分鐘內，寫不出來直接看解答，並透過 favorite list 記錄起來，等刷完一輪&lt;strong&gt;再回來重寫沒成功在時間內解出來的，如果還是無法繼續勾起來下次再回來直到都能在時限內解出來&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;理由: 剛開始刷題時很多時候是連需要的資料結構都沒有夠熟，在怎麼花時間想也很難想出來，直接看解答了解資料結構後刷完一輪再回來檢視有沒有把這個結構學起來比較有效率&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;跟 daily，保持刷提的手感，並且不像是 B75 一開始大概就知道要用哪種資料結構&lt;/li&gt;
&lt;li&gt;每周跟 weekily contest，用來大概了解自己在什麼程度，也可以逼你在兩個小時內要坐到寫出最後一題 (通常是比較水的 hard)&lt;/li&gt;
&lt;li&gt;如果有買 premium 了話偶爾可以寫 Interview -&amp;gt; Online Assessment，可以透過報告多少估算自己目前位置&lt;/li&gt;
&lt;li&gt;面試前一兩個禮拜針對要面試的公司刷最近常考題&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mock Interview&lt;/strong&gt;，這很重要，至少要練到流程熟悉 (流程可以參考
)，最好找同時要一起轉職 / 找工作的戰友互相練習，偶爾跟不同人練可以聽取不同的意見，這邊真的要特別特別感謝我的朋友與貴人，願意在工作之餘，還空出時間陪我一周四天的 Mock Interview。&lt;/li&gt;
&lt;li&gt;另外附上
，在面試 Google 時大概 300 題上下，但其實很多人沒刷多少題，或刷比我多的大有人在，所以這僅僅只是參考就好&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;Premium 不一定要買，被鎖的 Solution 可以看 Discussion 或上網找，公司常考題一樣可以看 Discussion 或上網抓，不過如果要密集刷題，panding 煩人程度 + Solution 的時間 CP 值 + OA 的統計數據我最終還是有買&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://calee0219.github.io/img/LeetCode_Assessment_Report.png" alt="Interview Assessment Report" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
LeetCode Premium 的 Interview -&amp;gt; Assessment 報告&lt;/p&gt;
&lt;h3 id="behavioral-interview"&gt;Behavioral interview&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Behavioral interview 並非技術性面試，而是會詢問你在團隊合作、工作文化、多元思想等問題。常見的題目可能是如何處理衝突、如何處理時間管理、你的優缺點、過去的經驗等，可以使用 STAR (situation, task, action, result) 的技巧回答&lt;/li&gt;
&lt;li&gt;Behavioral interview 反而是我比較不知道怎麼準備的部分，我主要是使用
這份請朋友問我，在問答的過程中去發想每個情境可以使用的經驗，並且我朋友也會提供給我一些 feedback&lt;/li&gt;
&lt;li&gt;比較特別的是 Amazon，通常其他公司 Behavioral 只會有一場，不過 Amazon 會有四場的 loop interview，並且會強調他希望的 Amazon 14 leadership principles，四場每場各 1hr，一樣會希望是透過 STAR 的形式回答&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="system-interview--os-interview"&gt;System interview / OS interview&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;由於我蠻多工作是面 SRE 相關的職缺，所以會被問到類似的問題，如果是一般 SWE 應該不會有&lt;/li&gt;
&lt;li&gt;Meta 對 New Grade 的問題主要偏向 OS 的問題，像是 booting process, virtual memory, IO, &amp;hellip;，另外可能會問實際上那些指令 / 操做對應到這些概念上&lt;/li&gt;
&lt;li&gt;有些時候會問你過去對系統的經驗，或是 troubleshooting 的能力&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="system-design-interview"&gt;System Design interview&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;System Design Interview 在 new grade 或 entry level 的職缺比較不太會被問到&lt;/li&gt;
&lt;li&gt;如果是標準的 system design interview 我自己是沒有很好的準備，所以也因此在 Booking 的面試中箭落馬，不過如果要我重新準備，我會推薦看
，並且惡補 YouTube 上別人分享的 system design interview 問與與回答&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="時間規劃"&gt;時間規劃&lt;/h2&gt;
&lt;p&gt;時間規劃上要掌握兩個原則，1. 盡可能同時拿到 offer 2. 不想去的先面試，當作面試練習。這兩個原則有時是蠻互相矛盾的，所以還是需要自己取捨。&lt;/p&gt;
&lt;p&gt;首先第二點應該很好理解，我自己的經驗也確實是越多次正式面試，後面的面試會越不緊張，Mock Interview 做再多次可能都沒有這樣的效果。再來就是要同時拿到 offer，其實也不難理解是為了 compete offer，首先通常越大的公司需要的 interview 流程越久，而越小的公司可能就越快，當然還是需要事前打聽一下比較好，了解大概的面試時間長度後，再根據其去調整丟履歷的時間，像是面完 Google 一面時丟可以兩個禮拜跑完的公司，當然其中還要考慮投出履歷到 recruiter 聯絡你可能還多少會有一些時間差，這部分可能就需要看你有沒有內推/打聽最近這家公司大概速度多快等。&lt;/p&gt;
&lt;p&gt;另外再差不多都面完等 offer 的時候，在一到兩個禮拜間結果會出來，如果超過兩個禮拜 recruiter 還沒聯絡你請務必寫信去確認，很高機會是他可能忘記了，當然也可能公司內部有其他異動，但提醒一下絕不會吃虧，而且也不要擔心會被 recruiter 嫌煩，recruiter 大部分的 performance 就是透過收到優秀的人才 (沒錯就是你) 來的。&lt;/p&gt;
&lt;p&gt;另外如果已經有想去的公司開獎了，也可以透過 email 來詢問結果是否出來 (&lt;del&gt;催 recruiter&lt;/del&gt;)，不過最好先想清楚這個時間是不是你想要開獎的時間，有時候催完開獎後，又發現想等另外一個還沒開獎的會比較尷尬。通常你寄信予 recruiter 表示手上已經有不錯的 offer，希望可以加快速度，recruiter 都會願意幫你快一點跟主管談。&lt;/p&gt;
&lt;p&gt;最後是拖，當你拿到口頭 accept 後，recruiter 通常會要求你在一定的時間內回他，標準是一個禮拜，比較雞掰的有三天，反正絕對不要當下回覆他，可以說你需要跟家人朋友討論，最少拖過一個假日，說你要跟朋友討論可是你的好朋友假日才有空。通常因為你更想去的公司還沒開獎或有辦法幫你做更好 compete 的還沒出來，這時候可以馬上寄信給還沒出來的公司表示已經有 offer 如果可以希望他們快一點。盡可能的手上拿到愈多的 offer。&lt;/p&gt;
&lt;h2 id="談薪"&gt;談薪&lt;/h2&gt;
&lt;p&gt;新鮮人相對會不好談薪水，但在怎麼難都還是建議一定要問，談出好的薪水不但可以讓接下來的工作可以拿比較好的薪水，同時也是你在跳到下一家公司時，談薪水的底氣。然而很多同學可能會怕談薪水是否顯示自己貪心而無法拿到 offer，對於這點有太多前輩的經驗告訴我們不會了，反而需要比較擔心的是無法談到好的 offer。&lt;/p&gt;
&lt;p&gt;首先我們要了解談薪水最主要是跟 recruiter 談而非直接跟主管談，然而你的 offer 是由面試你的人 and/or 主管給的，所以其實 offer 沒那麼容易被 recruiter 拿掉，另外聽說在部分公司 recruiter 的 performance 就是招攬人才的數量，其次才是可以用比較 fair 的薪水招到人，因此就算你喊太高，最多就是跟你表明無法給，同時如果你無法接受待遇，相信 recruiter 還是會盡量幫你爭取。&lt;/p&gt;
&lt;p&gt;流程上 recruiter 會跟你確認期望待遇，再去跟主管與 HR 部門相互協商出最終的待遇。想當然爾公司會希望出價(相對)低而員工會希望高，通常比起跟公司喊高，跟面試者喊低會比較簡單，但若面試者不能接受，recruiter 應該還是會向內部提出詢問。舉我自己的例子，其中一間公司一開始就有表明畢業生新人不能 compete，但由於一些誤會，讓 recruiter 以為我還是需要 compete 不然無法接受，當時 recruiter 還是有詢問我的預期以及表示會向內部討論，不過後來我沒有把握住機會就是另一個悲傷的故事了。&lt;/p&gt;
&lt;p&gt;有些公司制度上就是畢業生無法談，有規定好的 range，這時候還是可以透過問問看是否有 sign on bonus (簽約金) 來提高價碼。舉個例子，當初我朋友就有建議我可以跟 recruiter 表示如果給 sign on bonus 可以馬上答應並拒絕掉其他家公司。&lt;/p&gt;
&lt;p&gt;至於要怎麼談出好的 offer，其實目前我也不是很了解，不過可以確定的是談薪水就是透過誠實但資訊不對等來談，recruiter 有自己公司內部的狀況與了解追蹤市場行情的資訊，而你也有了解自己狀況與目前手上 offer 狀況。至於新人有什麼優勢呢? 最簡單的便是前面講的，一定要投多家公司，透過 compete offer 的狀態來談出好的薪水。以我的例子來說，背景比我漂亮的朋友當初由於沒有 compete，所以只拿到公司的 base，但有 compete 的我是拿到 1.2 倍，而且後來還有再往上談的機會。&lt;/p&gt;
&lt;h2 id="何時才算準備好"&gt;何時才算準備好&lt;/h2&gt;
&lt;p&gt;我會認為永遠沒有準備好的一天，看過各種 ACM / Conference 大神就都會覺得自己還有所不足，更何況我覺得台灣人可能因為教育的緣故，多少容易有
。但我們能做的就是提高自己的機率，而最簡單的做法就是不要害怕，這次沒上下次繼續投。其實就算沒有上，公司也不會像成績單有紀錄黑點，六個月後再投一次又是重來的狀況，請不要為此而擔心。所以我可能會建議，在想要投這些科技公司時，就先在日曆上寫好哪時候投，時間到了不管準備的怎麼樣都勇敢的上吧，因為我相信屆時你還是會覺得還沒準備好，可是永遠拖下去你就永遠沒有機會啊。&lt;/p&gt;
&lt;p&gt;如果真要說要怎麼衡量，我會認為把 Blind 75 做完 (每題都在 30 內解完) 基本上代表你的基礎功已經夠了，需要會的資料結構演算法都 ok 了，剩下的就是遇到題目時，可以想到適用哪一種資料結構，因此這時候我認為已經可以投了，並同時開始刷公司題增加對這個公司常考的題目的熟悉。&lt;/p&gt;
&lt;p&gt;另外如果有在跟 LeetCode 的 weekly contest，每次比賽 ranking 低於 2000 應該也可以是一個標準，有或是有訂閱 Premium 可以透過 Interview -&amp;gt; Assessment 來自我衡量，不過這些都只是參考用。&lt;/p&gt;
&lt;p&gt;我個人的經驗是在 Google Onsite 三場面試中，有兩場是 Medium 而另一場是 hard，我認為身為平常人，能做的就是把 Medium 把握好，hard 就只能隨緣了。另外在 cracking the coding interview 裡面也有講到，其實遇到 hard 不一定運氣比較差，因為你不會寫，別人也不會寫，如果可以表現出你的推導能力，讓面試官認為你是有潛力或多給你一些時間就能解出來，也許你就已經在候選人中脫穎而出了。&lt;/p&gt;
&lt;p&gt;最後試圖讓大家放心的是，Onsite Interview 的三場 coding interview 據說可以有一場的失手，算是面試時給的一個容錯，所以不要因為有一場沒有講好就影響到接下來的面試窩。&lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>位元運算</title><link>https://calee0219.github.io/blog/bit_manipulation/</link><pubDate>Wed, 23 Mar 2022 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/bit_manipulation/</guid><description>&lt;p&gt;最近迷上有趣的位元運算，發現原來有很多可玩的地方，所以就簡單紀錄一下
這裡幾乎都是以 32 bit 為主，若 64 bit 請自行擴充&lt;/p&gt;
&lt;h2 id="abs"&gt;ABS&lt;/h2&gt;
&lt;p&gt;取絕對值&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;int abs(int n) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return ((n &amp;gt;&amp;gt; 31) ^ n) - (n &amp;gt;&amp;gt; 31);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="count-1"&gt;Count 1&lt;/h2&gt;
&lt;p&gt;計算 1 存在的數量&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;int count_1(uint32_t n) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = (n &amp;amp; 0x55555555) + ((n &amp;amp; 0xAAAAAAAA) &amp;gt;&amp;gt; 1);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = (n &amp;amp; 0x33333333) + ((n &amp;amp; 0xCCCCCCCC) &amp;gt;&amp;gt; 2);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = (n &amp;amp; 0x0F0F0F0F) + ((n &amp;amp; 0xF0F0F0F0) &amp;gt;&amp;gt; 4);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = (n &amp;amp; 0x00FF00FF) + ((n &amp;amp; 0xFF00FF00) &amp;gt;&amp;gt; 8);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = (n &amp;amp; 0x0000FFFF) + ((n &amp;amp; 0xFFFF0000) &amp;gt;&amp;gt; 16);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return n;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;或用 &lt;code&gt;Brian Kernighan's Algorithm&lt;/code&gt;，此算法主要是由觀察 &lt;code&gt;n&lt;/code&gt; 與 &lt;code&gt;n-1&lt;/code&gt; 的 &lt;code&gt;&amp;amp;&lt;/code&gt; 會把最小非零位元歸零 &lt;code&gt;x..x10..0 &amp;amp; x..x01..1 = x..x00..0&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;int count_1(uint32_t n) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; int distance = 0;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; while (n != 0) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; distance += 1;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; // remove the rightmost bit of &amp;#39;1&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n &amp;amp;= n - 1;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return distance;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="pow-of-2"&gt;Pow of 2&lt;/h1&gt;
&lt;p&gt;簡單來說就是檢查 &lt;code&gt;Count 1 == 1&lt;/code&gt;，所以可以用前面的方法。&lt;/p&gt;
&lt;p&gt;但 &lt;code&gt;Brian Kernighan's Algorithm&lt;/code&gt; 的想法延伸可以找到更簡單作法，
&lt;code&gt;n&lt;/code&gt; 與 &lt;code&gt;n-1&lt;/code&gt;，如果 &lt;code&gt;n&lt;/code&gt; 呈現為 &lt;code&gt;xx...x10...0&lt;/code&gt;，而 &lt;code&gt;n-1&lt;/code&gt; 為 &lt;code&gt;xx..x01...1&lt;/code&gt;，相 &lt;code&gt;&amp;amp;&lt;/code&gt; 後為 &lt;code&gt;xx...x00...0&lt;/code&gt;，及 n 的最低位非 0 以下都會被壓縮成 0。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bool isPowerOfTwo(uint32_t n){
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return (n &amp;amp; (n-1)) == 0;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="swap"&gt;Swap&lt;/h2&gt;
&lt;p&gt;可以完成 in-placed swap&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;void swap(int *a, int *b) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; *a ^= *b;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; *b ^= *a;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; *a ^= *b;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="reverse-bits"&gt;Reverse Bits&lt;/h2&gt;
&lt;p&gt;將數字前後顛倒&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uint32_t reverseBits(uint32_t n) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = ((n &amp;amp; 0xFFFF0000) &amp;gt;&amp;gt; 16) | ((n &amp;amp; 0x0000FFFF) &amp;lt;&amp;lt; 16);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = ((n &amp;amp; 0xFF00FF00) &amp;gt;&amp;gt; 8) | ((n &amp;amp; 0x00FF00FF) &amp;lt;&amp;lt; 8);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = ((n &amp;amp; 0xF0F0F0F0) &amp;gt;&amp;gt; 4) | ((n &amp;amp; 0x0F0F0F0F) &amp;lt;&amp;lt; 4);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = ((n &amp;amp; 0xCCCCCCCC) &amp;gt;&amp;gt; 2) | ((n &amp;amp; 0x33333333) &amp;lt;&amp;lt; 2);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; n = ((n &amp;amp; 0xAAAAAAAA) &amp;gt;&amp;gt; 1) | ((n &amp;amp; 0x55555555) &amp;lt;&amp;lt; 1);
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return n;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="find-not-duplicate--find-difference"&gt;Find not duplicate / find difference&lt;/h2&gt;
&lt;p&gt;檢查字串裡沒有重複的字元 / 檢查兩字串的字元差(確定只有一個了話)。&lt;/p&gt;
&lt;p&gt;透過 xor 自己會得 0 的性質。&lt;/p&gt;
&lt;h1 id="reference"&gt;Reference&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>四月軍旅</title><link>https://calee0219.github.io/blog/compulsory_military_service/</link><pubDate>Wed, 02 Feb 2022 13:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/compulsory_military_service/</guid><description>&lt;p&gt;我是四個月的義務役，主要分為第一階段一個月的新兵訓練，以及第二階段下部隊三個月的軍事訓練役階段&lt;/p&gt;
&lt;h2 id="事前準備"&gt;事前準備&lt;/h2&gt;
&lt;p&gt;2021 年由於 COVID-19 疫情嚴重，於我畢業前後 (5 月開始)最為嚴重，臺灣疫情升到三級，整個兵役停招，因此我畢業時並沒有很確定我會何時當兵，沒想到大約九月底時突然收到區公所來電表示我排到 10/14 入伍，當時我也沒有特別想什麼，由於人在新竹，就請家人幫我代聽說明會。
到了 10/13 早上我才匆忙從新竹回到桃園做快篩，並於 14 早上到集合區做遊覽車出遊 (?)。可想而知其實我根本沒有上網查當兵注意事項或要帶的東西，還是很快地就度過了我的新訓生涯。&lt;/p&gt;
&lt;h2 id="一階段新訓"&gt;一階段新訓&lt;/h2&gt;
&lt;p&gt;我的新訓是在楊梅 109 旅 1 營 3 連，因為運氣好剛好遇到連假，所以是禮拜三才入營，新訓周 14 天少兩天。基本上第一周就是領領物品、寫寫資料、講講規定、教教軍歌等，另外也有辦一些招募活動，主要還是介紹不同單位在做的事情。&lt;/p&gt;
&lt;p&gt;大概第二周後開始有對鑑測要考的項目作教學，基本上主要都圍繞在單兵作戰上，包含口訣、動作、知識、防毒面具穿脫等，另外也有刺槍術的教學，基本上應該屬於就是一個過時的防技。另外有做一次的手榴彈投擲訓練，說實在真的訓練不足啊。打靶約有兩三次，每次都是簡單行軍到靶場，但由於靶場也沒有多遠所以基本上也不算是行軍，不過打靶確實蠻有趣的，雖然每次都要等很久。109 的伙食雖說還是屬於大鍋飯的類型，不過我個人覺得已經還算可以了，不過基本上我應該也算是不太挑食物的人 (但是要吃其實也可以吃很好 XD)。另外在鑑測前一兩周有開始督促大家被學科題目，由於太無聊了我還有把它抄下來
。基本上一天的作息就是早上 6:00 起床，6:20 集合做早操，約 7:00 下餐廳吃早餐。接下來早上的四節課，然後中午進餐廳，可以下餐廳後兩兩回寢室睡午覺，下午四堂課，晚上進餐廳，然後洗澡，最後接續晚上的課程，以及划手機時間，約九點到十點間就寢。比較有趣的點禮拜四晚上的莒光園地、早上記得折豆腐 (冬天時折豆腐，夏天折羊毛毯)、蚊帳、內務櫃整理、床下鋼盆擺放等。基本上新訓該有的都有，不該有的也大概沒有。&lt;/p&gt;
&lt;p&gt;我們旅比較特別的有包含因為是新建的旅，有特別一天介紹此旅的淵源，另外聽說班長很多都是從其他旅臨時調派過來協助。然後由於是全新訓營，所以沒有訓練役時全營只由幾個班長打掃，也是辛苦他們了。另外沒記錯在鑑測前就會抽下部隊的單位&lt;/p&gt;
&lt;p&gt;到了快一個月時便要鑑測，鑑測內容包含 學科、單戰、手榴彈投擲(野投、基投)、體適能 (伏地挺身、仰臥起坐)、大部分解結合、5000 公尺競走 (疫情關係)、175 打靶、刺槍術會&lt;/p&gt;</description></item><item><title>Cisco Router 設定</title><link>https://calee0219.github.io/blog/note_cisco_router/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_cisco_router/</guid><description>&lt;h3 id="password-recorivy"&gt;Password Recorivy&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Power ON, CTRL-break&lt;/li&gt;
&lt;li&gt;confreg 0x2142&lt;/li&gt;
&lt;li&gt;reload&lt;/li&gt;
&lt;li&gt;enable&lt;/li&gt;
&lt;li&gt;copy startup-config running-config&lt;/li&gt;
&lt;li&gt;no shutdown: open port&lt;/li&gt;
&lt;li&gt;change password&lt;/li&gt;
&lt;li&gt;config-register 0x2102: get back to normal boot&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="7609"&gt;7609&lt;/h2&gt;
&lt;h3 id="洗掉-config"&gt;洗掉 config&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;enable&lt;/li&gt;
&lt;li&gt;write erase&lt;/li&gt;
&lt;li&gt;reload&lt;/li&gt;
&lt;li&gt;這時候可能 default reboot 會進入 Romman 狀態，繼續下 boot 會來到正常狀態&lt;/li&gt;
&lt;li&gt;下 &lt;code&gt;configreg 0x2102&lt;/code&gt; (或 &lt;code&gt;configreg 0x2101&lt;/code&gt;) 讓開機直接進到正常狀態&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="reset"&gt;Reset&lt;/h3&gt;
&lt;h2 id="routing"&gt;Routing&lt;/h2&gt;
&lt;h3 id="vrrp"&gt;vrrp&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;作 gateway 備援使用&lt;/li&gt;
&lt;li&gt;有三種狀態 &lt;code&gt;初始狀態(Initialize)&lt;/code&gt;、&lt;code&gt;主狀態(Master)&lt;/code&gt;、&lt;code&gt;備援狀態(Backup)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="nx-os"&gt;NX-OS&lt;/h2&gt;
&lt;h3 id="沒有權限時重設-admin-密碼"&gt;沒有權限時，重設 admin 密碼&lt;/h3&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;開機&lt;/li&gt;
&lt;li&gt;按 &lt;code&gt;ctrl-C&lt;/code&gt; 或 &lt;code&gt;ctrl-R&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;進入 &lt;code&gt;loader&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;loader&amp;gt; dir&lt;/code&gt; 看有哪些 boot file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;boot n3000-xxx&lt;/code&gt; 選擇你要 boot 的檔案 (可能選有 kickstart 的)&lt;/li&gt;
&lt;li&gt;進入 &lt;code&gt;switch(boot)#&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;conf t&lt;/code&gt; -&amp;gt; &lt;code&gt;admin-password&lt;/code&gt; -&amp;gt; 輸入 admin 密碼 -&amp;gt; &lt;code&gt;exit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dir bootflash:&lt;/code&gt; 列出有的開機檔案&lt;/li&gt;
&lt;li&gt;&lt;code&gt;load bootflash:n3000-xxx&lt;/code&gt; 選擇以 xx 檔案開機&lt;/li&gt;
&lt;li&gt;帳號: admin, 密碼: 剛剛設定的&lt;/li&gt;
&lt;li&gt;進入系統後，記得要把 kickstart 與 system 指向對的地方&lt;/li&gt;
&lt;li&gt;&lt;code&gt;conf t&lt;/code&gt; -&amp;gt; &lt;code&gt;boot kickstart n3000-xxx&lt;/code&gt; -&amp;gt; &lt;code&gt;boot system n3000-kickstart-xxx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如果沒做上面的動作，有可能 &lt;code&gt;reload&lt;/code&gt; 後會回到 &lt;code&gt;loader&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="恢復原廠設定"&gt;恢復原廠設定&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;enable&lt;/li&gt;
&lt;li&gt;write erase&lt;/li&gt;
&lt;li&gt;reload&lt;/li&gt;
&lt;li&gt;如果 reload 卡在 loader，做上面的動作，並記得指向正確的 system 與 kickstart&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Cisco Switch 設定</title><link>https://calee0219.github.io/blog/note_cisco_switch/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_cisco_switch/</guid><description>&lt;h2 id="2960"&gt;2960&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="document"&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;不知道後面接啥就 &amp;ldquo;?&amp;rdquo; 一下嚕~~&lt;/li&gt;
&lt;li&gt;Vlan31: 17網段&lt;/li&gt;
&lt;li&gt;Vlan14: 168網段&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="刷新"&gt;刷新&lt;/h3&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;開機時長按 mode 鍵，直到燈號快閃&lt;/li&gt;
&lt;li&gt;flash_init&lt;/li&gt;
&lt;li&gt;del flash:config.text&lt;/li&gt;
&lt;li&gt;del flash:vlan.dat&lt;/li&gt;
&lt;li&gt;boot&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="console"&gt;Console&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;connect
&lt;ul&gt;
&lt;li&gt;Serial -&amp;gt; Serial port(在裝置管理員看的到) -&amp;gt; 9600&lt;/li&gt;
&lt;li&gt;screen /dev/tty.usbmodem145231 9600&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;跳過init自己設&lt;/li&gt;
&lt;li&gt;show version: 看版本
&lt;/li&gt;
&lt;li&gt;logging synchronous: 避免 log 擋住正在打的訊息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="command"&gt;Command&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;copy running-config startup-config: 存config&lt;/li&gt;
&lt;li&gt;enable/disable: 可以開始寫入/結束&lt;/li&gt;
&lt;li&gt;clock set {hh:mm:ss} {day} {month} {year}: 設定時間&lt;/li&gt;
&lt;li&gt;show running-config&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="config"&gt;Config&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;config t: 進入改 config 模式 (下列的指令都要在 config 模式下修改)&lt;/li&gt;
&lt;li&gt;hostname {myhostname}&lt;/li&gt;
&lt;li&gt;clock timezone CST 8 (CST 只是名字，沒有意義)&lt;/li&gt;
&lt;li&gt;no ip http server: 將 HTTP server 關掉&lt;/li&gt;
&lt;li&gt;no ip http secure-server&lt;/li&gt;
&lt;li&gt;username {name} password {clear password}: 設定帳號密碼&lt;/li&gt;
&lt;li&gt;service password-encryption: 密碼加密&lt;/li&gt;
&lt;li&gt;spanning-tree mode rapid-pvst: 使用 rapid-pvst 網路拓樸&lt;/li&gt;
&lt;li&gt;service timestamps log datetime localtime year show-timezone: 讓 log 有時間戳記&lt;/li&gt;
&lt;li&gt;ip name-server {CC 的 nameserver(140.113.235.1)}: 讓 DNS work&lt;/li&gt;
&lt;li&gt;ip default-gateway {通常網段最後一個}&lt;/li&gt;
&lt;li&gt;ntp server ntp.cc.cs.nctu.edu.tw: 設ntp server&lt;/li&gt;
&lt;li&gt;security passwords min-length 8: pw 最短長度&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="ssh-setting"&gt;ssh setting&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ip domain-name {your domain}&lt;/li&gt;
&lt;li&gt;ip ssh version 2: 用 version 2 的 ssh server&lt;/li&gt;
&lt;li&gt;crypto key generate rsa
&lt;ul&gt;
&lt;li&gt;打自己喜歡的數字&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;line vty 0 15&lt;/li&gt;
&lt;li&gt;transport input ssh&lt;/li&gt;
&lt;li&gt;login local&lt;/li&gt;
&lt;li&gt;username {name} privilege 15 password {pw}: 直接把權限提到最高 (15)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="限制連線-ip-config-t"&gt;限制連線 ip (config t)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;access-list 1 permit host {ip}: 在 access-list 1 下設定 access 規則 (只允許某 ip 連入)&lt;/li&gt;
&lt;li&gt;line vty 0 15: 進入 vty&lt;/li&gt;
&lt;li&gt;access-class 1 in: 限制只有 access-list 1 下的規則才能連進來(in)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="vlan-setting"&gt;Vlan setting&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;interface Vlan 31&lt;/li&gt;
&lt;li&gt;ip address {your IP} {your mask}: 將 Vlan 對上 static ip&lt;/li&gt;
&lt;li&gt;no shutdown: 不要關掉這個 Vlan&lt;/li&gt;
&lt;li&gt;no interface Vlan{num}: 如果不小心開啟不要的 interface，可以用這個指令把他關掉&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="網路孔"&gt;網路孔&lt;/h3&gt;
&lt;h4 id="將-port-接到-vlan-上"&gt;將 port 接到 Vlan 上&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;interface gigabitEthernet 0/1: 進入 no.1 port&lt;/li&gt;
&lt;li&gt;interface range gigabitEthernet 0/1 - 24: 上面的range版&lt;/li&gt;
&lt;li&gt;switchport access vlan 31: 將 port 接到 Vlan 31 上&lt;/li&gt;
&lt;li&gt;shutdown: 如果要那個 port 不能連網，記得要關掉&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="trunk"&gt;trunk&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;interface gigabitEthernet 0/48&lt;/li&gt;
&lt;li&gt;switchport mode trunk&lt;/li&gt;
&lt;li&gt;switchport access vlan {Vlan id}: 當 trunks 不 works 時，該用那一個 vlan &amp;lt;- 但是如果用 switchport mode trunk，就不會有這個問題 (trunk 死掉就直接死掉)&lt;/li&gt;
&lt;li&gt;switchport trunk allowed vlan 14,31&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="描述"&gt;描述&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;interface gigabiteEthernet 0/1: 進入 port&lt;/li&gt;
&lt;li&gt;description {要寫的描述}&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3750"&gt;3750&lt;/h2&gt;
&lt;h3 id="connect"&gt;Connect&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;mac
&lt;ul&gt;
&lt;li&gt;screen /dev/tty.usb&amp;hellip; 9600&lt;/li&gt;
&lt;li&gt;或者下載
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Windows&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="reset"&gt;Reset&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;指令
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;en&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# write earse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# reload&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;System&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;been&lt;/span&gt; &lt;span class="n"&gt;modified&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Save&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;yes&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Proceed&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;reload&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Model&lt;/span&gt; &lt;span class="n"&gt;revision&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;02&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Would&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;like&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;enter&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;initial&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt; &lt;span class="n"&gt;dialog&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;yes&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;物理&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="misc"&gt;Misc&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;no ip domain-lookup&lt;/code&gt;: 關閉 DNS 查詢功能&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;預設情況下，Router的DNS查詢是啟用的&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;當輸入Cisco IOS無法識別的指令時，Router會把這個指令視為主機名稱，然後向DNS查詢。&lt;/li&gt;
&lt;li&gt;但是這個無用的查詢是非常耗時的，若沒有需要可以關閉!!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;switch 1 provision ws-c3750g-24ts&lt;/code&gt;: 3750 可以作 stack，這個跟這台 3750 是在 stack 上的哪一台有關&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>DHCP 設定</title><link>https://calee0219.github.io/blog/note_dhcp/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_dhcp/</guid><description>&lt;h2 id="server"&gt;Server&lt;/h2&gt;
&lt;h3 id="centos"&gt;CentOS&lt;/h3&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;lease: /var/lib/dhcpd/dhcpd.leases&lt;/li&gt;
&lt;li&gt;config: /etc/dhcp/dhcpd.conf
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;option domain-name &amp;#34;calee.xyz&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;option domain-name-servers 140.113.235.1, 1.1.1.1, 9.9.9.9, 8.8.8.8;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;default-lease-time 600;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;max-lease-time 7200;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# Use this to send dhcp log messages to a different log file (you also
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# have to hack syslog.conf to complete the redirection).
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;log-facility local7;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# A slightly different configuration for an internal subnet.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;subnet 192.168.1.0 netmask 255.255.255.0 {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; range 192.168.1.0 192.168.1.254;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; option domain-name-servers 140.113.235.1, 1.1.1.1;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; option domain-name &amp;#34;pve.calee.xyz&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; option routers 192.168.1.1;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; option broadcast-address 192.168.1.254;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; default-lease-time 600;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; max-lease-time 7200;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;host DESKTOP-A6UOSVB {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; hardware ethernet 82:20:3d:cf:32:79;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; fixed-address 192.168.1.2;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;host DESKTOP-04E99PF {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; hardware ethernet 72:0e:c8:c3:6c:1c;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; fixed-address 192.168.1.3;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="client"&gt;Client&lt;/h2&gt;
&lt;h3 id="linux"&gt;Linux&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Renew: &lt;code&gt;dhclient -r&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="windows"&gt;Windows&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Renew: &lt;code&gt;ipconfig /renew&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="macos"&gt;MacOS&lt;/h3&gt;</description></item><item><title>Docker</title><link>https://calee0219.github.io/blog/docker/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/docker/</guid><description>&lt;h2 id="參考資料"&gt;參考資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="安裝"&gt;安裝&lt;/h2&gt;
&lt;h3 id="ubuntu"&gt;Ubuntu&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;transport&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt; &lt;span class="n"&gt;ca&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;certificates&lt;/span&gt; &lt;span class="n"&gt;curl&lt;/span&gt; &lt;span class="n"&gt;software&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;common&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;curl&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;fsSL&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;linux&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ubuntu&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gpg&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;repository&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ce&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="centos"&gt;CentOS&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;yum&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;yum&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;utils&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;persistent&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="n"&gt;lvm2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;yum&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;manager&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;linux&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;centos&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ce&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;yum&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ce&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="單位"&gt;單位&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;映像檔(image)
&lt;ul&gt;
&lt;li&gt;類似 docker 的模板&lt;/li&gt;
&lt;li&gt;image 類似模板，要用 image 開出來的 container 才能用&lt;/li&gt;
&lt;li&gt;名詞
&lt;ul&gt;
&lt;li&gt;NAME&lt;/li&gt;
&lt;li&gt;DESCRIPTION: 描述&lt;/li&gt;
&lt;li&gt;AUTOMATED&lt;/li&gt;
&lt;li&gt;REPOSITORY (倉庫)&lt;/li&gt;
&lt;li&gt;TAG: 標記，通常會存版本號&lt;/li&gt;
&lt;li&gt;IMAGE ID: image 被抓下來時，隨機產生的唯一 ID&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dockerfile
&lt;ul&gt;
&lt;li&gt;將 docker 與相關安裝執行指令寫成操作檔案&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;容器(container)
&lt;ul&gt;
&lt;li&gt;建立出來的執行實力&lt;/li&gt;
&lt;li&gt;基本上是基於 image 在跑得 =&amp;gt; 開出 container 後不能將 image 刪掉，or 可能會跑不動&lt;/li&gt;
&lt;li&gt;可以用 image 創&lt;/li&gt;
&lt;li&gt;可以用 Dockerfile 創&lt;/li&gt;
&lt;li&gt;可以被啟動、開始、停止、刪除&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;倉庫(Registry)
&lt;ul&gt;
&lt;li&gt;Public Hub
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Private Hub&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="指令"&gt;指令&lt;/h2&gt;
&lt;h3 id="hub"&gt;Hub&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker search [image]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;從 Docker Hub 上搜尋是否有相關名字的 docker image&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker pull [image]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;將 docker image 從 Docker Hub 上下載下來&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker login&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;登入 Docker Hub&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker push [image]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;把 docker image 推上 Docker Hub&lt;/li&gt;
&lt;li&gt;基本上倉儲相關指令與 Git 相同&lt;/li&gt;
&lt;li&gt;注意：docker push 必須有 namespace，也就是當初對 images 命名時，要記的命成 &lt;code&gt;username/imagename&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="image"&gt;Image&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker images&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;將所有的 docker image 列出&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker run [image]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;啟動一個 container&lt;/li&gt;
&lt;li&gt;通常後面會接一個操作指令，操作完就結束 container
&lt;ul&gt;
&lt;li&gt;e.g. &lt;code&gt;docker run Ubuntu /bin/echo &amp;quot;Hello World&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt;: 標準輸入保持打開&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-t&lt;/code&gt;: 讓Docker分配一個虛擬終端（pseudo-tty）並綁定到容器的標準輸入上&lt;/li&gt;
&lt;li&gt;通常 -i -t 會合用
&lt;ul&gt;
&lt;li&gt;e.g. &lt;code&gt;docker run -t -i Ubuntu /bin/bash&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-d&lt;/code&gt;: 進入背景執行&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker rmi [image]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;刪除 image&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;OPTIONS
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--author, -a&lt;/code&gt;: 作者&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--message, -m&lt;/code&gt;: commit message&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;container
&lt;ul&gt;
&lt;li&gt;要 commit 的 container =&amp;gt; commit 完後便會變成新的 image&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;REPOSITORY
&lt;ul&gt;
&lt;li&gt;如果想要對產出的 image 做命名&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker load/save IMAGE&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;匯入 or 匯出(儲存) image (像是存成 .tar)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker build [Dockerfile]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;從 Dockerfile 編譯&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="container"&gt;Container&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker ps&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;列出目前在執行的 container&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-a&lt;/code&gt;: 列出全部的 container(包含關機的)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker start [CONTAINER ID / CONTAINER NAME]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;啟動關機的 container&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker stop [CONTAINER ID / CONTAINER NAME]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;container 關機&lt;/li&gt;
&lt;li&gt;關機後會留下殘骸 =&amp;gt; 可以再次開啟&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker restart [CONTAINER ID / CONTAINER NAME]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;重新開機&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker logs [CONTAINER ID / CONTAINER NAME]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;列出這個 container 曾經的 stander output&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker exec [CONTAINER ID / CONTAINER NAME]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;將在背景執行的 container 提出來&lt;/li&gt;
&lt;li&gt;通常配合 &lt;code&gt;-i -t&lt;/code&gt;，回到互動視窗&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker rm [CONTAINER ID / CONTAINER NAME]&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;刪除 conatiner&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker import / export CONTAINER&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;匯入 or 匯出 container&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o NAME.tar&lt;/code&gt;: 指定匯出格式 (ex .tar)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="data-volumes"&gt;Data Volumes&lt;/h3&gt;
&lt;p&gt;分別有 Data Volumes 與 Data Valume Container 兩種&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Data Valumes
&lt;ul&gt;
&lt;li&gt;將主機目錄對應到容器中，類似 mount&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker run -v {容器內資料夾} IMAGE&lt;/code&gt;: 會在主機內建一個資料夾掛載上去&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker run -v {主機內資料夾}:{容器內資料夾} IMAGE&lt;/code&gt;: 直接用已存在的資料夾掛載&lt;/li&gt;
&lt;li&gt;可以多個容器掛載到同一個主機資料夾&lt;/li&gt;
&lt;li&gt;多個 &lt;code&gt;-v&lt;/code&gt; 參數可以掛載多個資料夾&lt;/li&gt;
&lt;li&gt;容器內資料夾一定要是絕對路徑，主機則不一定&lt;/li&gt;
&lt;li&gt;預設為 rw，可用 &lt;code&gt;docker run -v {主機內資料夾}:{容器內資料夾}:ro IMAGE&lt;/code&gt; 改成唯讀&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Data Valume Container&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="attach-device"&gt;Attach Device&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;USB:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker run --device=/dev/ttyUSB0 -it ubuntu /bin/bash&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;NVIDIA GPU:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker run --device=/dev/nvidia0 -it ubuntu /bin/bash&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="restful-api"&gt;RESTful API&lt;/h2&gt;
&lt;p&gt;修改 &lt;code&gt;/etc/docker/daemon.json&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;live-restore&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;group&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dockerroot&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;insecure-registries&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;0.0.0.0:5000&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;hosts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;unix:///var/run/docker.sock&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;tcp://0.0.0.0:2375&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以 &lt;code&gt;jupyter/tensorflow-notebook&lt;/code&gt; 為例，開啟 RESTful api 後，docker CLI 指令要用 Root 執行&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo docker pull jupyter/tensorflow-notebook
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;修改完後，重啟 docker service: &lt;code&gt;sudo systemctl restart docker&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;參考:
&lt;/li&gt;
&lt;li&gt;參考:
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="操作"&gt;操作&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker version&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -X GET http://localhost:2375/version
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker pull jupyter/tensorflow-notebook&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -X POST http://localhost:2375/images/create?fromImage=jupyter/tensorflow-notebook
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker images&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -X GET http://localhost:2375/images/json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker create -p 8080:80 jupyter/tensorflow-notebook&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -H &amp;#34;Content-Type: application/json&amp;#34; http://0.0.0.0:2375/containers/create?name=tensor -d &amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;Image&amp;#34;: &amp;#34;jupyter/tensorflow-notebook&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;HostConfig&amp;#34;:{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;Memory&amp;#34;: 4194304,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;NanoCPUs&amp;#34;: 2000000000,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;PortBindings&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;80/tcp&amp;#34;: [{&amp;#34;HostPort&amp;#34;: &amp;#34;8080&amp;#34;}]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;Dns&amp;#34;: [&amp;#34;8.8.8.8&amp;#34;],
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;Devices&amp;#34;: [{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;PathOnHost&amp;#34;: &amp;#34;/dev/nvidia0&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;PathInContainer&amp;#34;: &amp;#34;/dev/nvidia0&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;CgroupPermissions&amp;#34;: &amp;#34;rwm&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker ps -a&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -X GET http://localhost:2375/containers/json?all=true
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker start tensor&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -X POST http://localhost:2375/containers/tensor/start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker stop tensor&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -X POST http://localhost:2375/containers/tensor/stop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker rm tensor&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -X DELETE http://localhost:2375/containers/tensor?v=true
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;
&lt;/p&gt;
&lt;h2 id="nvidia-docker"&gt;Nvidia-docker&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有 cuda 但沒有 cudnn&lt;/li&gt;
&lt;li&gt;魔改
&lt;ul&gt;
&lt;li&gt;下載 cudnn:
&lt;/li&gt;
&lt;li&gt;解安裝到 jupyter/driver (之後會一起 mount 進 container):
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tar -xzvf cudnn-9.0-linux-x64-v7.tgz
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;開啟一個 container volumn
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker volumn create cudnn
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;把 container volumn 與 jupyter folder 同時 mount 入 container
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run --runtime=nvidia -v /home/intern2018/NCHC-docker-test/jupyter:/jupyter -v cudnn:/cudnn -it calee0219/jupyter-docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;照 doc 安裝 cudnn (複製貼上、修改權限):
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cp /jupyter/driver/cuda/include/cudnn.h /usr/local/cuda/include
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cp /jupyter/driver/cuda/lib64/libcudnn* /usr/local/cuda/lib64
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod a+r /usr/local/cuda/include/cudnn.h /usr/local/cuda/lib64/libcudnn*
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;測試
&lt;ul&gt;
&lt;li&gt;改環境變數指向
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;LD_LIBRARY_PATH&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cuda&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib64&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;LD_LIBRARY_PATH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;測試 script
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import sys
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import numpy as np
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;import tensorflow as tf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;from datetime import datetime
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;device_name = sys.argv[1] # Choose device from cmd line. Options: gpu or cpu
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;shape = (int(sys.argv[2]), int(sys.argv[2]))
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;if device_name == &amp;#34;gpu&amp;#34;:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; device_name = &amp;#34;/gpu:0&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;else:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; device_name = &amp;#34;/cpu:0&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;with tf.device(device_name):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; random_matrix = tf.random_uniform(shape=shape, minval=0, maxval=1)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dot_operation = tf.matmul(random_matrix, tf.transpose(random_matrix))
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sum_operation = tf.reduce_sum(dot_operation)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;startTime = datetime.now()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as session:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; result = session.run(sum_operation)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; print(result)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# It can be hard to see the results on the terminal with lots of output -- add some newlines to improve readability.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;print(&amp;#34;\n&amp;#34; * 5)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;print(&amp;#34;Shape:&amp;#34;, shape, &amp;#34;Device:&amp;#34;, device_name)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;print(&amp;#34;Time taken:&amp;#34;, str(datetime.now() - startTime))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;將 &lt;code&gt;/usr/local/cuda/&lt;/code&gt; 全部丟入 container volumn 內
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cp /usr/local/cuda/* /cudnn
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;之後都把 container volumn mount 到 &lt;code&gt;/usr/local/cuda/&lt;/code&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run --runtime=nvidia -v /home/intern2018/NCHC-docker-test/jupyter:/jupyter -v cudnn:/usr/local/cuda/ -it calee0219/jupyter-docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="dockerfile"&gt;Dockerfile&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="gpu"&gt;GPU&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;--divice=/dev/nvidia0&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Docker 實作 PoW</title><link>https://calee0219.github.io/blog/cryptocurrency_ethereum_pow_w_docker/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/cryptocurrency_ethereum_pow_w_docker/</guid><description>&lt;h2 id="安裝"&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker pull calee0219/ca_geth&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;更好的版本 XD
&lt;code&gt;docker pull blakeberg/geth-node&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="快速安裝"&gt;快速安裝&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;使用
&lt;/li&gt;
&lt;li&gt;這樣就可以開始挖 CACoin 啦~&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker run ca_geth -t /root/init_start.sh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="叢集版本"&gt;叢集版本&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="安裝-1"&gt;安裝&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;docker
詳情請看
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;執行 &amp;amp; 進入 ubuntu docker&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run --name first_node -i -t ubuntu /bin/bash &lt;span class="c1"&gt;# 這個 docker 是用來跑私鏈的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;docker 內安裝 geth&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;升級 ubuntu apt-get&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt-get upgrade
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;安裝 geth&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt-get install software-properties-common
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;add-apt-repository -y ppa:ethereum/ethereum
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt-get install ethereum
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="以上動作"&gt;以上動作&lt;/h3&gt;
&lt;p&gt;你也可以考慮直接使用
，裡面的功能更完備 XD&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull blakeberg/geth-node
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -d -h geth --name geth -p 20022:22 -p 8545:8545 blakeberg/geth-node
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh geth@localhost -p &lt;span class="m"&gt;20022&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="撰寫創世區塊-genesis"&gt;撰寫創世區塊 (Genesis)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;利用 &lt;code&gt;puppeth&lt;/code&gt; 幫助撰寫&lt;/li&gt;
&lt;li&gt;照著互動式指令即可
&lt;ol&gt;
&lt;li&gt;下 &lt;code&gt;puppeth&lt;/code&gt; 指令&lt;/li&gt;
&lt;li&gt;對此創世區塊命名&lt;/li&gt;
&lt;li&gt;選擇 2 新增設定檔&lt;/li&gt;
&lt;li&gt;選擇 1 PoW&lt;/li&gt;
&lt;li&gt;若希望有一開始就存在的節點，將其節點地址複製到此，最後保留一個 0x 結束&lt;/li&gt;
&lt;li&gt;設定 network id (留白則會預設 random)&lt;/li&gt;
&lt;li&gt;其他想要設定的資訊&lt;/li&gt;
&lt;li&gt;選擇 2 儲存設定檔&lt;/li&gt;
&lt;li&gt;Ctrl-C 結束設定&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="架設節點"&gt;架設節點&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;初始化節點
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;geth --datadir &amp;quot;./[資料存放資料夾]&amp;quot; --networkid [剛剛設定的 networdid] --rpc init [創世區塊.json]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;出現 &amp;ldquo;successfully wrote genesis block and/or chain rule set:&amp;hellip;&amp;rdquo; 字樣則成功開啟&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--maxpeers&lt;/code&gt;: 最多可連結點數&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--nodiscover&lt;/code&gt;: 不可讓一般人找到 (需要手動加入節點)
&lt;ul&gt;
&lt;li&gt;在 geth 指令加入 &lt;code&gt;--bootnodes&lt;/code&gt; 參數&lt;/li&gt;
&lt;li&gt;進到 console 裡使用 &lt;code&gt;admin.addPeer()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;存成 static-nodes.json 檔，讓geth自動連線&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--netrestrict&lt;/code&gt;: 讓節點只會接受在指定IP子網域內的連線&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--rpc&lt;/code&gt;: 启动 rpc 通信，可以进行智能合约的部署和调试&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;新增帳戶(account)
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;geth account new&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;也可以在 js console 裡下 &lt;code&gt;personal.newAccount(&amp;quot;passphrase&amp;quot;)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;預設位置是放在 &lt;code&gt;./ethereum/keystorm&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--datadir&lt;/code&gt;: 設定檔放置位置&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;啟動並進入節點 console
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;geth --datadir &amp;quot;./[資料存放資料夾]&amp;quot; --networkid [剛剛設定的 networdid] console --mine&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;最後面也可以不用加 console&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--rpc&lt;/code&gt;: 啟動 rpc 通信，可以进行智能合約的部署和調適&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--rpcaddr&lt;/code&gt;: default rpc ip 是 0.0.0.0，只有內部網路才能連，加 &lt;code&gt;--rpcaddr {ip}&lt;/code&gt; 後，rpc 的 port 才會是外部也可以連，只是可能會不安全&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--rpcport&lt;/code&gt;: 指定 rpc port&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="啟動其他節點"&gt;啟動其他節點&lt;/h2&gt;
&lt;p&gt;其實就是 架設節點&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;節點初始化
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;geth --datadir &amp;quot;./[資料存放資料夾]&amp;quot; --networkid [剛剛設定的 networdid] --bootnodes enode://[主鏈 id]@[主鏈 ip]:30303 console --mine&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;30303: 預設 port&lt;/li&gt;
&lt;li&gt;主機 ip: docker 了話，可以使用 &lt;code&gt;docker inspect [container name] | grep IPAddress&lt;/code&gt; 來查找 container 被配置的區域 ip&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--mine&lt;/code&gt;: 直接開始 mining&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--bootnodes&lt;/code&gt;: 若不加入這個參數，節點可能會需要在網路上找其他節點找很久&lt;/li&gt;
&lt;li&gt;主鏈 id: 可以用 &lt;code&gt;admin.nodeInfo&lt;/code&gt; 查找&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;新增帳戶(account)
&lt;ul&gt;
&lt;li&gt;一定要有帳戶才能收到挖礦的 $$ 啊～～～&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;啟動節點
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;geth --datadir &amp;quot;./[資料存放資料夾]&amp;quot; --networkid [剛剛設定的 networdid] console --mine&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="確認節點同步"&gt;確認節點同步&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;net.listening&lt;/code&gt;: 確認是否有在監聽其他節點&lt;/li&gt;
&lt;li&gt;&lt;code&gt;net.peerCount&lt;/code&gt;: 監聽其他節點數&lt;/li&gt;
&lt;li&gt;&lt;code&gt;admin.peers&lt;/code&gt;: 查看節點資訊&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="檢查錢包"&gt;檢查錢包&lt;/h2&gt;
&lt;p&gt;這是最重要的 XD
&lt;code&gt;web3.fromWei(eth.getBalance(eth.coinbase), &amp;quot;ether&amp;quot;)&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="交易"&gt;交易&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;參數版
&lt;code&gt;eth.sendTransaction({from: eth.coinbase, to: &amp;quot;0x154230ed91d1e711e56b9c0f88b5ba5fd2b0503f&amp;quot;, value: web3.toWei(1, &amp;quot;ether&amp;quot;),gas:22000,gasPrice:web3.toWei(45,&amp;quot;Shannon&amp;quot;),data: web3.toHex('ZeroCool')})&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;簡單版
&lt;code&gt;eth.sendTransaction({from: eth.coinbase, to: &amp;quot;0x154230ed91d1e711e56b9c0f88b5ba5fd2b0503f&amp;quot;, value: web3.toWei(1, &amp;quot;ether&amp;quot;)})&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ether Explorer 架設</title><link>https://calee0219.github.io/blog/cryptocurrency_ethereum_explorer/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/cryptocurrency_ethereum_explorer/</guid><description>&lt;h2 id="explorer"&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;提供類似 EtherScan 的功能&lt;/li&gt;
&lt;li&gt;用 pulling 的方式更新，效能較差&lt;/li&gt;
&lt;li&gt;UI 好看&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="安裝"&gt;安裝&lt;/h3&gt;
&lt;h4 id="前處理"&gt;前處理&lt;/h4&gt;
&lt;p&gt;需要先有 npm, bower&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install nodejs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install npm
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install bower
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;geth 需要開 rpc&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;geth --rpc --rpcaddr localhost --rpcport 8545 --rpcapi &amp;#34;web3,eth&amp;#34; --rpccorsdomain &amp;#34;http://localhost:8000&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--rpc&lt;/code&gt;: 把 rpc 開出來&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--rpcaddr&lt;/code&gt;: 指定 rpc 可以吃得 address，不寫 default 是 localhost&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--rpcport&lt;/code&gt;: 指定 rpc port，不寫 default 是 8545&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--rpcapi&lt;/code&gt;: 指定 rpc 提供的服務&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--rpccorsdomain&lt;/code&gt;: CORS domain，詳見
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="軟題"&gt;軟題&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/carsenk/explorer
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cd explorer
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;bower install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="啟動"&gt;啟動&lt;/h4&gt;
&lt;p&gt;建議先開個 tmux 或 screen&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install tmux
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmux
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cd explorer # 如果沒有在專案資料夾內，需要記得進去
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;到這裡，基本上就能在自己的電腦上的 http://localhost:8000 上看到 explorer 了&lt;/p&gt;
&lt;h4 id="如果還想讓別人看到了話"&gt;如果還想讓別人看到了話：&lt;/h4&gt;
&lt;h5 id="geth-部分"&gt;geth 部分&lt;/h5&gt;
&lt;p&gt;要把 loopback 的 localhost 改掉&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;geth --rpc --rpcaddr 你的對外 ip&lt;span class="o"&gt;(&lt;/span&gt;或者 0.0.0.0&lt;span class="o"&gt;)&lt;/span&gt; --rpcport &lt;span class="m"&gt;8545&lt;/span&gt; --rpcapi &lt;span class="s2"&gt;&amp;#34;web3,eth&amp;#34;&lt;/span&gt; --rpccorsdomain &lt;span class="s2"&gt;&amp;#34;你的 domain (或者 *)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果你都看不懂，可以考慮直接寫&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;geth --rpc --rpcaddr 0.0.0.0 --rpcport &lt;span class="m"&gt;8545&lt;/span&gt; --rpcapi &lt;span class="s2"&gt;&amp;#34;web3,eth&amp;#34;&lt;/span&gt; --rpccorsdomain &lt;span class="s2"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h5 id="explorer-部分"&gt;explorer 部分&lt;/h5&gt;
&lt;p&gt;修改 &lt;code&gt;app/app.js&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsx" data-lang="jsx"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;GETH_HOSTNAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;your-domain/ip&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// put your IP address!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h5 id="其他"&gt;其他&lt;/h5&gt;
&lt;p&gt;如果有開防火牆，記得把規則加進去&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 8545/tcp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw allow 8000/tcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;可以考慮直接把 8000 port 開出去給別人&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果是用 private ip，記得確認上層 NAT port forwarding 是否有把 port 開起來&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;也可以考慮用 nginx proxy 出去
nginx 設定 &lt;code&gt;/etc/nginx/sites-enabled/etherexplorer.conf&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;server {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; listen 80;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; server_name your-domain;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; location / {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_pass http://localhost:8000;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_http_version 1.1;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_set_header Upgrade $http_upgrade;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_set_header Connection &amp;#34;upgrade&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="etherchain-light"&gt;
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;比 explorer 更多功能&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Ethstats 佈署</title><link>https://calee0219.github.io/blog/cryptocurrency_ethereum_ethstats/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/cryptocurrency_ethereum_ethstats/</guid><description>&lt;p&gt;分別需要兩個 repo&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;api 的:
&lt;/li&gt;
&lt;li&gt;前端的:
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="什麼是-netstats"&gt;什麼是 netstats&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ethereum 監控網路節點狀態的視覺化網頁呈現&lt;/li&gt;
&lt;li&gt;任何人都可以在EthStats仪表板上添加他们的节点&lt;/li&gt;
&lt;li&gt;展示重要信息，诸如现在的区块，散表难度，gas价格和gas花费等&lt;/li&gt;
&lt;li&gt;架構: 後端在每一台 node 上，主動利用 instance-api 以 WebSocket 提供資訊給前端，前端統一在一台 server 接受推播&lt;/li&gt;
&lt;li&gt;後端可自己自由架設&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="api-部份架設"&gt;api 部份架設&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;需求&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;節點必須是 rpc 開啟的
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;geth --rpc&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;需要連得到指定節點的 rpc port (default 8545)
&lt;ul&gt;
&lt;li&gt;可用 &lt;code&gt;nc -v [ip] [port]&lt;/code&gt; 測試&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;需要有 pm2
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo npm install -g pm2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下載&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/cubedro/eth-net-intelligence-api
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; eth-net-intelligence-api
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改設定檔
在 app.json&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;#34;env&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; “RPC_HOST” : “localhost”,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; “RPC_PORT” : “8545”,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; “LISTENING_PORT” : “30303”,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; “INSTANCE_NAME” : “”,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; “CONTACT_DETAILS” : “”,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; “WS_SERVER” : “ http://localhost:3000”,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; “WS_SECRET” : “lalaland”,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; “VERBOSITY” : 2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;RPC_HOST:&lt;/li&gt;
&lt;li&gt;RPC_PORT: 給出資訊的節點的 port&lt;/li&gt;
&lt;li&gt;LISTENING_PORT: ethereum 將會監聽的 port&lt;/li&gt;
&lt;li&gt;INSTANCE_NAME: 對節點的命名，可隨便填，&lt;font style="color:red;"&gt;但是一定要填&lt;/font&gt;&lt;/li&gt;
&lt;li&gt;CONTACT_DETAILS: 若要分享合約資訊，則需要填寫此欄位&lt;/li&gt;
&lt;li&gt;WS_SERVER: 網頁伺服器會使用的 ip / hostname : port
(這裡填入的是前端 ethstats WebSocket 所在的位置(可以在不同的主機上))&lt;/li&gt;
&lt;li&gt;WS_SECRET: 指定一個密鑰，和網頁伺服器建立連線時使用&lt;/li&gt;
&lt;li&gt;VERBOSITY:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;啟動
&lt;code&gt;pm2 start app.json&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果出現 &lt;code&gt;/usr/bin/env: 'node': No such file or directory&lt;/code&gt;
下 &lt;code&gt;apt-get install nodejs-legacy&lt;/code&gt; 指令&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="前端架設"&gt;前端架設&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;需求
&lt;ul&gt;
&lt;li&gt;需要有 grunt
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo npm install -g grunt-cli
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;下載
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/cubedro/eth-netstats
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; eth-netstats
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;grunt all
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;啟動
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;要在 bash 下&lt;/strong&gt; (至少 fish 的變數不是這樣下的 XD)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WS_SECRET=&amp;quot;{密鑰}&amp;quot; npm start&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;密鑰 要與上面的 WS_SECRET 在相同的地方&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="nginx-proxy-設定"&gt;NGINX proxy 設定&lt;/h2&gt;
&lt;p&gt;只需要對前端做 proxy 就可以了~&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;server {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; listen 80;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; server_name ethstats.calee.com.tw;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; location / {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_pass http://localhost:3000;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_http_version 1.1;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_set_header Upgrade $http_upgrade;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_set_header Connection &amp;#34;upgrade&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="參考"&gt;參考&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>file system</title><link>https://calee0219.github.io/blog/note_fs/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_fs/</guid><description>&lt;h2 id="fstab"&gt;fstab&lt;/h2&gt;
&lt;h3 id="mount-ntfs"&gt;mount NTFS&lt;/h3&gt;
&lt;p&gt;
/etc/fstab&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;989CE0C49CE09E4E /home/calee/stg ntfs-3g defaults &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="find-uuid"&gt;Find UUID&lt;/h2&gt;
&lt;p&gt;it&amp;rsquo;s a symbolic link to /dev/sd_
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -l /dev/disk/by-uuid
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="檢視分割磁碟區"&gt;檢視分割磁碟區&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install gparted
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo gparted
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="link"&gt;link&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ln -s TARGET(src) LINK_NAME(dst) # soft link
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>firewalld 設定</title><link>https://calee0219.github.io/blog/note_firewalld/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_firewalld/</guid><description>&lt;h2 id="firewalld"&gt;firewalld&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --get-default-zone
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --set-default-zone&lt;span class="o"&gt;=&lt;/span&gt;internal
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --get-active-zones
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --list-all-zones
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="換腳"&gt;換腳&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;firewal-cmd --permanent --zone&lt;span class="o"&gt;=&lt;/span&gt;public --remove-interface&lt;span class="o"&gt;=&lt;/span&gt;ens34
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;firewall-cmd --permanent --zone&lt;span class="o"&gt;=&lt;/span&gt;internal --add-interface&lt;span class="o"&gt;=&lt;/span&gt;ens34
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="allow--deney-port"&gt;Allow / Deney port&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --zone=public --add-port=12345/tcp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --zone=public --remove-port=12345/tcp --permanent
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;
&lt;/p&gt;
&lt;h3 id="src-nat"&gt;src-nat&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;先設定網卡的 zone
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli c mod eth1 connection.zone internal
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo nmcli c mod eth2 connection.zone external
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;firewall-cmd --get-active-zone
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;允許封包轉送
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;firewall&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;direct&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;ipv4&lt;/span&gt; &lt;span class="n"&gt;nat&lt;/span&gt; &lt;span class="n"&gt;POSTROUTING&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;WAN&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="n"&gt;MASQUERADE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;firewall&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;direct&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;ipv4&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="n"&gt;FORWARD&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;LAN&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;WAN&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="n"&gt;ACCEPT&lt;/span&gt; &lt;span class="c1"&gt;# -i 是 input, -o 是 output&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;firewall&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;direct&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="n"&gt;ipv4&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="n"&gt;FORWARD&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;WAN&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;LAN&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="n"&gt;RELATED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ESTABLISHED&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="n"&gt;ACCEPT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;firewall&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;reload&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dst-nat"&gt;dst-nat&lt;/h3&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;做 masquerade
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;firewall&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;external&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;masquerade&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;permanent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;firewall&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;internal&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;masquerade&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;permanent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;firewall&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;reload&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;same server
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --zone=&amp;#34;public&amp;#34; --add-forward-port=port=80:proto=tcp:toport=12345 --permanent
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;different server
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --zone=external --add-masquerade --permanent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo firewall-cmd --zone=external --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=123.456.78.9 --permanent
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>GitHub 入門</title><link>https://calee0219.github.io/blog/github_intro/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/github_intro/</guid><description>&lt;h2 id="github-註冊"&gt;GitHub 註冊&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;首先到
&lt;/li&gt;
&lt;li&gt;點下網站上的Sign Up&lt;/li&gt;
&lt;li&gt;依網站要求輸入相關資料&lt;/li&gt;
&lt;li&gt;帳號開通後即完成！！&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="安裝git"&gt;安裝Git&lt;/h2&gt;
&lt;h3 id="windows"&gt;Windows&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;首先到
下載Git for windows安裝檔&lt;/li&gt;
&lt;li&gt;執行安裝檔安裝Git&lt;/li&gt;
&lt;li&gt;安裝完後, 電腦上應該會出現一個&lt;strong&gt;Git Bash&lt;/strong&gt;程式, 按下並執行Git Bash&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="linux"&gt;Linux&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install git // debian or ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo yum install git-core //fedora
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install git // fedora 24 or upper
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="mac"&gt;MAC&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew install git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;h2 id="git基本觀念"&gt;Git基本觀念&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;可以看
的第一章了解git版本控制基本觀念&lt;/li&gt;
&lt;li&gt;git 三類
&lt;ul&gt;
&lt;li&gt;tracked (被追蹤的檔案，有做過 git 版控的檔案皆為此類)&lt;/li&gt;
&lt;li&gt;ignored (忽略的檔案，此類檔案不會被追蹤，須寫在 .gitignore 裡)&lt;/li&gt;
&lt;li&gt;untracked (未被追蹤的，剛新增的檔案皆為此類)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;git 三狀態
&lt;ul&gt;
&lt;li&gt;working directory (工作狀態，未做任何版本控制，此狀態內修改的code都是不可逆的)&lt;/li&gt;
&lt;li&gt;staging area (版控站存區，working directory 的 code 皆可被這裡的 code 複寫回原來的版本，但若此區的檔案被更新，則無法回復之前在 staging area 的 code)&lt;/li&gt;
&lt;li&gt;repository (進入版控的 code，此區的 code 有許多節點，修改過的 code 可回復到此區的任意節點)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;git / GitHub 術語
&lt;ul&gt;
&lt;li&gt;repo: repository 縮寫&lt;/li&gt;
&lt;li&gt;merge: 兩份同一個專案的 code 互相衝突時，檢查檔案是否有衝突的地方，若無，合併檔案，法之修改衝突的部分後合併檔案&lt;/li&gt;
&lt;li&gt;pull request (PR): 要求他人將你的更新 merge 到他的 repo 中&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="git-基礎指令"&gt;git 基礎指令&lt;/h2&gt;
&lt;p&gt;:::info
指令中有[]者表示括號中內容依使用者的需求自填，&amp;quot;[&amp;quot; ＆ &amp;ldquo;]&amp;ldquo;不須下在指令中
:::&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;git init&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;新創一個git repository&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;git status&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查看目前專案目錄狀態&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;git branch&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查看目前所有分支(有打星號的分支)&lt;/li&gt;
&lt;li&gt;創建新分支：&lt;code&gt;git branch [newBranchName]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;切換分支：&lt;code&gt;git checkout [branchName]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;git add [fileName]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;將檔案加到暫存區stage, 在stage的檔案就是準備要commit的檔案&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;git commit&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;將所有已經加到stage的檔案提交到repository, 需要輸入提交訊息來紀錄這次提交&lt;/li&gt;
&lt;li&gt;通常會搭配 &lt;code&gt;-m&lt;/code&gt; 參數使用, 此參數可以讓你在下commit指令時同時順便輸入簡易的提交訊息&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;git merge&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;合併兩個分支&lt;/li&gt;
&lt;li&gt;指令：&lt;code&gt;git branch [firstBranch] [secondBranch]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;上述指令會將secondBranch合併到firstBranch中&lt;/li&gt;
&lt;li&gt;合併完且不再需要的branch可以下&lt;code&gt;git branch -d [branchName]&lt;/code&gt;刪除&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;git log&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查看歷次提交的相關資訊&lt;/li&gt;
&lt;li&gt;若只要看線圖可以加上 &lt;code&gt;--graph&lt;/code&gt; &lt;code&gt;--oneline&lt;/code&gt; &lt;code&gt;--decorate&lt;/code&gt; &lt;code&gt;--all&lt;/code&gt;四個參數&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;git push&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;將本地分支提交到遠端伺服器&lt;/li&gt;
&lt;li&gt;若遠端分支有更新，push會失敗，必須先pull遠端更新才能push本地更新&lt;/li&gt;
&lt;li&gt;完整指令：&lt;code&gt;git push [remoteRepositoryName] [localBranchName]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;若你的repository是從gitHub clone下來的，reomteRepositoryName會是origin&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;git pull&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把遠端更新下載回本地端並與本地端分支合併&lt;/li&gt;
&lt;li&gt;類似把 git fetch 及 git merge 一起做的指令&lt;/li&gt;
&lt;li&gt;完整指令：&lt;code&gt;git pull [remoteRepositoryName] [localBranchName]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;可以加入&lt;code&gt;--rebase&lt;/code&gt;參數讓線圖更漂亮&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;git &amp;ndash;help&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查看git幫助訊息&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="專案協作"&gt;專案協作&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;git clone
&lt;ul&gt;
&lt;li&gt;複製git server 的 repository 到 local 端&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="step-by-step"&gt;Step by step&lt;/h2&gt;
&lt;p&gt;對於 moztw 的專案，如果你不想要知道他們到底是幹什麼的，只要可以讓你可以做就好的話&amp;hellip;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;到 moztw 的
，右上方按 fock ，複製到自己的 GitHub 上
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/um4W72c.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;到自己 fork 的 repo ，按右上方 Clone or download，將看到的網址複製下來
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/ntuZBun.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;到你的電腦，下 &lt;code&gt;git clone [剛剛的網址]&lt;/code&gt; 的指令，等待電腦下載完成&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;到 moztw issue 尋找你想要改的 bug 或新增的 feature
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/1la2x1y.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;點入 issue 後可以查看詳細內容
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/CCK3SjL.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;針對你要貢獻的 issue，編輯你需要修改的檔案，在編輯前，記得先讀過一些 coding 的
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;若想看修改的結果，可以 npm 的方式運行，運行方式
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;編輯完成後，下 &lt;code&gt;git status&lt;/code&gt; 可以看到你所修改的檔案變成 &lt;em&gt;modified&lt;/em&gt; (紅色的) 狀態，若是新檔案則是 &lt;em&gt;untracked files&lt;/em&gt; 狀態&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;若已經確認某檔案將不再修改，可以下 &lt;code&gt;git add [filePath]&lt;/code&gt; 將檔案放到暫存區 (staging area) 準備commit&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;add完所有需要提交的檔案後，就可以下 &lt;code&gt;git commit -m &amp;quot;Fix issue [issue No.], [yourCommitMessage]&amp;quot;&lt;/code&gt; 將檔案提交到repository了，記得要把 issue No. 寫在你的 commit 裡，pull request 時管理員才能知道你修的是哪個 issue&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;確認所有檔案都以完成提交，下 &lt;code&gt;git push origin master&lt;/code&gt; 上傳到你 GitHub 上的 repo&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;確認你 GutHub repo 上的檔案是正確的後，按左上方的 new pull request 完成你的 pull request
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/qKh2Hwj.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;坐等你的 pull request 被 merge 或被退回吧~~~&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="如何運行-moztw"&gt;如何運行 moztw&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;安裝
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;windows 下安裝
即可&lt;/li&gt;
&lt;li&gt;Ubuntu / Debian 下，在 terminal 下 &lt;code&gt;sudo apt install nodejs npm&lt;/code&gt; 指令&lt;/li&gt;
&lt;li&gt;Fedora 下，在 terminal 下 &lt;code&gt;sudo dnf install nodejs npm&lt;/code&gt; 指令&lt;/li&gt;
&lt;li&gt;Mac 下， 在 terminal 下 &lt;code&gt;brew install node&lt;/code&gt; 指令&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;用 terminal (linux/mac) 或 cmd (windows) 到你 moztw 所在的資料夾下&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下 &lt;code&gt;npm install&lt;/code&gt; 安專所需的套件，然後下 &lt;code&gt;npm start&lt;/code&gt; 運行網頁&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在瀏覽器裡打開 &lt;code&gt;localhost:3000&lt;/code&gt; 即可看到你下載下來的網頁，之後對資料夾內檔案做修改，網頁都會自動更新&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="附錄"&gt;附錄&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>iptables 使用小記</title><link>https://calee0219.github.io/blog/note_iptables/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_iptables/</guid><description>&lt;h2 id="iptables"&gt;iptables&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;iptables [-t table] &lt;code&gt;command&lt;/code&gt; &lt;code&gt;CHAIN&lt;/code&gt; [NUM] match criteria -j ACTION&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CHAIN&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;-N: (new) new a chain&lt;/li&gt;
&lt;li&gt;-X: delete chain&lt;/li&gt;
&lt;li&gt;-F: flush all chain&lt;/li&gt;
&lt;li&gt;-Z: zero the pkg counter&lt;/li&gt;
&lt;li&gt;-P: policy of chain&lt;/li&gt;
&lt;li&gt;-E: rename&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;rule
&lt;ul&gt;
&lt;li&gt;-A: append rule&lt;/li&gt;
&lt;li&gt;-I: insert rule to number&lt;/li&gt;
&lt;li&gt;-R: replace&lt;/li&gt;
&lt;li&gt;-D: delete&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LIST
&lt;ul&gt;
&lt;li&gt;-L: list&lt;/li&gt;
&lt;li&gt;-S: Specification&lt;/li&gt;
&lt;li&gt;-n: user number to show&lt;/li&gt;
&lt;li&gt;-v: verbose&lt;/li&gt;
&lt;li&gt;-x: show msg&lt;/li&gt;
&lt;li&gt;&amp;ndash;line number: show line number&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dst-nat"&gt;DST-NAT&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sysctl net.ipv4.ip_forward=1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo iptables -t nat -A PREROUTING -j DNAT -p tcp --to-destination 192.168.15.254:80 -i ens19
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Jupyter 設定</title><link>https://calee0219.github.io/blog/note_jupyter/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_jupyter/</guid><description>&lt;h2 id="install"&gt;Install&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;pip install jupyter&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pip3 install --upgrade pip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pip3 install jupyter
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="error"&gt;Error&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;h2 id="modulenotfounderror-no-module-named-_sqlite3"&gt;&lt;code&gt;ModuleNotFoundError: No module named '_sqlite3'&lt;/code&gt;&lt;/h2&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ModuleNotFoundError: No module named 'pysqlite2'&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="used"&gt;Used&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;start&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /要用來存資料的資料夾/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;jupyter notebook
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;參數&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--ip
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--port
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--no-browser
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;--help
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="config"&gt;config&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;環境設定&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ipython --ipython-dir= # override the default IPYTHONDIR directory, ~/.ipython/ by default
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ipython profile create foo # create the profile foo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ipython profile locate foo # find foo profile directory, IPYTHONDIR by default,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ipython --profile=foo # start IPython using the new profile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;產生設定檔&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;jupyter –-generate-config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;會在產生 &lt;code&gt;~/.jupyter/jupyter_notebook_config.py&lt;/code&gt; 設定檔&lt;/p&gt;
&lt;h2 id="jupyter-server"&gt;jupyter server&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;產生設定檔&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;jupyter notebook --generate-config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;產生密碼&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;jupyter notebook password
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;會在 &lt;code&gt;jupyter_notebook_config.json&lt;/code&gt; 存密碼的 hash value，需要把它丟到 &lt;code&gt;jupyter_notebook_config.py&lt;/code&gt; 裡的 &lt;code&gt;c.NotebookApp.password =&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;修改設定檔&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Set options for certfile, ip, password, and toggle off&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Set ip to &amp;#39;*&amp;#39; to bind on all interfaces (ips) for the public server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotebookApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotebookApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;sha1:bcd259ccf...&amp;lt;your hashed password here&amp;gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotebookApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open_browser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# It is a good idea to set a known, fixed port for server access&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotebookApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9999&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="jupyter-daemon"&gt;Jupyter Daemon&lt;/h3&gt;
&lt;p&gt;
檔案：&lt;code&gt;/lib/systemd/system/jupyter.service&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[Unit]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Description=Jupyter Notebook
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[Service]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Type=simple
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PIDFile=/run/jupyter.pid
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# Step 1 and Ste 2 details are here..
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# -----------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ExecStart=/usr/local/bin/jupyter-notebook --config=/home/calee/.jupyter/jupyter_notebook_config.py
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;User=calee
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Group=calee
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;WorkingDirectory=/home/calee/Project/Jupyter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Restart=always
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;RestractSec=10
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;#KillMode=mixed
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[Install]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;WantedBy=multi-user.target
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;執行&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl start jupyter.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart jupyter.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; jupyter.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="nginx-proxy-setting"&gt;NGINX proxy setting&lt;/h2&gt;
&lt;p&gt;位置：&lt;code&gt;/etc/nginx/sites-enabled/notebook.conf&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;upstream notebook {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; server localhost:8888;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;server{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; listen 80;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; server_name notebook.calee.xyz;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; location / {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_pass http://notebook;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_set_header Host $host;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; location ~ /api/kernels/ {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_pass http://notebook;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_set_header Host $host;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; # websocket support
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_http_version 1.1;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_set_header Upgrade &amp;#34;websocket&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_set_header Connection &amp;#34;Upgrade&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_read_timeout 86400;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; location ~ /terminals/ {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_pass http://notebook;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_set_header Host $host;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; # websocket support
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_http_version 1.1;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_set_header Upgrade &amp;#34;websocket&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_set_header Connection &amp;#34;Upgrade&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_read_timeout 86400;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Restart Nginx&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>LDAP</title><link>https://calee0219.github.io/blog/note_ldap/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_ldap/</guid><description>&lt;h2 id="freeipa"&gt;freeIPA&lt;/h2&gt;
&lt;h2 id="openldap"&gt;OpenLDAP&lt;/h2&gt;
&lt;h3 id="server"&gt;Server&lt;/h3&gt;
&lt;h4 id="nfs"&gt;NFS&lt;/h4&gt;
&lt;h4 id="nis"&gt;NIS&lt;/h4&gt;
&lt;h4 id="ldap"&gt;LDAP&lt;/h4&gt;
&lt;h3 id="client"&gt;Client&lt;/h3&gt;
&lt;h4 id="nfs-1"&gt;NFS&lt;/h4&gt;
&lt;h4 id="nis-1"&gt;NIS&lt;/h4&gt;
&lt;h4 id="ldap-1"&gt;LDAP&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;需要下載
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sudo yum update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; yum install openldap openldap-clients nss-pam-ldapd
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;複製 server 端的 CAe&lt;/li&gt;
&lt;li&gt;產生 config
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;authconfig --enableldap --enableldapauth --ldapserver&lt;span class="o"&gt;=&lt;/span&gt;ldaps://ldaps.cs.nctu.edu.tw --ldapbasedn&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;dc=cs,dc=nctu,dc=edu,dc=tw&amp;#34;&lt;/span&gt; --update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;設定檔: &lt;code&gt;/etc/openldap/ldap.conf&lt;/code&gt; :
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BASE dc=cs,dc=nctu,dc=edu,dc=tw
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;URI ldaps://ldaps.cs.nctu.edu.tw/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;TLS_REQCERT allow
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;TLS_CIPHER_SUITE=AES256
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;TLS_CACERTDIR /etc/ssl/certs/csrootca.crt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;filter passwd (memberof=cn=cs-ta,ou=MemberGroup,dc=cs,dc=nctu,dc=edu,dc=tw) # 如果要限制只有 cs-ta groups 的資訊才會被透過 LDAP 進來了話
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;重啟服務
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart nslcd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart nscd
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;檢查
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ldapsearch -D &lt;span class="s2"&gt;&amp;#34;uid=calee,ou=People,dc=cs,dc=nctu,dc=edu,dc=tw&amp;#34;&lt;/span&gt; -W &lt;span class="nv"&gt;uid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xxx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ypwhich : 查詢 NIS Server
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ypchsh：改變 NIS 上使用者登入的 Shell
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ypchfn：改變 NIS 上使用者的完整名稱跟相關資訊，也就是 /etc/passwd 中的第五個欄位
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ypmatch：查詢 NIS map 的 KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;yptest：測試 NIS 的設定，如果可以跑出來 NIS 上的使用者則代表可以查詢
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;-D uid 裡面的是去登入 ldaps.cs.nctu.edu.tw 的帳號，之後問問密碼，使用 uid 使用者的密碼登入搜尋&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cache-solution"&gt;Cache Solution&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SSSD
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;NSCD&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Linux 上密碼相關設定</title><link>https://calee0219.github.io/blog/note_linux_passwd/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_linux_passwd/</guid><description>&lt;h2 id="password-policy"&gt;Password Policy&lt;/h2&gt;
&lt;p&gt;密碼品質檢查，這個功能是透過 pam 時做，避免 user 弱密碼導致 ssh 或其他服務被破解 (&lt;code&gt;man pam_pwquality&lt;/code&gt;)&lt;/p&gt;
&lt;h3 id="修改方法"&gt;修改方法&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Debian 系統預設沒有 pwquality，需要先安裝: &lt;code&gt;sudo apt-get install libpam-pwquality&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;可以直接修改 &lt;code&gt;/etc/pam.d/&lt;/code&gt; 檔案，直接接在 &lt;code&gt;pam_unix.so&lt;/code&gt; 當行最後用空白隔開&lt;/li&gt;
&lt;li&gt;修改 &lt;code&gt;/etc/security/pwquality.conf&lt;/code&gt; 檔案 [rpm_pam] 或用 &lt;code&gt;authconfig&lt;/code&gt; 指令 (Red Hat 系列，自己 man ㄅ)，可以寫在 &lt;code&gt;/etc/pam.d&lt;/code&gt;，不過都給 config file 了就用杯&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="設定內容"&gt;設定內容&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;密碼最小長度: &lt;code&gt;minlen=12 dcredit=0 ucredit=0 lcredit=0 ocredit=0 # 最少 12 char，後面 credit 要記得加，理由後述&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;密碼複雜度:
&lt;ul&gt;
&lt;li&gt;其實前面的 &lt;code&gt;minlen&lt;/code&gt; 並不完全是密碼最小長度，而是密碼最少應得分數。計算方式是每個字元 +1，另外將字元分類成四類，分別再給一分，但另給的分數有上限:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ucredit=3&lt;/code&gt;: 密碼如果包含 upper-case 大寫字母最多多給分數&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lcredit=2&lt;/code&gt;: 密碼如果包含 lower-case 小寫字母最多多給分數&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dcredit=1&lt;/code&gt;: 密碼如果包含 digit-case 數字字母最多多給分數&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ocredit=0&lt;/code&gt;: 密碼如果包含 other-case 其他字母最多多給分數 (eg. 符號)&lt;/li&gt;
&lt;li&gt;分數加總後便是總所得分數，以上例來看，&lt;code&gt;$$$$$$$a&lt;/code&gt; 得分為 &lt;code&gt;8+0+1+0+0&lt;/code&gt;，符號沒額外得分，小寫單字額外一分。而 &lt;code&gt;$$$$$aaa&lt;/code&gt; 得分為 &lt;code&gt;8+0+2+0+0&lt;/code&gt;，小寫單字做多額外兩分，不會給超過。&lt;/li&gt;
&lt;li&gt;故得知，如果只寫 &lt;code&gt;minlen=12&lt;/code&gt;，會因為有額外分數而可以少於 12 字元&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;也可以不用得分來算複雜度，而是直接用管理員想要的數量，只要將所想要的數字加負號 (common)
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ucredit=-1&lt;/code&gt;: upper-case 大寫字母最少 1 個&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lcredit=-2&lt;/code&gt;: lower-case 小寫字母最少 2 個&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dcredit=-3&lt;/code&gt;: digit-case 數字字母最少 3 個&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ocredit=-4&lt;/code&gt;: other-case 其他字母最少 4 個&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其他參考 &lt;code&gt;/etc/security/pwquality.conf&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;retry&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="c1"&gt;# 最多可以是錯幾次&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;difok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;# 新密碼中不可出現跟舊密碼相同字串長度 (eg. 舊: abcdef，新密碼不可以是 abcdez)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;minclass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="c1"&gt;# 最少一定要出現幾種字元 (大寫、小寫、數字、其他)，好處是不用限定一定要哪一種&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;maxrepeat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# 最大可重複字元次數，0 是不檢查 (!) (eg. =3，則不能有 26aaaac)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;maxclassrepeat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# 同一種類的字元最多可以重複出現的次數，0 是不檢查&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;gecoscheck&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# 會從 /etc/passwd 的 GECOS 欄位檢查是否有跟密碼重複超過 3 個字元串，簡單來說就是為了避免用身分資料來合成密碼，0 是不檢查，只有 True False (由 pam_cracklib 檢查)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;dictcheck&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# 字典攻擊檢查，由 pam_cracklib 的字典來查找，選項 True False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;usercheck&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# 檢查是否有 username 組成的密碼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;enforcing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# 密碼規則建議或強制，預設 1 是強制&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;badwords&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gura inna &lt;span class="c1"&gt;# 自訂一不合法字串&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;enforce_for_root &lt;span class="c1"&gt;# 如果使用者用 sudo passwd 也會強制檢查密碼，不然預設只會警告 (用 sudo 時)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;local_users_only &lt;span class="c1"&gt;# 只檢查有在 /etc/passwd 的密碼&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;ucredit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;lcredit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;dcredit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;ocredit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="password-expiration"&gt;Password Expiration&lt;/h2&gt;
&lt;p&gt;密碼過期，可以設定密碼有效期限，或是請使用者登入時修改密碼 (方便用於幫使用者亂數生成密碼給他後請他第一次登入修改密碼)&lt;/p&gt;
&lt;h3 id="logindefs"&gt;login.defs&lt;/h3&gt;
&lt;p&gt;這份檔案類似模板，只會影響到新加的使用者，對於已經存在的使用者並不影響&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PASS_MAX_DAYS &lt;span class="m"&gt;1234&lt;/span&gt; &lt;span class="c1"&gt;# 密碼最多用幾天 (要換)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PASS_MIN_DAYS &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# 密碼幾天內不能修改&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PASS_WARN_AGE &lt;span class="m"&gt;7&lt;/span&gt; &lt;span class="c1"&gt;# 密碼到期前幾天開始提醒&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="chage"&gt;chage&lt;/h3&gt;
&lt;p&gt;修改現存使用者的密碼到期時間&lt;/p&gt;
&lt;p&gt;&lt;code&gt;chage [options] LOGIN&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-d&lt;/code&gt;: 修改 &amp;ldquo;上一次修改時間&amp;rdquo;，可用 YYYY-MM-DD 格式或從 1970/01/01 開始算的天數&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-E&lt;/code&gt;: 修改到期時間，可用 YYYY-MM-DD 格式或從 1970/01/01 開始算的天數&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-h&lt;/code&gt;: help&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-I&lt;/code&gt;: 密碼到期後 N 天會直接把使用者鎖掉&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-l&lt;/code&gt;: list，顯示資料&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-m&lt;/code&gt;: min，密碼幾天內不能修改&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-M&lt;/code&gt;: max，密碼最多用幾天&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-R&lt;/code&gt;: 應用 chroot，也許是到期後把使用者 chroot 到低權限的家目錄 (?)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-W&lt;/code&gt;: 密碼到期前幾天開始提醒&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="迫使使用者換密碼"&gt;迫使使用者換密碼&lt;/h3&gt;
&lt;p&gt;通常一些系統我們可能為了避免知道使用者密碼，會亂數生成密碼給他，再請他登入後自己 &lt;code&gt;passwd&lt;/code&gt; 改密碼，但如何避免使用者懶得改呢?&lt;/p&gt;
&lt;p&gt;其實密碼到期後的下一次登入，系統並不會讓使用者無法登入，而是登入後迫使他改密碼，因此我們可以將使用者設定成密碼到期，便可以讓系統請他改密碼&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;passwd --expire $USER&lt;/code&gt;: 用 passwd 版本&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chage -d 0 $USER&lt;/code&gt;: 用 chage 版本，其實就是把他的到期日期設定成 1970/01/01&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="remember"&gt;Remember&lt;/h2&gt;
&lt;p&gt;避免使用者設定以前設定過的密碼&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;/etc/pam.d&lt;/code&gt; 下的檔案 (&lt;code&gt;common-password&lt;/code&gt; 或 &lt;code&gt;system-auth&lt;/code&gt;)，password 最後面接 &lt;code&gt;remember=5&lt;/code&gt;，代表新密碼不能用前五次內的密碼&lt;/p&gt;
&lt;h2 id="password-generation"&gt;Password Generation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mkpasswd&lt;/code&gt;: 用你輸入的參數送你密碼&lt;/li&gt;
&lt;li&gt;&lt;code&gt;makepasswd --chars 12&lt;/code&gt;: 用 &lt;code&gt;urandom&lt;/code&gt; 送你一組密碼&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pwgen&lt;/code&gt;: 送你一堆密碼&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ps"&gt;P.S.&lt;/h2&gt;
&lt;p&gt;[rpm_pam]: 理論上要在 &lt;code&gt;/etc/pam.d/passwd&lt;/code&gt; 下面多寫 &lt;code&gt;password required pam_pwquality.so retry=3&lt;/code&gt; 讓系統知道要用 pam_pwquality，但現在預設應該都有 &lt;code&gt;auth include system-auth&lt;/code&gt;，而去翻 &lt;code&gt;system-auth&lt;/code&gt; 檔案會發現內部就有寫 &lt;code&gt;pam_pwquality&lt;/code&gt;，因此應該是不用特別再寫一次。&lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Linux 上的 NVIDIA 驅動</title><link>https://calee0219.github.io/blog/note_nvidia/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_nvidia/</guid><description>&lt;h2 id="nvidia-driver-on-ubuntu"&gt;Nvidia driver on Ubuntu&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;到
查看最新版本
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;34x: 傳統架構版本&lt;/li&gt;
&lt;li&gt;387: 新版短期&lt;/li&gt;
&lt;li&gt;384: 新版長期&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;刪除舊版&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get purge nvidia*
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;安裝新版&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo add-apt-repository ppa:graphics-drivers
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install nvidia-387
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo reboot &lt;span class="c1"&gt;# 重開機&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;檢查&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lsmod &lt;span class="p"&gt;|&lt;/span&gt; grep nvidia
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-smi
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cuda"&gt;cuda&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install cuda-9
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install cuda-nvcc-9-1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;手動安裝
到
下載 runfile(local)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo sh cuda_9.1.85_387.26_linux.run
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;檢查
注意：gcc 要是 &amp;lt; 6 的版本 @@&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cp -r /usr/local/cuda-9.1/samples ./
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; samples
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cudnn"&gt;cudnn&lt;/h2&gt;
&lt;p&gt;到
下載&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cuda 的資料夾要在 &lt;code&gt;/usr/local/cuda/&lt;/code&gt;，so 不管裝在哪裡，都給一個 link 到 &lt;code&gt;/usr/local/cuda&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ubuntu 版:
&lt;ul&gt;
&lt;li&gt;下載 libcudnn7&amp;hellip;deb, libcudnn7-dev&amp;hellip;deb, libcudnn7-doc&amp;hellip;deb&lt;/li&gt;
&lt;li&gt;三個都做 &lt;code&gt;sudo dpkg -i&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;其他
&lt;ul&gt;
&lt;li&gt;下載壓縮檔&lt;/li&gt;
&lt;li&gt;解壓縮: &lt;code&gt;tar -xzvf cudnn-9.0-linux-x64-v7.tgz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;安裝:
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo cp cuda/include/cudnn.h /usr/local/cuda/include
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo chmod a+r /usr/local/cuda/include/cudnn.h /usr/local/cuda/lib64/libcudnn*
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Linux 小指令</title><link>https://calee0219.github.io/blog/note_linux_cli/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_linux_cli/</guid><description>&lt;h3 id="change-default-editor"&gt;Change default editor&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;For global
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo update-alternatives --config editor
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;# 然後選擇數字
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;For one user
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;select&lt;/span&gt;-editor
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;or
in &lt;code&gt;.bashrc&lt;/code&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;EDITOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;vim&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="n"&gt;VISUAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;vim&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="add-groups"&gt;Add groups&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Change main group
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo groupadd mynewgroup # Add a new group
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;usermod -g groupname username
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;groups username
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Add secondary group
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo usermod -aG groupname username
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="password-policy"&gt;password policy&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vim /etc/pam.d/common-password&lt;/code&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;password required pam_cracklib.so minlen=8 # 最短 8 digits
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ssh"&gt;SSH&lt;/h2&gt;
&lt;h3 id="ssh-keep-alive"&gt;SSH Keep Alive&lt;/h3&gt;
&lt;h4 id="client-side"&gt;Client side&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;~/.ssh/config&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host *
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ServerAliveInterval 240
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;chmod 600 ~/.ssh/config&lt;/code&gt;&lt;/p&gt;
&lt;h4 id="server-side"&gt;Server Side&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ClientAliveInterval 60
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ClientAliveCountMax 2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="ssh-tunnel"&gt;SSH Tunnel&lt;/h3&gt;
&lt;p&gt;
![](
=400x)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Normal Tunnel (Local Port Forward)
&lt;ul&gt;
&lt;li&gt;正常情況下，你希望你的封包先過一台機器(Server Side)，再用這台機器出去，達到 VPN 的效果，你如果可以直接對這台機器(Server Side) SSH，便可以用正常的 SSH Tunnel&lt;/li&gt;
&lt;li&gt;指定碰到 client 的 port 就等於碰到 server 的 port&lt;/li&gt;
&lt;li&gt;Client
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -L [bind_address:]port:host:hostport user@host_ip
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reverse Tunnel (Remote Port Forward)
&lt;ul&gt;
&lt;li&gt;如果你希望封包進入一台無法 SSH 的機器(Server Side)，可能是再公司防火牆內的機器，對於開 SSH Session 只能由內往外開，不能由外往內開，這時候就需要先再 Server Side 主動開 Reverse SSH Tunnel，把 port bind 再 Client Side 上的某個 port，再由 client side 戳 localhost 的這個 port&lt;/li&gt;
&lt;li&gt;Server:
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -R 2222(bind to client port):localhost(server / server 可碰到):22(server port) user@client_ip
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Client:
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nc -v localhost 2222
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Socket Proxy (Dynamic Port Forward)
&lt;ul&gt;
&lt;li&gt;正常情況下，你希望你的封包先過一台機器(Server Side)，再用這台機器出去，達到 VPN 的效果，同時不需要指定碰到 client 的 port 就等於碰到 server 的 port&lt;/li&gt;
&lt;li&gt;Client
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -D [bind_address:]port user@server_ip
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="icmp-tunnel"&gt;ICMP Tunnel&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>MariaDB (MySQL)</title><link>https://calee0219.github.io/blog/note_mariadb/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_mariadb/</guid><description>&lt;h2 id="安裝"&gt;安裝&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install mariadb-server
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mysql &lt;span class="c1"&gt;# 第一次進入&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="使用者"&gt;使用者&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;change password
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PASSWORD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PASSWORD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;new_password&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;新增使用者
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ALL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;username&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IDENTIFIED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ALL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;username&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IDENTIFIED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;username&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IDENTIFIED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;刪除使用者
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DROP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;IF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;EXISTS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="操作"&gt;操作&lt;/h2&gt;
&lt;h3 id="create-new-db"&gt;Create New DB&lt;/h3&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DATABASE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;testDB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="drop-db--table--column--row"&gt;Drop DB / table / column / row&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DROP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DATABASE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;db_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DROP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TABLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;table_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- table
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TABLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;table_name&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DROP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;column_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* column */&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;DELETE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;table_name&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="use-sql-file"&gt;Use .sql file&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mysql -p &amp;lt; xxx.sql
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="dump-db-in--out"&gt;Dump DB in / out&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;in&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mysqlimport --ignore-lines&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; --fields-terminated-by&lt;span class="o"&gt;=&lt;/span&gt;, --verbose --local -u &lt;span class="o"&gt;[&lt;/span&gt;user&lt;span class="o"&gt;]&lt;/span&gt; -p &lt;span class="o"&gt;[&lt;/span&gt;database&lt;span class="o"&gt;]&lt;/span&gt; /path/to/address.csv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;out&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Mastering in Bitcoin 讀書筆記</title><link>https://calee0219.github.io/blog/cryptocurrency_mastering_in_bitcoin/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/cryptocurrency_mastering_in_bitcoin/</guid><description>&lt;p&gt;
&lt;/p&gt;
&lt;h2 id="ch1--ch2"&gt;Ch1 / Ch2&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ch3-比特幣客戶端"&gt;Ch3 比特幣客戶端&lt;/h2&gt;
&lt;p&gt;以
為主&lt;/p&gt;
&lt;p&gt;也可以到
直接選擇 binary file 執行&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;下載並切換版本&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Download&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/bitcoin/bitcoin.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; bitcoin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 檢查版本 &amp;amp; 切換&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git tag
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git checkout &lt;span class="o"&gt;{&lt;/span&gt;tag&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;自動產生相關檔案
&lt;code&gt;./autogen.sh&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;參數設定&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./configure --help
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./configure &lt;span class="o"&gt;{&lt;/span&gt;需要的參數&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;之後軟體會檢查所需要的相關軟體，若沒有，會中途中止，安裝完後重跑即可
過程中可能會遇到一些 bug，可以先到
參考需要安裝的東西&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;編譯與安裝&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo make install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="開啟"&gt;開啟&lt;/h3&gt;
&lt;p&gt;安裝完後，應該會有 &lt;code&gt;bitcoind&lt;/code&gt;, &lt;code&gt;bitcoin-cli&lt;/code&gt; 等指令可以用&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用 &lt;code&gt;which bitcoind&lt;/code&gt; 可以查看安裝位置&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bitcoind&lt;/code&gt;: 開啟服務&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;~/.bitcoin/bitcoin.conf&lt;/code&gt; 修改設定檔
&lt;ul&gt;
&lt;li&gt;用戶名 &amp;amp; 密碼
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;rpcuser&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bitcoinrpc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;rpcpassword&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2XA4DuKNCbtZXsBQRRNDEwEY2nM6M4H9Tx5dFjoAVVbK
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;其他設定參數
&lt;code&gt;bitcoind --help&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bitcoind --daemon&lt;/code&gt;: 在後台執行&lt;/li&gt;
&lt;li&gt;第一次運行時，會同步區塊，至少會有 122GB 以上，可能需要 2 天的時間下載區塊&amp;hellip;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/Lz3S2OR.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="json-rpc-api"&gt;JSON-RPC API&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;bitcoin 提供 json-rpc api&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli help&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli getinfo&lt;/code&gt;: 獲得基本資訊 (網路節點，錢包，區塊數據&amp;hellip;)
&lt;ul&gt;
&lt;li&gt;version, protocolversion, walletversion: 版本&lt;/li&gt;
&lt;li&gt;balance: 錢包餘額&lt;/li&gt;
&lt;li&gt;&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="錢包設定及加密"&gt;錢包設定及加密&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在生成密鑰或其他指令前，需要先對錢包加密
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli encryptwallet {密碼}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;解鎖錢包
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli walletpassp {密碼} {時間/秒}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="備份"&gt;備份&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli backupwallet {檔名}&lt;/code&gt;: 匯出成可以匯入的檔案&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli importwallet {檔名}&lt;/code&gt; (需要是錢包解鎖的狀態)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli dumpwallet {檔名}&lt;/code&gt;: 將錢包匯出成人看得懂的明文&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="地址--交易"&gt;地址 &amp;amp; 交易&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli getnewaddress&lt;/code&gt;: 產生新的 address&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli getreceivedbyaddress {地址} 0&lt;/code&gt;: 若有匯錢進來，可以檢查匯入的錢&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli listtransactions&lt;/code&gt;: 列出所有交易&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli listaddressbyaccount &amp;quot;&amp;quot;&lt;/code&gt;: 列出所有地址&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli getbalence&lt;/code&gt;: 列出錢包總額&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli gettransaction {txid}&lt;/code&gt;: 列出 txid 的交易明細&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="區塊"&gt;區塊&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bitcoin-cli getblock {區塊的 hash}&lt;/code&gt;: 查看這個 block 的內容&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ch4-密鑰-地址-錢包"&gt;Ch4 密鑰-地址-錢包&lt;/h2&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/zeXOX07.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id="密鑰"&gt;密鑰&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;$1$ ~ $2^{256}$&lt;/li&gt;
&lt;li&gt;生成方法：密碼學安全隨機源取出一串隨機字串 -&amp;gt; sha256 -&amp;gt; 檢查是否小於 $n-1$&lt;/li&gt;
&lt;li&gt;256 bit，但可以用不同的表示法
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/8gjTSqB.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;base58check-&amp;gt;hex: &lt;code&gt;sx base58check-decode ...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;hex-&amp;gt;base58check: &lt;code&gt;sx base58check-encode {hex} {prefix}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="公鑰"&gt;公鑰&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;用 ECC (橢圓曲線) 從私鑰生成&lt;/li&gt;
&lt;li&gt;公鑰 = 私鑰 * G&lt;/li&gt;
&lt;li&gt;G: 生成點，bitcoin 的生成點是固定的&lt;/li&gt;
&lt;li&gt;secp256k1 標準的橢圓曲線&lt;/li&gt;
&lt;li&gt;$y^2=(x^3+7)$ over $F_p$&lt;/li&gt;
&lt;li&gt;$y^2\mod p = (x^3+7)\mod p$&lt;/li&gt;
&lt;li&gt;$p = 2^{256}-2^{32}-2^9-2^8-2^7-2^6-2^4-1$&lt;/li&gt;
&lt;li&gt;無窮點對 (0)&lt;/li&gt;
&lt;li&gt;加法定義$P_1=P_2+P_3$&lt;/li&gt;
&lt;li&gt;$K=k*G$
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/nT8sxsu.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;格式
&lt;ul&gt;
&lt;li&gt;非壓縮型
&lt;ul&gt;
&lt;li&gt;prefix: 04&lt;/li&gt;
&lt;li&gt;K = 04xy&lt;/li&gt;
&lt;li&gt;520bit: 8 + 256 + 256&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;壓縮型
&lt;ul&gt;
&lt;li&gt;prefix: 02 / 03&lt;/li&gt;
&lt;li&gt;有 x，有曲線方程式，可算出 y&lt;/li&gt;
&lt;li&gt;解方程式時，y 有平方 =&amp;gt; 有兩解 =&amp;gt; 用 02 / 03 區別奇偶&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;壓縮格式公鑰產生的地址會與非壓縮的不一樣&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;=&amp;gt; 現在的協定多以非壓縮為主&lt;/li&gt;
&lt;li&gt;but 應該還是要能支援非壓縮&lt;/li&gt;
&lt;li&gt;WIF (錢包導入格式) 應該要標示出私鑰產生的公鑰是否為壓縮格式 (基本上就是要說明這把私鑰最終產生的地址應該要是哪一個)&lt;/li&gt;
&lt;li&gt;壓縮格式私鑰:
&lt;ul&gt;
&lt;li&gt;私鑰 + &amp;lsquo;01&amp;rsquo;&lt;/li&gt;
&lt;li&gt;用來表示這個私鑰的 address 是用壓縮格式公鑰產生的&lt;/li&gt;
&lt;li&gt;事實上會比私鑰長 XD&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;WIF
&lt;ul&gt;
&lt;li&gt;使用壓縮格式導出私鑰時，永遠只用 WIF 壓縮格式 (K or L 前綴 (因為經過 Base58Check 格式作為最終輸出格式))&lt;/li&gt;
&lt;li&gt;使用非壓縮，導出時使用 WIF 格式 (5 前綴)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="地址"&gt;地址&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;hash160 / double hash&lt;/li&gt;
&lt;li&gt;address = RIPEMD160(SHA256(K))&lt;/li&gt;
&lt;li&gt;經過 base58check 編碼呈現&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/lc2hEYS.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Base58: base64 去掉易混淆單字 ex. O, 0, I, l&amp;hellip;&lt;/li&gt;
&lt;li&gt;Base58Check: Base58 + error check&lt;/li&gt;
&lt;li&gt;$checksum = sha256(sha256(prefix+data))$ (data 是公鑰哈希，而不是純公鑰)&lt;/li&gt;
&lt;li&gt;只取前四個 bit
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/7xU5Ory.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;prefix
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/lIX7xIr.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="比特幣錢包"&gt;比特幣錢包&lt;/h3&gt;
&lt;p&gt;錢包是私鑰的容器&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;非確定性錢包：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;隨機生成 n 個私鑰，每個只使用一次&lt;/li&gt;
&lt;li&gt;需要整份備份&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;確定性種子錢包&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;單向離像方程式&lt;/li&gt;
&lt;li&gt;公共種子&lt;/li&gt;
&lt;li&gt;種子可以產生所有錢包裡的私鑰，因此只要備份種子就好了&lt;/li&gt;
&lt;li&gt;輔助記憶詞彙
&lt;ul&gt;
&lt;li&gt;易於記憶&lt;/li&gt;
&lt;li&gt;種子對應確定性錢包的隨機數&lt;/li&gt;
&lt;li&gt;BIP0039
&lt;ol&gt;
&lt;li&gt;生成 128~256 位 (2^&amp;hellip;) 的隨機數&lt;/li&gt;
&lt;li&gt;用 sha256 hash，取前幾位，生成 check bit&lt;/li&gt;
&lt;li&gt;num + check bit&lt;/li&gt;
&lt;li&gt;把數字分解成 11 位不同的集合 (11 bit 切一組，切成 n 組)，與預先定義好的字典做對應&lt;/li&gt;
&lt;li&gt;生成 12 ~ 24 個 word 的助記碼
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/KoQcb3F.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;分層性錢包 (HD 錢包)
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/bz9ljMP.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;BIP0032 標準&lt;/li&gt;
&lt;li&gt;母鑰匙生成子鑰匙&lt;/li&gt;
&lt;li&gt;樹狀結構&lt;/li&gt;
&lt;li&gt;建立公共密鑰的序列而不需要訪問相對的私鑰&lt;/li&gt;
&lt;li&gt;每筆交易發行不同的公鑰&lt;/li&gt;
&lt;li&gt;從種子產生 HD
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/FE5SOSD.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
![](
=150x)&lt;/li&gt;
&lt;li&gt;CKD (child key derivation)&lt;/li&gt;
&lt;li&gt;三個主要元素：
&lt;ul&gt;
&lt;li&gt;母私鑰&lt;/li&gt;
&lt;li&gt;鏈碼 (256bit)&lt;/li&gt;
&lt;li&gt;索引號 (index, 32bit)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;母公鑰 + 鏈碼 + 索引號 =&amp;gt; HMAC-sha512 =&amp;gt; 分成兩個 256 bit
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/K9fqChd.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;子密鑰無法 trace back 母密鑰&lt;/li&gt;
&lt;li&gt;子密鑰在沒有鏈碼下，也無法 trace 兄弟密鑰&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="擴展鑰匙-extending-key"&gt;擴展鑰匙 (extending key)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;鑰匙 + 鏈碼&lt;/li&gt;
&lt;li&gt;兩種
&lt;ul&gt;
&lt;li&gt;密鑰 + 鏈碼
&lt;ul&gt;
&lt;li&gt;可以衍生出子密鑰&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;公鑰 + 鏈碼
&lt;ul&gt;
&lt;li&gt;可以衍生出子公鑰&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;也是用 Base58Check 表示
&lt;ul&gt;
&lt;li&gt;512 or 513 bit&lt;/li&gt;
&lt;li&gt;前綴 &amp;lsquo;xprv&amp;rsquo; or &amp;lsquo;xpub&amp;rsquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="硬化子密鑰"&gt;硬化子密鑰&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;擴展公鑰可以衍生出所有鏈碼，只要有某一個子私鑰洩漏，就會從被洩露的子私鑰開始，得到所有私鑰 =&amp;gt; 不夠安全&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;子私鑰 &amp;amp; 母鏈碼 可以推測母私鑰！！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;hardened derivation
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/eFRP2OW.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;索引號&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;32 bit&lt;/li&gt;
&lt;li&gt;正常衍生: $0$ ~ $2^{31-1}$&lt;/li&gt;
&lt;li&gt;強化衍生: $2^{31}$ ~ $2^{32-1}$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="高級私鑰--地址"&gt;高級私鑰 &amp;amp; 地址&lt;/h3&gt;
&lt;p&gt;BIP0038: 使用另一個 key + AES 對私鑰加密&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;前綴: 6P&lt;/li&gt;
&lt;li&gt;用 AES + key 轉換回前綴為 5 的 base58check 格式&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="p2sh--多重簽名地址"&gt;P2SH &amp;amp; 多重簽名地址&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;P2SH: Pay-to-Script Hash&lt;/li&gt;
&lt;li&gt;P2SH 地址: 前綴 3&lt;/li&gt;
&lt;li&gt;收益者不是地址所有人，而會是交易雙方&lt;/li&gt;
&lt;li&gt;目前常用在 多重簽名地址 script
&lt;ul&gt;
&lt;li&gt;script 需要多個簽名來證明所有權&lt;/li&gt;
&lt;li&gt;N 個密碼中，至少需要 M 個來簽，才能證明所有權&lt;/li&gt;
&lt;li&gt;詳細放在 ch5&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="靚號地址"&gt;靚號地址&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;地址中有指定的 pattern
&lt;ul&gt;
&lt;li&gt;ex. iloveyou&amp;hellip;&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;用不斷的 hash 密鑰，直到找到符合 pattern 的密鑰&lt;/li&gt;
&lt;li&gt;如果特定 pattern 夠長，可以增加地址比對時的安全性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="紙錢包"&gt;紙錢包&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;將地址印在紙上，通常會配合 BIP0038 地址加密&lt;/li&gt;
&lt;li&gt;可多次存入，但最好一次性提取，避免產生找零地址 (?)&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/1XjdFPz.jpg" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ch5-交易"&gt;Ch5 交易&lt;/h2&gt;
&lt;h3 id="交易生命週期"&gt;交易生命週期&lt;/h3&gt;
&lt;h2 id="ch6-比特幣網路"&gt;Ch6 比特幣網路&lt;/h2&gt;
&lt;h2 id="ch7-區塊鏈"&gt;Ch7 區塊鏈&lt;/h2&gt;
&lt;h3 id="簡介"&gt;簡介&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;包含交易訊息由後向前有序連接
&lt;ul&gt;
&lt;li&gt;flat file&lt;/li&gt;
&lt;li&gt;LevelDB (Google)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;每一塊都指向前一塊
&lt;ul&gt;
&lt;li&gt;垂直的 stack&lt;/li&gt;
&lt;li&gt;創世區塊為最底塊&lt;/li&gt;
&lt;li&gt;高度代表該區塊與創世區塊之間的距離&lt;/li&gt;
&lt;li&gt;頂端添加新區塊&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;區塊識別
&lt;ul&gt;
&lt;li&gt;區塊頭做 SHA256 兩次&lt;/li&gt;
&lt;li&gt;利用區塊頭的父區塊 hash 值識別父區塊&lt;/li&gt;
&lt;li&gt;可以從最新的區塊一路往回追溯至創世區塊，形成區塊鏈&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;分岔
&lt;ul&gt;
&lt;li&gt;每個區塊僅有一父區塊，但可能暫時擁有多個子區塊&lt;/li&gt;
&lt;li&gt;多個區塊幾乎同時被礦工挖出時發生&lt;/li&gt;
&lt;li&gt;解決方法後面會詳細說明&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;安全性
&lt;ul&gt;
&lt;li&gt;若要竄改一區塊內容則必須重新計算該區塊 hash 值，接著更新子區塊頭的父區塊 hash 值，一直更新到最新的區塊為止，如此的計算資源龐大不易成功&lt;/li&gt;
&lt;li&gt;差不多六個區塊後可被竄改的機會非常低&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="區塊結構"&gt;區塊結構&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;包含交易訊息的資料結構
&lt;ul&gt;
&lt;li&gt;區塊頭
&lt;ul&gt;
&lt;li&gt;80 bytes&lt;/li&gt;
&lt;li&gt;區塊識別&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;區塊主體
&lt;ul&gt;
&lt;li&gt;大小可變&lt;/li&gt;
&lt;li&gt;紀錄交易&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;平均每筆交易至少 250 bytes&lt;/li&gt;
&lt;li&gt;平均每個區塊至少 500 個交易
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/CjidmkR.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="區塊頭"&gt;區塊頭&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;父區塊 hash 值
&lt;ul&gt;
&lt;li&gt;用於指向父區塊&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Merkle root
&lt;ul&gt;
&lt;li&gt;可有效總結區塊中所有交易的資料結構&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Nonce、難度目標、時間戳記與挖礦相關，會在之後說明
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/0FLk3tN.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="區塊識別"&gt;區塊識別&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;區塊頭 hash 值
&lt;ul&gt;
&lt;li&gt;32 bytes&lt;/li&gt;
&lt;li&gt;SHA256 兩次區塊頭所得的數位指紋&lt;/li&gt;
&lt;li&gt;唯一明確的識別一個區塊&lt;/li&gt;
&lt;li&gt;第一個比特幣區塊頭 hash 值&lt;/li&gt;
&lt;li&gt;&lt;code&gt;000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;區塊高度
&lt;ul&gt;
&lt;li&gt;創世區塊高度為零&lt;/li&gt;
&lt;li&gt;每增加一個區塊高度加一&lt;/li&gt;
&lt;li&gt;並不一定是唯一識別，在區塊鏈分岔時同一高度有多個區塊&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;兩者並不包含在區塊中，在節點接收區塊時計算並儲存，便於查詢檢索&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="創世區塊"&gt;創世區塊&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2009 年創建&lt;/li&gt;
&lt;li&gt;所有區塊的祖先&lt;/li&gt;
&lt;li&gt;編入比特幣客戶端程式中，確保創世區塊不會改變，並從此建構區塊鏈&lt;/li&gt;
&lt;li&gt;
中可以看到創世區塊詳細內容&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="區塊的連接"&gt;區塊的連接&lt;/h3&gt;
&lt;p&gt;比特幣的完整節點是從創世節點到最新節點的一個本地副本，當接收到一個新區塊時，需驗證然後接到現有區塊上&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;檢查傳入的區塊頭並尋找父區塊
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/YTpywFx.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="merkle-tree"&gt;Merkle tree&lt;/h3&gt;
&lt;p&gt;區塊中包含的所有交易以 Merkle tree 形式呈現&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;hash 二元平衡樹&lt;/li&gt;
&lt;li&gt;用於快速歸納和檢驗大規模數據完整性&lt;/li&gt;
&lt;li&gt;快速驗證區塊中的交易是否存在&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="建立方法"&gt;建立方法&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;hash 方法採用 double-SHA256&lt;/li&gt;
&lt;li&gt;由葉節點建立到根節點&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;將所有元素做 double-SHA256 後放入葉節點&lt;/li&gt;
&lt;li&gt;串聯兩節點的 hash 值做 double-SHA256 生成父節點&lt;/li&gt;
&lt;li&gt;重複步驟 2 直到剩下一個節點為止，此點即為 Merkle root&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/uaRcghh.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;若葉節點個數為奇數則將最後一筆交易重複一次，以維持偶數個葉節點&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/JpKEPLm.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 id="驗證交易存在"&gt;驗證交易存在&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;綠色為要驗證的交易對應的節點&lt;/li&gt;
&lt;li&gt;藍色為 Merkle 路徑&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/7Lis8PB.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;若要驗證交易是否存在可以參考 Merkle tree 建立方法，將 Merkle 路徑與該交易依序做 hash 生成藍色虛線的節點，最終比較 Merkle root 是否相同，即可得知該交易是否存在於區塊中&lt;/p&gt;
&lt;h4 id="效率"&gt;效率&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;時間複雜度 ${O(log\ n)}$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/UUb0RXT.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id="簡單支付驗證-spv"&gt;簡單支付驗證 (SPV)&lt;/h3&gt;
&lt;p&gt;利用 Merkel tree 驗證交易，SPV 不下載交易紀錄和區塊，僅保存區塊頭，利用 Merkle 路徑驗證交易存在&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Merkel 區塊
&lt;ul&gt;
&lt;li&gt;區塊頭&lt;/li&gt;
&lt;li&gt;Merkel 路徑&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ch8-挖礦與共識"&gt;Ch8 挖礦與共識&lt;/h2&gt;
&lt;h3 id="簡介-1"&gt;簡介&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;挖礦
&lt;ul&gt;
&lt;li&gt;增加比特幣&lt;/li&gt;
&lt;li&gt;保護比特幣系統安全&lt;/li&gt;
&lt;li&gt;提供算力獲取比特幣&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;礦工
&lt;ul&gt;
&lt;li&gt;驗證每筆交易並記錄到區塊鏈中&lt;/li&gt;
&lt;li&gt;平均 10 分鐘挖出一個新的區塊&lt;/li&gt;
&lt;li&gt;得到新幣獎勵和手續費&lt;/li&gt;
&lt;li&gt;工作量證明&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;發行
&lt;ul&gt;
&lt;li&gt;預計發行到 2140 年，上限為 2100 萬個&lt;/li&gt;
&lt;li&gt;每隔 210000 塊 (大約 4 年)，新區塊挖出獎勵減半&lt;/li&gt;
&lt;li&gt;2009 / 01 獎勵 50 比特幣&lt;/li&gt;
&lt;li&gt;2012 / 11 獎勵 25 比特幣&lt;/li&gt;
&lt;li&gt;2016 / 07 獎勵 12.5 比特幣&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="比特幣經濟學和貨幣創造"&gt;比特幣經濟學和貨幣創造&lt;/h4&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/dEiBmbL.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;抗通膨
&lt;ul&gt;
&lt;li&gt;總量有限&lt;/li&gt;
&lt;li&gt;發行速度遞減&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;通縮貨幣
&lt;ul&gt;
&lt;li&gt;貨幣供需不平衡所導致增值&lt;/li&gt;
&lt;li&gt;隨時間增長有愈來愈強的購買力&lt;/li&gt;
&lt;li&gt;是否會有隱藏未知的經濟風險&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="去中心化共識"&gt;去中心化共識&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;沒有經過明確的投票或固定達成共識的時間&lt;/li&gt;
&lt;li&gt;異步互動更新&lt;/li&gt;
&lt;li&gt;每個全節點依據綜合標準對每個交易進行獨立驗證&lt;/li&gt;
&lt;li&gt;通過完成工作量證明演算法的驗算，礦工將交易紀錄獨立打包進新區塊&lt;/li&gt;
&lt;li&gt;每個節點獨立的對新區塊進行檢驗並加入區塊鏈&lt;/li&gt;
&lt;li&gt;每個節點對區塊鏈進行獨立選擇，在工作量證明機制下選擇累計工作量較大的區塊&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="交易的獨立檢驗"&gt;交易的獨立檢驗&lt;/h3&gt;
&lt;p&gt;收到一個交易時先驗證交易，有效交易繼續傳播，無效則丟棄&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/qZJY7Ez.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;詳細可參考
、
、
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;隨時間可能會有所改變，為處理惡意攻擊或要使交易更多樣化而放寬&lt;/li&gt;
&lt;li&gt;收到交易後對全網廣播前先驗證，並以接收順序建立交易池&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="挖礦節點"&gt;挖礦節點&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;接收驗證交易並在新區塊中整合&lt;/li&gt;
&lt;li&gt;隨時監聽新區塊，若有人已經打包出新區塊則放棄，繼續打包下一個區塊&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="整合交易至區塊"&gt;整合交易至區塊&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在接收到新節點時，將交易池中已打包的交易移除&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="交易塊齡礦工費和優先級"&gt;交易塊齡、礦工費和優先級&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;塊齡為 UTXO 被記錄到區塊前所經過的區塊數&lt;/li&gt;
&lt;li&gt;按照礦工費排序，優先將高礦工費的交易打包&lt;/li&gt;
&lt;li&gt;優先級
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Priority = Sum (Value of input * Input Age) / Transaction Size&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如果區塊有足夠空間，則高優先級的交易將不需礦工費&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="鑄幣交易-coinbase"&gt;鑄幣交易 (coinbase)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;打包出新區塊的獎勵&lt;/li&gt;
&lt;li&gt;沒有輸入，不消耗 UTXO&lt;/li&gt;
&lt;li&gt;輸出到礦工地址&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="coinbase-獎勵與礦工費"&gt;coinbase 獎勵與礦工費&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;GetBlockValue&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int64_t&lt;/span&gt; &lt;span class="nf"&gt;GetBlockValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;nHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int64_t&lt;/span&gt; &lt;span class="n"&gt;nFees&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int64_t&lt;/span&gt; &lt;span class="n"&gt;nSubsidy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;COIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;halvings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nHeight&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;SubsidyHalvingInterval&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//210000 blocks
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;halvings&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nFees&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;nSubsidy&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;halvings&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nSubsidy&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;nFees&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;礦工費
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Total Fees = Sum(Inputs) Sum(Outputs)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="鑄幣交易結構"&gt;鑄幣交易結構&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;普通交易
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/uvLAOYc.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;鑄幣交易
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/symOzly.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="coinbase-數據"&gt;coinbase 數據&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;不包含 scriptSig 以 coinbase 取代，最小 2 bytes 最大 100 bytes&lt;/li&gt;
&lt;li&gt;除了開始的幾個 bytes 外，礦工可以任意填充其他部分&lt;/li&gt;
&lt;li&gt;創世區塊中的 coinbase&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;The Times 03/Jan/2009 Chancellor on brink of second bailout for banks&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;利用 coinbase 實現 extra nonce 功能，標示挖出的礦池&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="構造區塊頭"&gt;構造區塊頭&lt;/h3&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/rL9fO9l.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id="建構區塊"&gt;建構區塊&lt;/h3&gt;
&lt;p&gt;藉由修改 nonce 值重複計算區塊頭 hash 值，直到符合難度條件&lt;/p&gt;
&lt;h4 id="工作量證明算法"&gt;工作量證明算法&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;hash 輸入長度任意，輸出長度固定且對於不同字串輸出幾乎不會相同，可作為數位指紋&lt;/li&gt;
&lt;li&gt;有意選擇輸入並生成一個特定 hash 值幾乎不可能&lt;/li&gt;
&lt;li&gt;礦工藉由修改 nonce 直到區塊頭 hash 值足夠小&lt;/li&gt;
&lt;li&gt;可藉由統計估算礦工工作量&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="難度表示"&gt;難度表示&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;難度位、bits&lt;/li&gt;
&lt;li&gt;前 1 byte 為冪次後為係數&lt;/li&gt;
&lt;li&gt;&lt;code&gt;target = coefficient * 2^(8 * (exponent – 3))&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;範例：難度位的值為 0x1903a30c&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;target = 0x03a30c * 2^(0x08 * (0x19 0x03))
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;=&amp;gt; target = 0x03a30c * 2^(0x08 * 0x16)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;=&amp;gt; target = 0x03a30c * 2^0xB0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;=&amp;gt; target = 0x0000000000000003A30C00000000000000000000000000000000000000000000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="難度目標與難度調整"&gt;難度目標與難度調整&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;維持 10 分鐘生成一個區塊&lt;/li&gt;
&lt;li&gt;每個完整節點自動調整
&lt;ul&gt;
&lt;li&gt;每 2016 個區塊的時間與 20160 分鐘比較來調整難度&lt;/li&gt;
&lt;li&gt;&lt;code&gt;New Difficulty = Old Difficulty * (Actual Time of Last 2016 Blocks / 20160 minutes)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;每次調整幅度最高為 4 倍，平衡算力和難度巨大差異&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;難度與交易量和金額無關&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="成功建構區塊"&gt;成功建構區塊&lt;/h3&gt;
&lt;p&gt;算出符合條件的特定 nonce 值後立即發給相鄰節點，其他節點驗證通過後在發送出去，同時放棄打包同高度的區塊立即開始打包下一塊&lt;/p&gt;
&lt;h3 id="檢驗新區塊"&gt;檢驗新區塊&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;每個節點獨立驗證
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/ayJn4gL.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;h3 id="區塊鏈的組裝與選擇"&gt;區塊鏈的組裝與選擇&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;將區塊集合至最大工作量證明的鏈上&lt;/li&gt;
&lt;li&gt;節點維護的區塊
&lt;ul&gt;
&lt;li&gt;連接到主鏈&lt;/li&gt;
&lt;li&gt;分支或備用鏈&lt;/li&gt;
&lt;li&gt;孤兒區塊&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;兩區塊在短時間內被挖出，節點可能會以相反的順序接收接收，造成孤兒區塊&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="區塊練的分岔"&gt;區塊練的分岔&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;區塊不同時間抵達節點導致不同副本不一致&lt;/li&gt;
&lt;li&gt;每個節點延長最大工作量的鏈&lt;/li&gt;
&lt;li&gt;最終可以收斂到一致的狀態&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;礦工幾乎同時挖到區塊，各自廣播出去形成分支&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/sNF9v5t.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;其中一條鏈先挖到下一區塊&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/g9cOp4R.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;重新共識收斂為同一主鏈&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/wvgC3DQ.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id="挖礦與算力競賽"&gt;挖礦與算力競賽&lt;/h3&gt;
&lt;p&gt;極富競爭性並且算力以指數及成長
CPU ${\rightarrow}$ GPU ${\rightarrow}$ FPGA ${\rightarrow}$ ASIC&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/tOpvaLA.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/14WoJbH.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 id="隨機值升位方案"&gt;隨機值升位方案&lt;/h4&gt;
&lt;p&gt;算力增加使得難度增加，所需的隨機值不足&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;早期可以透過修改時間戳解決，但移動太多會變成無效區塊&lt;/li&gt;
&lt;li&gt;利用 coinbase 交易可以在 coinbase script 裡寫入任意值，進而改變 Merkel root 作為額外隨機值來源&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="礦池"&gt;礦池&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;礦工合作組成
&lt;ul&gt;
&lt;li&gt;集合算力&lt;/li&gt;
&lt;li&gt;分享獎勵&lt;/li&gt;
&lt;li&gt;減少不確定性&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;設定較低的難度
&lt;ul&gt;
&lt;li&gt;評估各礦工算力&lt;/li&gt;
&lt;li&gt;算出來的解並不一定滿足新區塊要求&lt;/li&gt;
&lt;li&gt;有時產出符合的區塊可以一起分潤&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="共識攻擊"&gt;共識攻擊&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;51% 攻擊
&lt;ul&gt;
&lt;li&gt;算力過大，30% 以上就有威脅&lt;/li&gt;
&lt;li&gt;至多可影響最近 10 個區塊&lt;/li&gt;
&lt;li&gt;實現雙花或拒絕他人交易&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;防禦
&lt;ul&gt;
&lt;li&gt;等待 6 個以上區塊確認&lt;/li&gt;
&lt;li&gt;第三方等多方認證簽名&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在算力以指數及增加的現今要達成攻擊難上加難&lt;/p&gt;</description></item><item><title>MikroTik RouterBoard 設定</title><link>https://calee0219.github.io/blog/note_mkt_routerboard/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_mkt_routerboard/</guid><description>&lt;h3 id="wiki"&gt;
&lt;/h3&gt;
&lt;h2 id="reset"&gt;Reset&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;斷電時 按(插)住 reset 鍵，接電，等到燈光閃爍後，放開&lt;/li&gt;
&lt;li&gt;/system reset-configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="連接"&gt;連接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;下載官網給的
&lt;/li&gt;
&lt;li&gt;點開後，在 &lt;code&gt;connect to&lt;/code&gt; 的地方打入 MAC address，按 &lt;code&gt;Connect To RoMON&lt;/code&gt;，等他自己找到 routerboard&lt;/li&gt;
&lt;li&gt;Login 打 admin，Password 留白&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Connect&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="wan-設定"&gt;WAN 設定&lt;/h2&gt;
&lt;h3 id="static-ip"&gt;Static IP&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;/ip route add gateway={getway} dst-address=0.0.0.0/0: 設定好對外連線的 gateway&lt;/li&gt;
&lt;li&gt;/ip address add interface={eth1} address={static ip} network={} netmask={}&lt;/li&gt;
&lt;li&gt;/ping 8.8.8.8&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dhcp"&gt;DHCP&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;/ip dhcp-client add interface={port id}&lt;/li&gt;
&lt;li&gt;/ip dhcp-client enable: 將他開起來&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="lan"&gt;LAN&lt;/h2&gt;
&lt;h3 id="nat"&gt;NAT&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;/ip address add interface=ether3 address={192.168.3.1} network={192.168.3.0} netmask={255.255.255.0} &amp;lt;- 這裡的 address 會是下面機器的 gateway，netmask 會是下面機器可以用的網段&lt;/li&gt;
&lt;li&gt;/ip firewall nat add chain=srcnat src-address=192.168.2.0/24 action=masquerade: 讓網域下可以用 NAT 對外連線 (srnat: 將內網封包轉到外網)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dhcp-1"&gt;DHCP&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;/ip pool add name={name} ranges={x.x.x.x}-{x.x.x.x}: 先開出這個 DHCP Server 要分下去的 range&lt;/li&gt;
&lt;li&gt;/ip dhcp-server add name={name} interface={ether1} address-pool={pool name}&lt;/li&gt;
&lt;li&gt;/ip dhcp-server network add address={192.168.5.0/24} gateway={192.168.5.1}: 設定 DHCP default gateway&lt;/li&gt;
&lt;li&gt;/ip dhcp-server enable&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dhcp-bind-mac-address"&gt;DHCP bind MAC address&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;/ip dhcp-server lease make-static&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="port-forwarding"&gt;Port Forwarding&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;/ip firewall nat add chain=dstnat action=dst-nat protocol=tcp dst-address={WAN IP} dst-port={外網看得到的 port} to-address={內網 ip} to-ports={內部 port(22/80)}&lt;/li&gt;
&lt;li&gt;/ip firewall nat move {4} destination={0}: 將規則往前移動&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="security"&gt;Security&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;/password old-password={} new-password={} confirm-new-password={}&lt;/li&gt;
&lt;li&gt;/user set 0 address={}&lt;/li&gt;
&lt;li&gt;/ip service ssh port={}: 改 ssh port&lt;/li&gt;
&lt;li&gt;/system ssh port={}: 改 ssh port&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="config"&gt;Config&lt;/h2&gt;
&lt;h3 id="firewall-nat"&gt;firewall nat&lt;/h3&gt;
&lt;h3 id="dhcp-server-lease"&gt;dhcp-server lease&lt;/h3&gt;</description></item><item><title>Nagious</title><link>https://calee0219.github.io/blog/nagious/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/nagious/</guid><description>&lt;h2 id="介紹"&gt;介紹&lt;/h2&gt;
&lt;p&gt;
&amp;lt;- 點我&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/9JnBhHE.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Main Config : 控制Nagios Deamon的行為，這份config會被Deamon和CGIs讀&lt;/li&gt;
&lt;li&gt;Resource File: 儲存user-defined macro，權限660&lt;/li&gt;
&lt;li&gt;Object Definition File : 定義host, service, hostgroup, command, etc，決定要監控的項目和要如何監控&lt;/li&gt;
&lt;li&gt;CGI Config File : 讓Nagios知道main config位置以及你怎麼設定Nagios和object define的位置&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="config-內容"&gt;Config 內容&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;主要config檔在 /usr/local/nagios/etc&lt;/li&gt;
&lt;li&gt;Nagios額外套件在 /usr/local/nagios/libexec&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="debug"&gt;Debug&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;/etc/init.d/nagios checkconfig&lt;/li&gt;
&lt;li&gt;journalctl -xe&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="安裝"&gt;安裝&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;快速安裝
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;curl&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;assets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;downloads&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagiosxi&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;install&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;手動安裝
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;wget&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;assets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;downloads&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagiosxi&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;xi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tar&lt;/span&gt; &lt;span class="n"&gt;xzf&lt;/span&gt; &lt;span class="n"&gt;xi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;latest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;nagiosxi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;./&lt;/span&gt;&lt;span class="n"&gt;fullinstall&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="web-顯示"&gt;Web 顯示&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;cd /etc/httpd/conf.d/&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="nagioscfg"&gt;nagios.cfg&lt;/h3&gt;
&lt;p&gt;
&amp;lt;- 點我&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;log_file=&amp;lt;file_name&amp;gt;
&lt;ul&gt;
&lt;li&gt;log_file=/usr/local/nagios/var/nagios.log&lt;/li&gt;
&lt;li&gt;設定log file的位置，當config有錯誤時，會記錄在這裡，適用rotation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;cfg_file=&amp;lt;file_name&amp;gt;
&lt;ul&gt;
&lt;li&gt;cfg_file=/usr/local/nagios/etc/hosts.cfg&lt;/li&gt;
&lt;li&gt;object config files位置&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;cfg_dir=&amp;lt;directory_name&amp;gt;
&lt;ul&gt;
&lt;li&gt;cfg_dir=/usr/local/nagios/etc/commands&lt;/li&gt;
&lt;li&gt;object config direction位置，其下的附檔名要是.cfg，會遞迴尋找config file&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;object_cache_file=&amp;lt;file_name&amp;gt;
&lt;ul&gt;
&lt;li&gt;object_cache_file=/usr/local/nagios/var/objects.cache&lt;/li&gt;
&lt;li&gt;default : &amp;lsquo;/dev/null&amp;rsquo;&lt;/li&gt;
&lt;li&gt;當Nagios被[re]start，存一份object definition到這裡。&lt;/li&gt;
&lt;li&gt;在running Nagios時，可以改object definition，而不會影響
Nagios&lt;/li&gt;
&lt;li&gt;這份檔案被CGIs使用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;precached_object_file=&amp;lt;file_name&amp;gt;
&lt;ul&gt;
&lt;li&gt;precached_object_file=/usr/local/nagios/var/objects.precache&lt;/li&gt;
&lt;li&gt;預處理object definition，當object definition很多時，可以加速&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;resource_file=&amp;lt;file_name&amp;gt;
&lt;ul&gt;
&lt;li&gt;resource_file=/usr/local/nagios/etc/resource.cfg&lt;/li&gt;
&lt;li&gt;放一些重要資訊，CGI不會讀這份檔案，權限設600或660&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;temp_file=&amp;lt;file_name&amp;gt;
&lt;ul&gt;
&lt;li&gt;temp_file=/usr/local/nagios/var/nagios.tmp&lt;/li&gt;
&lt;li&gt;Nagios在更新data時，會創建他，不用的時候會刪除他&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;temp_path=&amp;lt;dir_name&amp;gt;
&lt;ul&gt;
&lt;li&gt;temp_path=/tmp&lt;/li&gt;
&lt;li&gt;scratch space for creating temporary files used during the monitoring process&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;status_file=&amp;lt;file_name&amp;gt;
&lt;ul&gt;
&lt;li&gt;status_file=/usr/local/nagios/var/status.dat&lt;/li&gt;
&lt;li&gt;default : &amp;lsquo;/dev/null&amp;rsquo;&lt;/li&gt;
&lt;li&gt;store the current status, comment, and downtime information&lt;/li&gt;
&lt;li&gt;CGIs用這份檔案透過web來顯示監控狀況，需要讀取權限&lt;/li&gt;
&lt;li&gt;每次stop時，這份檔案會被刪掉&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;status_update_interval=&amp;lt; seconds &amp;gt;
&lt;ul&gt;
&lt;li&gt;status_update_interval=15&lt;/li&gt;
&lt;li&gt;多久更新一次status file，最短1秒&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;nagios_user=&amp;lt;username/UID&amp;gt;
&lt;ul&gt;
&lt;li&gt;nagios_user=nagios&lt;/li&gt;
&lt;li&gt;set the effective user that the Nagios process should run as&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;nagios_group=&amp;lt;groupname/GID&amp;gt;
&lt;ul&gt;
&lt;li&gt;nagios_group=nagios&lt;/li&gt;
&lt;li&gt;set the effective group that the Nagios process should run as&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;host_down_disable_service_checks=&amp;lt;0/1&amp;gt;
&lt;ul&gt;
&lt;li&gt;host_down_disable_service_checks=1&lt;/li&gt;
&lt;li&gt;This option will disable all service checks if the host is not in an UP state&lt;/li&gt;
&lt;li&gt;New config in Version 4&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;enable_notifications=&amp;lt;0/1&amp;gt;
&lt;ul&gt;
&lt;li&gt;enable_notifications=1&lt;/li&gt;
&lt;li&gt;Nagios will send out notifications for any host or service when it initially [re]starts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;execute_service_checks=&amp;lt;0/1&amp;gt;
&lt;ul&gt;
&lt;li&gt;execute_service_checks=1&lt;/li&gt;
&lt;li&gt;If this option is disabled, Nagios will not actively execute any service checks and will remain in a sort of &amp;ldquo;sleep&amp;rdquo; mode (it can still accept passive checks unless you&amp;rsquo;ve disabled them)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;accept_passive_service_checks=&amp;lt;0/1&amp;gt;
&lt;ul&gt;
&lt;li&gt;accept_passive_service_checks=1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;execute_host_checks=&amp;lt;0/1&amp;gt;
&lt;ul&gt;
&lt;li&gt;execute_host_checks=1&lt;/li&gt;
&lt;li&gt;Nagios will execute on-demand and regularly scheduled host checks when it initially (re)starts&lt;/li&gt;
&lt;li&gt;If this option is disabled, Nagios will not actively execute any host checks, although it can still accept passive host checks unless you&amp;rsquo;ve disabled them&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;accept_passive_host_checks=&amp;lt;0/1&amp;gt;
&lt;ul&gt;
&lt;li&gt;accept_passive_host_checks=1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;enable_event_handlers=&amp;lt;0/1&amp;gt;
&lt;ul&gt;
&lt;li&gt;enable_event_handlers=1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;log_rotation_method=&amp;lt;n/h/d/w/m&amp;gt;
&lt;ul&gt;
&lt;li&gt;log_rotation_method=d&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;log_current_states=&amp;lt;0/1&amp;gt;
&lt;ul&gt;
&lt;li&gt;log_current_states=1&lt;/li&gt;
&lt;li&gt;Nagios will log host and service current states at the beginning of a newly created log file after log rotation occurs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;log_archive_path=&amp;lt; path &amp;gt;
&lt;ul&gt;
&lt;li&gt;log_archive_path=/usr/local/nagios/var/archives/&lt;/li&gt;
&lt;li&gt;This is the directory where Nagios should place log files that have been rotated.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;External Command Check Option
&lt;ul&gt;
&lt;li&gt;Nagios will check the command file for commands that should be executed&lt;/li&gt;
&lt;li&gt;This option must be enabled if you plan on using the command CGI to issue commands via the web interface&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;command_file=&amp;lt;file_name&amp;gt;
&lt;ul&gt;
&lt;li&gt;command_file=/usr/local/nagios/var/rw/nagios.cmd&lt;/li&gt;
&lt;li&gt;The command CGI writes commands to this file. The external command file is implemented as a named pipe&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;check_for_updates=&amp;lt;0/1&amp;gt;
&lt;ul&gt;
&lt;li&gt;check_for_updates=1&lt;/li&gt;
&lt;li&gt;自動檢查Nagios有沒有new patch&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;bare_update_check=&amp;lt;0/1&amp;gt;
&lt;ul&gt;
&lt;li&gt;bare_update_check=0&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="object-definition"&gt;Object definition&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;define host {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; host_name 這個host的名字，其他define會用到
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; alias 類似註解
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; address IP或FQDN
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; parents 設定為最接近的上游設備(好像沒有用到)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; check_command 檢查這個主機是否正常，若無此項Nagios會認為他是alive的
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; check_interval check_command的正常測試間隔，其中的單位定義在Nagios設定的interval_length
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; retry_interval check_command的soft status時的重試間隔，達到max_check_attempts就會變為hard status
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; max_check_attempts check_command的檢查重試次數
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; check_period 執行active check的時段
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; process_perf_data 是否會處理performance data
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; retain_status_information 是否讀取重開機之前的狀態檔，前提是全域設定的retain_state_information必須設為1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; retain_nonstatus_information 是否不讀取主機狀態檔
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; contact_groups 要告警的人員群組，可用 “,” 分隔多個群組
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; notification_interval 當狀態持續發生時，兩個告警之間的時間。單位是interval_length
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; notification_period 會發送告警的時間
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; notification_options 哪幾種狀態才告警，DOWN = d，UNREACHABLE=u，回復到OK的狀態=r，flapping=f，排程關閉狀態=s，都不發送=n
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="安裝-1"&gt;安裝&lt;/h2&gt;
&lt;h3 id="需要工具"&gt;需要工具&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;yum install unzip wget httpd php php-cli gd gd-devel gcc glibc glibc-common net-snmp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="下載主程式"&gt;下載主程式&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cd /usr/local/src
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;wget http://liquidtelecom.dl.sourceforge.net/project/nagios/nagios-4.x/nagios-4.3.2/nagios-4.3.2.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cd nagios-4.3.2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ./configure --with-command-group=nagioscmd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make all
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make install
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make install-init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make install-config
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make install-commandmode
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make install-webconf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="下載插件-usrlocalnagioslibexec"&gt;下載插件 (/usr/local/nagios/libexec)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;wget&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;1.&lt;/span&gt;&lt;span class="n"&gt;tar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tar&lt;/span&gt; &lt;span class="n"&gt;xzf&lt;/span&gt; &lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;1.&lt;/span&gt;&lt;span class="n"&gt;tar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;./&lt;/span&gt;&lt;span class="n"&gt;configure&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;nagioscmd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;make&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="web監控的帳號密碼"&gt;Web監控的帳號密碼&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;注意 : 帳號名稱之間不能有空白&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;htpasswd -c /usr/local/nagios/etc/htpasswd.users {帳號名稱}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;authorized_for_system_information=...,帳號名稱
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;authorized_for_configuration_information=...,帳號名稱
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;authorized_for_system_commands=...,帳號名稱
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;authorized_for_all_hosts=...,帳號名稱
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;authorized_for_all_service_commands=...,帳號名稱
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;authorized_for_all_host_commands=...,帳號名稱
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="設定"&gt;設定&lt;/h2&gt;
&lt;h3 id="nagioscfg-1"&gt;nagios.cfg&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 設定Log存放位置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;log_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spool&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 設定指令參數&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cfg_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;commands&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 設定聯絡人資訊&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cfg_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;contactgroup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 設定CSCC相關聯絡人/群組資訊&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cfg_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;templates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cfg_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cfg_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;csgroup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 設定監控服務設定檔&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cfg_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 將object cache住，避免start/restart時有inconsistencies&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;object_cache_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spool&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 下特殊參數，加速用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;precached_object_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spool&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;precache&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 相關resource位置, ex:Nagios額外套件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;resource_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 儲存Nagios偵測結果檔案位置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;status_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spool&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dat&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 設定Nagios偵測結果狀態更新的時間區隔&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;status_update_interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 設定使用者/群組&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;nagios_user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;nagios_group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Nagios外部檢查命令功能開關，否則CGI不能用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;check_external_commands&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 檢查時間間隔，預設15s，-1為盡可能的檢查&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;command_check_interval&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;command_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spool&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;external_command_buffer_slots&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# PID資訊&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;lock_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spool&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Nagios執行時，暫存檔位置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;temp_file&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spool&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Nagios執行時，暫存目錄位置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;temp_path&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;event_broker_options&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;log_rotation_method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;log_archive_path&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spool&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;archives&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 使用syslog，開啟通知&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;use_syslog&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;log_notifications&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1 : 紀錄, 0 : 不紀錄&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;log_service_retries&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;log_host_retries&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;log_event_handlers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;log_initial_states&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;log_external_commands&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;log_passive_checks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;service_inter_check_delay_method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;max_service_check_spread&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;service_interleave_factor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;host_inter_check_delay_method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;max_host_check_spread&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;max_concurrent_checks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;#決定同時間執行多少個check processes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;check_result_reaper_frequency&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;max_check_result_reaper_time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;check_result_path&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spool&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nagios&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;checkresults&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;max_check_result_file_age&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cached_host_check_horizon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cached_service_check_horizon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;enable_predictive_host_dependency_checks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;enable_predictive_service_dependency_checks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;soft_state_dependencies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;auto_reschedule_checks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;auto_rescheduling_interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;auto_rescheduling_window&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;180&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;......&lt;/span&gt; &lt;span class="err"&gt;之後補上&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>NetApp</title><link>https://calee0219.github.io/blog/note_netapp/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_netapp/</guid><description>&lt;h2 id="背板資訊"&gt;背板資訊&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;兩個 SAS (LNK 0a, 0b)&lt;/li&gt;
&lt;li&gt;兩個 console (一個 RJ45, 一個 USB)&lt;/li&gt;
&lt;li&gt;一個 mgmt (e0M)&lt;/li&gt;
&lt;li&gt;一個 硬體資訊交換&lt;/li&gt;
&lt;li&gt;四個 data 網孔 (e0a, e0b, e0c, e0d)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="安裝"&gt;安裝&lt;/h2&gt;
&lt;p&gt;可以從 http / tftp 裝 OS 安裝 (無法使用 USB)
Ctrl-C 進入 loader&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用網路開機
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ifconfig&lt;/span&gt; &lt;span class="n"&gt;e0M&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mask&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;# 設定 ip&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;netboot&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//...&lt;/span&gt; &lt;span class="c1"&gt;# 用網路開機&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;e0M 是網孔名稱，用 mgmt port 安裝&lt;/li&gt;
&lt;li&gt;安裝 OS
開始開機後，在一半要按 Ctrl-C 進 boot menu
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Select&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="c1"&gt;# 裝 OS (一樣是用 http 抓，輸入網路上的位置 [http://xxx])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 然後會問是否 backup config 與 是否 reboot，直接 reboot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# reboot 後就不用 Ctrl-C 進 loader 了，直接到進 boot menu 的地方在 Ctrl-C&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Select&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;# 進 memtance mode 清 disk owner，將所有 disk 權限要回&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;disk&lt;/span&gt; &lt;span class="n"&gt;xxx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;disk&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="c1"&gt;# 把 disk owner 拉成 local user&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Select&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="c1"&gt;# 清掉所有 config&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Select&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="c1"&gt;# reboot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;2T 硬碟大概要 init 8 ~ 15 hr&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>NGINX 好用設定</title><link>https://calee0219.github.io/blog/nginx/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/nginx/</guid><description>&lt;h2 id="certbot"&gt;
&lt;/h2&gt;
&lt;p&gt;(let&amp;rsquo;s encrypt 簽 https)&lt;/p&gt;
&lt;h3 id="install"&gt;Install&lt;/h3&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo apt-get install software-properties-common
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo add-apt-repository ppa:certbot/certbot
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ sudo apt-get install python-certbot-nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Fedora
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install certbot-nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="簽署"&gt;簽署&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;自動幫改 nginx 設定檔&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo certbot --nginx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;手動改 nginx 設定檔&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo certbot --nginx certonly
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;自動更新憑證&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo certbot renew --dry-run
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;手動更新憑證&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;certbot renew
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="redirect-to-https"&gt;Redirect to https&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;301
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;server &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; listen &lt;span class="m"&gt;443&lt;/span&gt; ssl&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# managed by Certbot &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ssl_certificate /etc/letsencrypt/live/notebook.calee.xyz/fullchain.pem&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# managed by Certbot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ssl_certificate_key /etc/letsencrypt/live/notebook.calee.xyz/privkey.pem&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# managed by Certbot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; include /etc/letsencrypt/options-ssl-nginx.conf&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# managed by Certbot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# managed by Certbot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$scheme&lt;/span&gt; !&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;301&lt;/span&gt; https://&lt;span class="nv"&gt;$host$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;rewrite
&lt;ul&gt;
&lt;li&gt;除了 301 redirect 之外，nginx 還有一個 Force HTTPS 是用 rewrite 來處理
不過要小心也可能出現 Mixed Content too many 的問題&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rewrite ^ https://&lt;span class="nv"&gt;$server_name$request_uri&lt;/span&gt;? permanent&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="redirect-too-many"&gt;Redirect too many&lt;/h3&gt;
&lt;p&gt;如果你的 domain 有上 CDN，會有 redirect too many 的問題，解法是偵測請求協定是否為 http，若是，才可以 redirect 了
通常出現在 DNS 是由 cloud flare 代管，並且有上 CDN 的情況下
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;server &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; listen 80&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$http_x_forwarded_proto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;http&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;301&lt;/span&gt; https://&lt;span class="nv"&gt;$server_name$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="hsts"&gt;hsts&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;server &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; listen &lt;span class="m"&gt;443&lt;/span&gt; ssl&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; add_header Strict-Transport-Security &lt;span class="s2"&gt;&amp;#34;max-age=31536000; includeSubDomains&amp;#34;&lt;/span&gt; always&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Because this &amp;#39;location&amp;#39; block contains another &amp;#39;add_header&amp;#39; directive,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# we must redeclare the STS header&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; location /servlet &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; add_header X-Served-By &lt;span class="s2"&gt;&amp;#34;My Servlet Handler&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; add_header Strict-Transport-Security &lt;span class="s2"&gt;&amp;#34;max-age=31536000; includeSubDomains&amp;#34;&lt;/span&gt; always&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_pass http://localhost:8080&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;includeSubDomains: always; 會讓所有 subdomains 都上 hsts，此處需要小心&lt;/li&gt;
&lt;li&gt;(servlet) 如果有一個的 block 本身有自己加 header，需要重新把 hsts 寫進去，不然會被覆蓋掉&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="加密檢測"&gt;加密檢測&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;如果你透過Chrome瀏覽器發現網站的連線變成「https」然後是灰色，你可以點一下即可查資訊，他會顯示「這個網頁含有其他不安全的資源」，那代表網站有使用到非https的圖片、js、css的資源，那就得修正了。&lt;/li&gt;
&lt;li&gt;有時候可能是 hsts subdomain 還沒全部生效，重轉幾次就好了 (?)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;permission deny 問題:
&lt;ul&gt;
&lt;li&gt;簡言之，nginx 要全部的歷遍權限都有才能讀檔案，所以路徑上的 file 都要 o+x&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SELinux reverse proxy:
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;SELinux 有擋 reverse，隨便的 port 不能開 http (可能怕 SSRF ?)&lt;/li&gt;
&lt;li&gt;需要下 &lt;code&gt;semanage port -a -t http_port_t -p tcp {to port no.}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;上面那個好像不用下，下這個就好 &lt;code&gt;setsebool -P httpd_can_network_connect 1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;(待釐清)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="load-balance"&gt;Load Balance&lt;/h2&gt;
&lt;p&gt;這裡指的是 proxy pass 的 load balance&lt;/p&gt;
&lt;p&gt;利用 upstream 參數，參考
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;upstream backend {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; server backend1.example.com weight=5; # 可以設定權重
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; server backend2.example.com:8080; # 可以用 port
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; server unix:/tmp/backend3; # 可以用 unix domain socket
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; server backup1.example.com:8080 backup; # 備援
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; server backup2.example.com:8080 backup;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;server {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; listen 443 ssl http2;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; location / {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; proxy_pass https://backend; # 記得使用 upstream 定義的參數
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="ipv6-enable"&gt;IPv6 enable&lt;/h2&gt;
&lt;p&gt;其實很簡單，參考 nginx.conf 也有寫的，只要多加 ipv6 的 ip 在 port 前面，沒寫 ip 預設只有 ipv4。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;server {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; listen 443;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; listen [::]:443;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; listen 80;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; listen [::]:80;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Package Manager</title><link>https://calee0219.github.io/blog/note_package_manager/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_package_manager/</guid><description>&lt;h3 id="ubuntu-ppa"&gt;Ubuntu ppa&lt;/h3&gt;
&lt;p&gt;Sourse List
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/etc/apt/sources.list.d/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="deb-basic"&gt;deb basic&lt;/h3&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo apt update&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo apt upgrade&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo apt remove&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo apt-get --purge remove [name]&lt;/code&gt;: 連設定檔一起移除&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo apt-get clean&lt;/code&gt;: 清除 &lt;code&gt;/var/cache/apt/archives/&lt;/code&gt; 下的所有 DEB 套件檔 (白話文：清除已經下載的套件)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo apt-get autoclean&lt;/code&gt;: 清除 &lt;code&gt;/var/cache/apt/archives/&lt;/code&gt; 下已經過期的 DEB 套件檔&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="未滿足相依關係"&gt;未滿足相依關係&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;系統處理
&lt;code&gt;sudo apt --fix-broken install&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;尋找那個套件是那一套件需要用的，把套件刪掉
`sudo apt remove xxx&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Proxmox 相關</title><link>https://calee0219.github.io/blog/note_proxmox/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_proxmox/</guid><description>&lt;h3 id="proxmox-ve-4x-中文初階學習手冊"&gt;
&lt;/h3&gt;
&lt;h2 id="安裝"&gt;安裝&lt;/h2&gt;
&lt;h3 id="磁碟選擇"&gt;磁碟選擇&lt;/h3&gt;
&lt;p&gt;在選擇安裝磁碟時，有一個 Options 可以調整&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Filesystem
&lt;ul&gt;
&lt;li&gt;ext3&lt;/li&gt;
&lt;li&gt;ext4&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;zfs (RAID 0)
&lt;ul&gt;
&lt;li&gt;加速，分散儲存，不做備份&lt;/li&gt;
&lt;li&gt;一顆硬碟壞掉，就全部壞掉了&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;zfs (RAID 1)
&lt;ul&gt;
&lt;li&gt;完全備份，不加速&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;zfs (RAID 10)
&lt;ul&gt;
&lt;li&gt;需要至少 4 顆硬碟&lt;/li&gt;
&lt;li&gt;![](
=200x)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;zfs (RAIDZ-1)
&lt;ul&gt;
&lt;li&gt;RAIDZ 好像就是 RAID5&lt;/li&gt;
&lt;li&gt;需要至少 3 顆硬碟&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;zfs (RAIDZ-2)
&lt;ul&gt;
&lt;li&gt;需要至少 4 顆硬碟&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;zfs (RAIDZ-3)
&lt;ul&gt;
&lt;li&gt;需要至少 5 顆硬碟&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Advanced Options
&lt;ul&gt;
&lt;li&gt;ashift
&lt;ul&gt;
&lt;li&gt;ZFS 中最小的存取單元&lt;/li&gt;
&lt;li&gt;default value = 9, 即最小的存取單位是 2 ^ 9 = 512 bytes. 剛好符合傳統的硬碟1 sector 的size.&lt;/li&gt;
&lt;li&gt;若要讓ZFS 支援Advanced Format HDD 的方法就是將ashift 值改為12 (2 ^ 12 = 4096 bytes)&lt;/li&gt;
&lt;li&gt;12 好像也剛好是 4k 對齊&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;compress
&lt;ul&gt;
&lt;li&gt;on&lt;/li&gt;
&lt;li&gt;off&lt;/li&gt;
&lt;li&gt;lzjb&lt;/li&gt;
&lt;li&gt;lz4
&lt;ul&gt;
&lt;li&gt;lzjb 的替代，具有较高的压缩和解压性能，同时具有折中的压缩比，推荐使用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;checksum
&lt;ul&gt;
&lt;li&gt;on&lt;/li&gt;
&lt;li&gt;off&lt;/li&gt;
&lt;li&gt;fletcher2&lt;/li&gt;
&lt;li&gt;fletcher4&lt;/li&gt;
&lt;li&gt;sha256&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;copies&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="更新"&gt;更新&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;/etc/apt/sources.list.d/pve-enterprise.list &lt;/code&gt;
進這裡把 &lt;code&gt;deb https://enterprise.proxmox.com/debian wheezy pve-enterprise &lt;/code&gt; 註解掉，因為你沒有錢 XD&lt;/p&gt;</description></item><item><title>SSH 相關設定</title><link>https://calee0219.github.io/blog/note_ssh/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_ssh/</guid><description>&lt;p&gt;SSH 的全稱是 secure shell，大家都知道可以用來遠端進入機器的殼層，但有一些有趣的設定或應用也許不是廣為人知，仔細研究會發現 SSH 其實還蠻可怕的 XD&lt;/p&gt;
&lt;h2 id="client-side"&gt;Client Side&lt;/h2&gt;
&lt;h3 id="ssh-key"&gt;SSH key&lt;/h3&gt;
&lt;h3 id="ssh-with-hardware-key"&gt;SSH with hardware key&lt;/h3&gt;
&lt;h3 id="security-issue"&gt;Security issue&lt;/h3&gt;
&lt;h3 id="ssh-tunnel"&gt;SSH Tunnel&lt;/h3&gt;
&lt;h2 id="server-side"&gt;Server Side&lt;/h2&gt;
&lt;h2 id="password-policy"&gt;Password Policy&lt;/h2&gt;
&lt;p&gt;密碼品質檢查，這個功能其實不是掛在 ssh 下面的，只是因為 ssh 是 pam linux 的，所以可以順便避免 user 弱密碼導致 ssh 被破解 (&lt;code&gt;man pam_pwquality&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;參考
&lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>systemd 小記</title><link>https://calee0219.github.io/blog/note_systemd/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_systemd/</guid><description>&lt;h3 id="sample"&gt;sample&lt;/h3&gt;
&lt;p&gt;位置 &lt;code&gt;/lib/systemd/system/xxx.service&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Jupyter&lt;/span&gt; &lt;span class="n"&gt;Notebook&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Documentation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;man&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;mysqld&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Documentation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;mariadb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;kb&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;en&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;library&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;systemd&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="n"&gt;syslog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Install&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;multi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Alias&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Alias&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;mysqld&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;simple&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;StandardError&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;inherit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;StandardOutput&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;syslog&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;PIDFile&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jupyter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Step 1 and Step 2 details are here..&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ------------------------------------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ExecStartPre&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;avkash&lt;/span&gt;&lt;span class="o"&gt;/.&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jupyter&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;notebook&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;avkash&lt;/span&gt;&lt;span class="o"&gt;/.&lt;/span&gt;&lt;span class="n"&gt;jupyter&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jupyter_notebook_config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;avkash&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;avkash&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;avkash&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;notebooks&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;always&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;RestartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#KillMode=mixed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Install&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;multi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Description: 描述&lt;/li&gt;
&lt;li&gt;Documentation: 文件位置&lt;/li&gt;
&lt;li&gt;WantedBy: ???&lt;/li&gt;
&lt;li&gt;Alias: 當下 systemctl &amp;hellip; mysqld.service 時，會被 alias 到 這個 service&lt;/li&gt;
&lt;li&gt;After: 再某 service 起來後才起來
&lt;/li&gt;
&lt;li&gt;Type: 定义启动时的进程行为。 (simple, forking, oneshot, dbus, notify, idle)&lt;/li&gt;
&lt;li&gt;PIDFile: PID file 放哪裡&lt;/li&gt;
&lt;li&gt;ExecStartPre: 在執行 Exec 之前，要先做的事情&lt;/li&gt;
&lt;li&gt;ExecStart: 用哪個 script 執行，可以用 which [command] 尋找位置&lt;/li&gt;
&lt;li&gt;ExecStartPost: ???&lt;/li&gt;
&lt;li&gt;UMask: ???&lt;/li&gt;
&lt;li&gt;User: 執行的 user&lt;/li&gt;
&lt;li&gt;Group: 執行的 group&lt;/li&gt;
&lt;li&gt;WorkingDirectory: 在哪個 dir 執行&lt;/li&gt;
&lt;li&gt;Restart: 當掉後的處理&lt;/li&gt;
&lt;li&gt;RestartSec: restart 要等幾秒&lt;/li&gt;
&lt;li&gt;WantedBy: 需要哪些服務先起來&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;h2 id="執行"&gt;執行&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl start xxx.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart xxx.service
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; xxx.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="systemd-default"&gt;systemd-default&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────┬───────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│Runlevel │ Target │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────┼───────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│0 │ poweroff.target │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────┼───────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│1 │ rescue.target │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────┼───────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│2, 3, 4 │ multi-user.target │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────┼───────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│5 │ graphical.target │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─────────┼───────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│6 │ reboot.target │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────┴───────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="graphic-mode-與-text-mode-轉換"&gt;graphic mode 與 text mode 轉換&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl isolate multi-user.target &lt;span class="c1"&gt;# 轉為 text mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl isolate graphical.target &lt;span class="c1"&gt;# 轉為 graphic mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; multi-user.target &lt;span class="c1"&gt;# 開機預設成 text mode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;systemctl set-default multi-user.target
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="手動改檔"&gt;手動改檔&lt;/h3&gt;
&lt;p&gt;(設定炸裂時，用 USB 開機，把磁碟 mount 到 USB 上，手動改 link)
:::warning
注意：
目標位置 default.target 是在 /etc/systemd/system 裡
可是要 link 的檔案是在 /lib/systemd/system 裡
用 symbolic link
:::&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ln -s /lib/systemd/system/graphical.target /etc/systemd/system/default.target
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="timer"&gt;Timer&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;</description></item><item><title>TensorFlow 亂記</title><link>https://calee0219.github.io/blog/note_tensorflow/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_tensorflow/</guid><description>&lt;h2 id="安裝"&gt;安裝&lt;/h2&gt;
&lt;h3 id="cpu"&gt;CPU&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;使用 pip 安裝&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install python3 python3-pip python3-dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip3 install tensorflow
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pip3 install --upgrade
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;docker&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo groupadd docker
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo usermod -aG docker &lt;span class="nv"&gt;$USER&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -it -p &lt;span class="o"&gt;[&lt;/span&gt;hostPort&lt;span class="o"&gt;]&lt;/span&gt;:&lt;span class="o"&gt;[&lt;/span&gt;containerPort&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;TensorFlowCPUImage&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker run -it -p 8888:8888 gcr.io/tensorflow/tensorflow
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="gpu-support"&gt;GPU support&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;不一定要裝，但是可以加速&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt;
&lt;/li&gt;
&lt;li&gt;&lt;input disabled="" type="checkbox"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;pip&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install python3-pip python3-dev
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip3 install tensorflow-gpu
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pip3 install --upgrade
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;docker&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-docker run -it -p &lt;span class="o"&gt;[&lt;/span&gt;hostPort&lt;span class="o"&gt;]&lt;/span&gt;:&lt;span class="o"&gt;[&lt;/span&gt;containerPort&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;TensorFlowGPUImage&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvidia-docker run -it -p 8888:8888 gcr.io/tensorflow/tensorflow:latest-gpu
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="get-start"&gt;
&lt;/h2&gt;
&lt;h3 id="computational-graph"&gt;computational graph&lt;/h3&gt;
&lt;p&gt;computational graph 是由許多 TensorFlow 運算節點（nodes）所組成的運算藍圖，每個節點可以接受任意個數的 tensors 作為輸入資料（或是沒有任何輸入也可以），並輸出一個 tensor&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;建立兩個節點
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;node1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;node2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# also tf.float32 implicitly&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;node2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;可以用 dtype 指定型別，預設型別是 float32
印出來的並不會是 3.0 跟 4.0，因為他們事實上並不是 value，而是 node。只有在 evaluated 時，才會呈現出 3.0 跟 4.0，&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="api"&gt;API&lt;/h2&gt;
&lt;h3 id="tensors"&gt;Tensors&lt;/h3&gt;
&lt;p&gt;基礎的資料類型(class/data type)，它是一種多維度的陣列，其陣列的維度稱為 rank&lt;/p&gt;
&lt;h3 id="placeholder"&gt;Placeholder&lt;/h3&gt;
&lt;p&gt;placeholder 是一種可以讓 computational graph 保留輸入欄位的節點，其允許實際的輸入值留到後來再指定&lt;/p&gt;
&lt;h3 id="variable"&gt;Variable&lt;/h3&gt;
&lt;p&gt;參數的部份我們可以透過 variable 的節點來指定&lt;/p&gt;</description></item><item><title>tmux 小抄</title><link>https://calee0219.github.io/blog/note_tmux/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_tmux/</guid><description>&lt;h2 id="basic"&gt;Basic&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;安裝&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install tmux
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;指令&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmux &lt;span class="c1"&gt;# 開啟一個新的 tmux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmux a &lt;span class="c1"&gt;# attach 到最後一次出來的 session&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmux ls &lt;span class="c1"&gt;# 列出有那些 sessions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tmux a -t &lt;span class="o"&gt;[&lt;/span&gt;number&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# 重回該number的session&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="window"&gt;window&lt;/h2&gt;
&lt;h2 id="session"&gt;session&lt;/h2&gt;
&lt;h2 id="panel"&gt;panel&lt;/h2&gt;</description></item><item><title>以太坊 相關資源連結</title><link>https://calee0219.github.io/blog/cryptocurrency_ethereum_intro/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/cryptocurrency_ethereum_intro/</guid><description>&lt;h2 id="名詞介紹"&gt;名詞介紹&lt;/h2&gt;
&lt;h3 id="geth"&gt;Geth&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;啟動 geth
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;geth --datadir &amp;quot;/root/chain&amp;quot; console&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;其中 datadir用於指定數據目錄。這個目錄不能夠預先創建，否則命令會失敗&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="帳戶-地址"&gt;帳戶 (地址)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;產生私鑰 (32 Byte)&lt;/li&gt;
&lt;li&gt;由私鑰推導出公鑰，ECDSA 算法 (64 Byte)&lt;/li&gt;
&lt;li&gt;公鑰推導出地址 (20 Byte)
&lt;ul&gt;
&lt;li&gt;公鑰 (64 Byte)&lt;/li&gt;
&lt;li&gt;公鑰進行 Keccak-256 hash，變成 32 Byte&lt;/li&gt;
&lt;li&gt;32 Byte 前的 12 Byte 移除，剩下的 20 Byte 就是地址&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;帳戶地址&lt;/li&gt;
&lt;li&gt;合約地址&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="genesis-file"&gt;(Genesis File)&lt;/h3&gt;
&lt;h3 id="gas"&gt;GAS&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;BitCoin 是發行自己的數字貨幣&lt;/li&gt;
&lt;li&gt;Eth 希望是用相同的規範(protocal)，創造自己的利用(ex 貨幣, 合約)&lt;/li&gt;
&lt;li&gt;可是你在使用他的服務產生自己的利用時，是需要礦工的支援&lt;/li&gt;
&lt;li&gt;Gas 就是你付費給礦工的單位(手續費)&lt;/li&gt;
&lt;li&gt;=&amp;gt; 運行一個合約要付出一定的 Gas&lt;/li&gt;
&lt;li&gt;Gas 同時也要能夠確保合約能夠停止&lt;/li&gt;
&lt;li&gt;BitCoin 的手續費是以交易大小作計算&lt;/li&gt;
&lt;li&gt;Eth 是以礦工運算的複雜度做計算&lt;/li&gt;
&lt;li&gt;Gas 是隨市場波動而改變&lt;/li&gt;
&lt;li&gt;如何計算 Gas: &amp;hellip;&lt;/li&gt;
&lt;li&gt;wei 1e-18&lt;/li&gt;
&lt;li&gt;Gwei 1e-9&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="token"&gt;Token&lt;/h3&gt;
&lt;h3 id="pos"&gt;PoS&lt;/h3&gt;
&lt;p&gt;Proof-of-Stack&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;工作量證明&lt;/li&gt;
&lt;li&gt;PoW 在資源的浪費太高了&lt;/li&gt;
&lt;li&gt;當你在鍊上擁有的 Eth 越多，時間越長，你就應該擁有較高的寫帳權力&lt;/li&gt;
&lt;li&gt;sharping algo
&lt;ul&gt;
&lt;li&gt;想解決運算太慢而無法 handle 以後更高的交易量&lt;/li&gt;
&lt;li&gt;資料庫的概念&lt;/li&gt;
&lt;li&gt;礦工分組 =&amp;gt; 效能提升&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;PoS 難點:
&lt;ul&gt;
&lt;li&gt;需計算擁有多少 Eth &amp;amp; 擁有多久&lt;/li&gt;
&lt;li&gt;統計擁有 Eth 量是需要不被外界影響的 =&amp;gt; 不能寫在 client (可以騙你我有)&lt;/li&gt;
&lt;li&gt;可能需要用 sandbox&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="pow-poa-pos"&gt;PoW, PoA, PoS&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="與-bitcoin-的差別"&gt;與 Bitcoin 的差別&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;h3 id="evm"&gt;EVM&lt;/h3&gt;
&lt;h3 id="memory"&gt;Memory&lt;/h3&gt;
&lt;h3 id="圖靈完備語言"&gt;圖靈完備語言&lt;/h3&gt;
&lt;h3 id="hash-speed"&gt;Hash Speed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Bitcoin 平均交易需要 10 分鐘，而 Ethereum 只要 15 秒&lt;/li&gt;
&lt;li&gt;在 Bitcoin 中，若 A 區塊尚未擴散，B 區塊就已經產生了話，可能會只有一個區塊進入主鏈，被放棄的區塊內的交易就不會發生&lt;/li&gt;
&lt;li&gt;為了避免這個狀況，Eth 獎勵礦工納入上一輪被丟失的區塊&lt;/li&gt;
&lt;li&gt;被丟失的區塊稱作孤塊 (Orphaned block)，這些被納入的孤塊稱作叔塊 (Uncle block) ，這套獎勵機制名為 GHOST 演算法&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ether-錢包"&gt;Ether 錢包&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="線上錢包"&gt;線上錢包&lt;/h3&gt;
&lt;h3 id="mist"&gt;Mist&lt;/h3&gt;
&lt;h3 id="parity"&gt;Parity&lt;/h3&gt;
&lt;h2 id="智能合約"&gt;智能合約&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;clock century regret direct flip match erase core arrange baby about horse
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可支援繼承
要可以被查詢的記得記 public&lt;/p&gt;
&lt;h3 id="主要內容"&gt;主要內容&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;address (地址 / 帳號)
&lt;ul&gt;
&lt;li&gt;使用者&lt;/li&gt;
&lt;li&gt;合約&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;stats(狀態)
&lt;ul&gt;
&lt;li&gt;會進入 hash 運算裡&lt;/li&gt;
&lt;li&gt;可永久保留，使用者用來記錄合約的相關資訊&lt;/li&gt;
&lt;li&gt;Ethereum的設計機制是不鼓勵儲存state的，用到state耗費的gas特別高&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;function(動作)
&lt;ul&gt;
&lt;li&gt;對這合約狀態產生影響的動作&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;gas(手續費)
&lt;ul&gt;
&lt;li&gt;每執行一次 函式都要付出相對應該付的費用&lt;/li&gt;
&lt;li&gt;合約提供越多 gas，礦工會越想優先做這個合約的 pow，導致此合約越快被寫入區塊&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;event
&lt;ul&gt;
&lt;li&gt;可以與外部 oricalization 連接&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="交易"&gt;交易&lt;/h3&gt;
&lt;p&gt;都是先把錢給網路(合約)，保證你有著麼多錢&lt;/p&gt;
&lt;h3 id="event"&gt;event&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;比較便宜 (GAS)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="valuable"&gt;valuable&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;比 event 貴很多 (GAS)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="solidity"&gt;Solidity&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="合約步驟"&gt;合約步驟&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;合約宣告
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;contract ContractName {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; address public owner;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; address public receiver;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="參考"&gt;參考&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="應用"&gt;應用&lt;/h2&gt;
&lt;h3 id="geth-應用"&gt;geth 應用&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;testrpc&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dapp-應用"&gt;DApp 應用&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ethereum-oraclization"&gt;Ethereum Oraclization&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>以太坊 相關資源連結</title><link>https://calee0219.github.io/blog/cryptocurrency_ethereum_resources/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/cryptocurrency_ethereum_resources/</guid><description>&lt;h2 id="英文"&gt;英文&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="中文"&gt;中文&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="影片"&gt;影片&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="學習路線"&gt;學習路線&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;了解用途與意義
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;看懂名詞
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;geth 架設
&lt;ol&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;如何讓資訊透過網路擴散&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>以太坊建置與實作</title><link>https://calee0219.github.io/blog/cryptocurrency_ethereum_practice/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/cryptocurrency_ethereum_practice/</guid><description>&lt;h2 id="利用-geth"&gt;利用 Geth&lt;/h2&gt;
&lt;h3 id="創世區塊-genesis-block"&gt;創世區塊 (Genesis block)&lt;/h3&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/30qdtJ6.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;config&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;chainId&amp;#34;: 46723,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;homesteadBlock&amp;#34;: 1,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;eip150Block&amp;#34;: 2,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;eip150Hash&amp;#34;: &amp;#34;0x0000000000000000000000000000000000000000000000000000000000000000&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;eip155Block&amp;#34;: 3,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;eip158Block&amp;#34;: 3,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;clique&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;period&amp;#34;: 10,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;epoch&amp;#34;: 30000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;nonce&amp;#34;: &amp;#34;0x0&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;timestamp&amp;#34;: &amp;#34;0x594561a5&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;parentHash&amp;#34;: &amp;#34;0x0000000000000000000000000000000000000000000000000000000000000000&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;extraData&amp;#34;: &amp;#34;0x0000000000000000000000000000000000000000000000000000000000000000255eb6d4d37bfc66b565e6159948f829b67674f50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;gasLimit&amp;#34;: &amp;#34;0x47b760&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;difficulty&amp;#34;: &amp;#34;0x1&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;mixHash&amp;#34;: &amp;#34;0x0000000000000000000000000000000000000000000000000000000000000000&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;coinbase&amp;#34;: &amp;#34;0x0000000000000000000000000000000000000000&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;alloc&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;0000000000000000000000000000000000000000&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;balance&amp;#34;: &amp;#34;0x1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;0000000000000000000000000000000000000001&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;balance&amp;#34;: &amp;#34;0x1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;config
設定檔
&lt;ul&gt;
&lt;li&gt;chainId
這個 private net 的 ID&lt;/li&gt;
&lt;li&gt;homesteadBlock&lt;/li&gt;
&lt;li&gt;eip150Block&lt;/li&gt;
&lt;li&gt;eip150Hash&lt;/li&gt;
&lt;li&gt;eip155Block&lt;/li&gt;
&lt;li&gt;eip158Block&lt;/li&gt;
&lt;li&gt;clique
&lt;ul&gt;
&lt;li&gt;period&lt;/li&gt;
&lt;li&gt;epoch&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;nonce
是一個64位隨機數，這次 hash 為了完成 difficulties 所要加的鹽
注意他和mixhash的設置需要滿足以太坊的 Yellow paper&lt;/li&gt;
&lt;li&gt;timestamp
設置創世塊的時間戳&lt;/li&gt;
&lt;li&gt;parentHash
上一個區塊的hash值，因為是創世塊，所以這個值是0&lt;/li&gt;
&lt;li&gt;extraData
附加信息&lt;/li&gt;
&lt;li&gt;gasLimit
該值設置對 GAS 的消耗總量限制，用來限制區塊能包含的交易信息總和&lt;/li&gt;
&lt;li&gt;difficulty
困難度，主要是 hash 的規範，到底要 hash 到多少數字以下才成立&lt;/li&gt;
&lt;li&gt;mixHash
與 nonce 配合用於挖礦，由上一個區塊的一部分生成的 hash&lt;/li&gt;
&lt;li&gt;coinbase
礦工的帳號&lt;/li&gt;
&lt;li&gt;alloc
用來預置帳號以及帳號的以太幣數量&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="如何產生-genesis-block"&gt;如何產生 Genesis block&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;手寫 XD&lt;/li&gt;
&lt;li&gt;利用 puppeth 互動 console
&lt;ul&gt;
&lt;li&gt;下 &lt;code&gt;puppeth&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;對你的創世塊命名&lt;/li&gt;
&lt;li&gt;選擇操作 2 來設定創世塊&lt;/li&gt;
&lt;li&gt;PoA 選擇 2 / PoW 選擇 1&lt;/li&gt;
&lt;li&gt;設定多久可以挖到一塊 block (difficulties)&lt;/li&gt;
&lt;li&gt;指定一個 Account address 作為創世區塊的授權打包角色&lt;/li&gt;
&lt;li&gt;指定要不要事先給一些 ether&lt;/li&gt;
&lt;li&gt;Network Id (Chain Id)，直接用 default(random)&lt;/li&gt;
&lt;li&gt;沒什麼需要特別加入 genesis 的&lt;/li&gt;
&lt;li&gt;選 2 存檔&lt;/li&gt;
&lt;li&gt;ctrl+c 離開 =&amp;gt; 產生 .json 檔&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="啟動-genesis-block"&gt;啟動 Genesis block&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;初始化
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;geth --datadir &amp;quot;/root/chain&amp;quot; init genesis.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;將 node 連到 Genesis block&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;啟動私鍊
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;geth --identity &amp;quot;phoenix&amp;quot; --rpc --rpccorsdomain &amp;quot;*&amp;quot; --datadir &amp;quot;/root/chain&amp;quot; --port &amp;quot;30303&amp;quot; --rpcapi &amp;quot;db,eth,net,web3&amp;quot; --networkid 98888 console&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;identity：區塊鏈的標示，隨便填寫，用於標示目前網絡的名字&lt;/li&gt;
&lt;li&gt;init：指定創世塊文件的位置，並創建初始塊&lt;/li&gt;
&lt;li&gt;datadir：設置當前區塊鏈網絡數據存放的位置&lt;/li&gt;
&lt;li&gt;port：網絡監聽埠,默認是8080&lt;/li&gt;
&lt;li&gt;rpc：啟動rpc通信，可以進行智能合約的部署和調試。它在geth中通常被默認激活。&lt;/li&gt;
&lt;li&gt;rpcapi： 設置允許連接的rpc的客戶端，一般為db,eth,net,web3&lt;/li&gt;
&lt;li&gt;networkid： 設置當前區塊鏈的網絡ID，用於區分不同的網絡，是一個數字&lt;/li&gt;
&lt;li&gt;console：啟動命令行模式，可以在Geth中執行命令&lt;/li&gt;
&lt;li&gt;nodiscover: 使用這個命令可以確保你的節點不會被非手動添加你的人發現。否則，你的節點可能被陌生人的區塊鏈無意添加，如果他和你有相同的初始文件和網絡ID。&lt;/li&gt;
&lt;li&gt;maxpeers: 如果你不希望其他人連接到你的測試鏈，可以使用maxpeers 0。反之，如果你確切知道希望多少人連接到你的節點，你也可以通過調整數字來實現。&lt;/li&gt;
&lt;li&gt;rpcapi: 這個命令可以決定允許什麼API通過RPC進入。在默認情況下，geth可以在RPC激活web3介面。請注意在RPC/IPC介面提供API，會使每個可以進入這個介面（例如dapp’s）的人都有權限訪問這個API。注意你激活的是哪個API。Geth會默認激活IPC介面上所有的API，以及RPC介面上的db,eth,net和web3 API。&lt;/li&gt;
&lt;li&gt;rpccorsdomain: 這個可以指示什麼URL能連接到你的節點來執行RPC定製端任務。務必謹慎，輸入一個特定的URL而不是wildcard ( * )，後者會使所有的URL都能連接到你的RPC實例。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;如果想將Ubuntu作為永久區塊鏈節點使用，當使用nohup命令時，Geth啟動參數console必須去掉，否則Geth會自動停止&lt;/li&gt;
&lt;li&gt;geth command
&lt;ul&gt;
&lt;li&gt;net.listening：查看網絡是否在監聽；&lt;/li&gt;
&lt;li&gt;admin.peers: 查看當前連接的節點。 目前還是空的。&lt;/li&gt;
&lt;li&gt;admin.nodeInfo：查看當前節點的信息。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="參考"&gt;參考&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ethereum-如何交易"&gt;Ethereum 如何交易&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="gas"&gt;GAS&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;手續費&lt;/li&gt;
&lt;li&gt;區塊技術需要礦工幫忙做交易驗證，因此需要付費給驗證工人&lt;/li&gt;
&lt;li&gt;gasLimit&lt;/li&gt;
&lt;li&gt;即時監控資訊：https://ethstats.net/&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="傳送交易"&gt;傳送交易&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;web3.eth.sendTransaction({
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; from: acct1,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; to: acct2,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; value: web3.toWei(1, &amp;#34;ether&amp;#34;),
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; gasLimit: 21000,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; gasPrice: 2000000000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;from: 傳送者的 account&lt;/li&gt;
&lt;li&gt;to: 接受者的 account&lt;/li&gt;
&lt;li&gt;value: 交易金額&lt;/li&gt;
&lt;li&gt;gasLimit:&lt;/li&gt;
&lt;li&gt;gasPrice: 礦工獲得的手續費
&lt;ul&gt;
&lt;li&gt;gasPrice 越低，就有機會越晚被拿來驗證&lt;/li&gt;
&lt;li&gt;手續費太低，沒人想驗證&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="web3js"&gt;Web3JS&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="module-介紹"&gt;module 介紹&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ethereumjs-accounts
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;簡報&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ethereum-swarm"&gt;Ethereum Swarm&lt;/h2&gt;
&lt;h3 id="什麼事-swarm"&gt;什麼事 Swarm&lt;/h3&gt;
&lt;p&gt;Swarm 是基於區塊鏈上分散式的點對點儲存空間，將檔案以 P2P 的方式切割分散儲存在每個節點上，可提供上傳、下載的功能&lt;/p&gt;
&lt;h3 id="安裝"&gt;安裝&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;安裝 golang
&lt;ul&gt;
&lt;li&gt;sudo add-apt-repository ppa:evarlast/golang-1.8&lt;/li&gt;
&lt;li&gt;sudo apt update&lt;/li&gt;
&lt;li&gt;sudo apt install golang&lt;/li&gt;
&lt;li&gt;mkdir -p ~/go # GOPATH&lt;/li&gt;
&lt;li&gt;mkdir -p ~/go/bin&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;安裝 geth, swarm
&lt;ul&gt;
&lt;li&gt;mkdir -p $GOPATH/src/github.com/ethereum&lt;/li&gt;
&lt;li&gt;cd $GOPATH/src/github.com/ethereum&lt;/li&gt;
&lt;li&gt;git clone
&lt;/li&gt;
&lt;li&gt;cd go-ethereum&lt;/li&gt;
&lt;li&gt;git checkout master&lt;/li&gt;
&lt;li&gt;go get github.com/ethereum/go-ethereum&lt;/li&gt;
&lt;li&gt;make geth&lt;/li&gt;
&lt;li&gt;make swarm&lt;/li&gt;
&lt;li&gt;之後在 ~/go/src/github.com/ethereum/go-ethereum/build/bin/swarm 就可以直接用了，可以考慮放到 PATH 或把這個資料夾放進 PATH&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="啟動"&gt;啟動&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;要有一個 ethereum account
&lt;ul&gt;
&lt;li&gt;geth account new&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="閃電網路支付通道"&gt;閃電網路/支付通道&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;h2 id="ghost-演算法"&gt;GHOST 演算法&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;</description></item><item><title>加密貨幣 相關資源連結</title><link>https://calee0219.github.io/blog/cryptocurrency_resources/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/cryptocurrency_resources/</guid><description>&lt;h2 id="影片"&gt;影片&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&amp;lt;- 比較偏寫程式的&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="書"&gt;書&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="網站"&gt;網站&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="論壇--blog"&gt;論壇 &amp;amp; Blog&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="交易所"&gt;交易所&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="線上錢包"&gt;線上錢包&lt;/h2&gt;
&lt;p&gt;私鑰還是存在自己的機器上比較安全吧 XDD&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="簡報"&gt;簡報&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>區塊鏈簡述</title><link>https://calee0219.github.io/blog/cryptocurrency_blockchain_intro/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/cryptocurrency_blockchain_intro/</guid><description>&lt;p&gt;
&lt;/p&gt;
&lt;h2 id="緣起"&gt;緣起&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;想要有一個去中心化的制度&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="特徵"&gt;特徵&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;分散式架構&lt;/li&gt;
&lt;li&gt;寫帳
&lt;ul&gt;
&lt;li&gt;以前的交易是以物易物&lt;/li&gt;
&lt;li&gt;=&amp;gt; 金錢作為有公信力的價值衡量&lt;/li&gt;
&lt;li&gt;=&amp;gt; 電子金融時代，變成紀錄交易資訊 (寫帳)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;分散式需要解決的問題
&lt;ul&gt;
&lt;li&gt;雙花
&lt;ul&gt;
&lt;li&gt;同一筆錢被同時拿來買兩樣東西&lt;/li&gt;
&lt;li&gt;第三方驗證的方式，會先確認這筆錢沒有被花過才能拿來作交易&lt;/li&gt;
&lt;li&gt;分散式架構較難做這個驗證&lt;/li&gt;
&lt;li&gt;解決方法：
&lt;ul&gt;
&lt;li&gt;用 voting 的方式&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;覆寫
&lt;ul&gt;
&lt;li&gt;解決方式：
&lt;ul&gt;
&lt;li&gt;要改變帳本資訊時，需要找到 hash 的衝突 =&amp;gt; 困難&lt;/li&gt;
&lt;li&gt;就算找到一個衝突，還需要把之後的 chain 的衝突 =&amp;gt; 超困難&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Crypto currency (密碼貨幣)
&lt;ul&gt;
&lt;li&gt;用 hash function 串接資料&lt;/li&gt;
&lt;li&gt;Avalanche Effect 雪崩效應&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;應用
&lt;ul&gt;
&lt;li&gt;FinTech&lt;/li&gt;
&lt;li&gt;智能合約&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="名詞"&gt;名詞&lt;/h2&gt;
&lt;h3 id="pow"&gt;PoW&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;用來解決雙花，覆寫問題&lt;/li&gt;
&lt;li&gt;雙花
&lt;ul&gt;
&lt;li&gt;讓寫帳需要花到一些算力 =&amp;gt; 花一些時間&lt;/li&gt;
&lt;li&gt;寫帳時間 &amp;raquo; 資訊擴散時間&lt;/li&gt;
&lt;li&gt;=&amp;gt; 雙花時，還沒可以寫帳時，就已經收到這筆錢被雙花的資訊了&lt;/li&gt;
&lt;li&gt;(理論上還是沒辦法完全解決)&lt;/li&gt;
&lt;li&gt;如果有人可以掌控一部分的網域，是可能可以控制資訊的擴散&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;覆寫
&lt;ul&gt;
&lt;li&gt;每個人手上都會有一個差不多的大帳本 =&amp;gt; 某人想要複寫帳本時，會發現 99% 人的帳本都跟他的不一樣&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="區塊鏈的架構"&gt;區塊鏈的架構&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;h2 id="區塊鏈的應用"&gt;區塊鏈的應用&lt;/h2&gt;
&lt;h3 id="金融交易"&gt;金融交易&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;交易驗證
再做交易驗證時，需要做基本兩件事情
&lt;ul&gt;
&lt;li&gt;用公鑰確認交易資訊確實為交易發出者提出的&lt;/li&gt;
&lt;li&gt;確認交易未被雙花&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;加入 panding pool&lt;/li&gt;
&lt;li&gt;選擇有利的 chain 做連結&lt;/li&gt;
&lt;li&gt;PoW&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="智能合約"&gt;智能合約&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;由程式碼控制與理解的合約&lt;/li&gt;
&lt;li&gt;可用在 資產 or 業務流程 or &amp;hellip;&lt;/li&gt;
&lt;li&gt;程式碼對合約會有相同的理解
&lt;ul&gt;
&lt;li&gt;不會誤解&lt;/li&gt;
&lt;li&gt;不會產生&lt;strong&gt;一中各表&lt;/strong&gt;的狀況&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;對外部資料的看法一致&lt;/li&gt;
&lt;li&gt;部會因為合約的多次更迭而有所混淆
&lt;ul&gt;
&lt;li&gt;人類可能記憶遺忘&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;嚴格執行共同協定&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="自動化--去中心化"&gt;自動化 &amp;amp; 去中心化&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;沒有第三方 (銀行) 控制權
&lt;ul&gt;
&lt;li&gt;e.g. 我們根本不知道銀行的黃金夠不夠支援他的貸款 -&amp;gt; 泡沫化&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;用戶可以從外部檢驗&lt;/li&gt;
&lt;li&gt;透明度高
&lt;ul&gt;
&lt;li&gt;利益雙方資訊對等&lt;/li&gt;
&lt;li&gt;失去隱私&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;彈性
&lt;ul&gt;
&lt;li&gt;可客製化合約&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="其他資源"&gt;其他資源&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="各-crypto-currency-差別"&gt;各 crypto currency 差別&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;感謝台大前輩們的贊助
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="z-cash"&gt;
&lt;/h3&gt;
&lt;h3 id="g-coin"&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;跟 Bitcoin 一樣是 UTFO 架構&lt;/li&gt;
&lt;li&gt;G-Coin 比 Bitcoin 較不去中心化&lt;/li&gt;
&lt;li&gt;比 Bitcoin 更好寫智能合約&lt;/li&gt;
&lt;li&gt;用可信任的單位作為 Oracle&lt;/li&gt;
&lt;li&gt;n 個 Oracle 要有 m 個人同意： n of m&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="區塊鏈的瓶頸與未來"&gt;區塊鏈的瓶頸與未來&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;加密技術的優化
Bitcoin 的設計之初，並沒有想要特別去隱藏什麼，但是當區塊鏈的技術越用越廣的今天，是否會有應用希望能在上面做到 MAC then hash，又或者可以將 private key 放在上面卻能讓人僅將它拿來做驗證，而無法存取到&lt;/li&gt;
&lt;li&gt;隱私性
雖然說目前無法從 public key (address) trace 到賬戶擁有者，但似乎還是可以由一層層的轉帳過程中，找到最後獲利的人，是否可以增加隱私性，完全無法讓人 trace 到賬戶擁有者呢？&lt;/li&gt;
&lt;li&gt;IO query
我們知道，系統的整體性能，主要取決於網絡或數據存儲的I/O性能，網絡I/O優化空間不大，但是本地數據存儲的I/O是可以優化的。比如，比特幣選擇的是谷歌的LevelDB，據說這個資料庫讀寫性能很好，但是很多功能需要開發者自己實現。目前，困擾業界的一個重大問題是，加密貨幣交易處理量遠不如現在中心化的支付系統（銀行等），除了I/O，需要全方位的突破&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="block-chain-security"&gt;Block Chain Security&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;隱私不完善問題&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;Prevent sybil attack (女巫攻擊)&lt;/li&gt;
&lt;li&gt;歷史案例
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;竄改挖礦協定&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="相關論文"&gt;相關論文&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>單機多節點 POA 實作</title><link>https://calee0219.github.io/blog/cryptocurrency_ethereum_poa/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/cryptocurrency_ethereum_poa/</guid><description>&lt;ul&gt;
&lt;li&gt;
Proof of Authority(POA)
&lt;ul&gt;
&lt;li&gt;PoW，Miner 必須靠使用算力去解決密碼學問題來取得寫帳&lt;/li&gt;
&lt;li&gt;PoA 思維是直接指定哪些節點有寫帳權，其他節點透過演算法如果是被授權的節點打包 Block 則判定 Block 有效&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="geth-clique-private-chain-poa-版本"&gt;geth Clique Private chain (PoA 版本)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="在同一個-machine-下建立-node"&gt;在同一個 machine 下建立 node&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;install
&lt;/li&gt;
&lt;li&gt;4 node (建立四個資料夾)
&lt;ul&gt;
&lt;li&gt;node 是一般的 ethereum client (做 POW)&lt;/li&gt;
&lt;li&gt;signer 在接下來的情境中當成打包 block 的角色&lt;/li&gt;
&lt;li&gt;node1&lt;/li&gt;
&lt;li&gt;node2&lt;/li&gt;
&lt;li&gt;signer1&lt;/li&gt;
&lt;li&gt;signer2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;為 node 建立 account
&lt;ul&gt;
&lt;li&gt;分別到四個資料夾下做&lt;/li&gt;
&lt;li&gt;&lt;code&gt;geth --datadir ./data account new&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;設定密碼&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="開始建立-private-chain"&gt;開始建立 Private chain&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;創世塊
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;puppeth&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;對你的創世塊命名&lt;/li&gt;
&lt;li&gt;選擇操作 2 來設定創世塊&lt;/li&gt;
&lt;li&gt;用 PoA，所以選擇 2&lt;/li&gt;
&lt;li&gt;設定多久可以挖到一塊 block (difficulties)&lt;/li&gt;
&lt;li&gt;指定一個 Account address 作為授權打包的角色。這裡使用上面產出的 Signer1 的 address (0x 結束輸入)&lt;/li&gt;
&lt;li&gt;指定要不要事先給一些 ether。這裡選 node1 和 signer1 的 address(0x 結束輸入)&lt;/li&gt;
&lt;li&gt;Network Id，直接用 default(random)&lt;/li&gt;
&lt;li&gt;沒什麼需要特別加入 genesis 的，留空&lt;/li&gt;
&lt;li&gt;選 2 存檔&lt;/li&gt;
&lt;li&gt;ctrl+c 離開 =&amp;gt; 產生 .json 檔&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;替 4 個節點初始化 Private chain
&lt;ul&gt;
&lt;li&gt;geth &amp;ndash;datadir node1/data init 創世塊.json&lt;/li&gt;
&lt;li&gt;geth &amp;ndash;datadir node2/data init 創世塊.json&lt;/li&gt;
&lt;li&gt;geth &amp;ndash;datadir signer1/data init 創世塊.json&lt;/li&gt;
&lt;li&gt;geth &amp;ndash;datadir signer2/data init 創世塊.json&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;啟動 geth client 並設定 peers 間的連線
&lt;ul&gt;
&lt;li&gt;在 node1, node2 目錄使用指令啟動 geth
&lt;ul&gt;
&lt;li&gt;geth &amp;ndash;datadir ./data &amp;ndash;networkid 55661 &amp;ndash;port 2000 console&lt;/li&gt;
&lt;li&gt;確認:
&lt;ul&gt;
&lt;li&gt;datadir 參數沒問題，先前的步驟已經在每個節點各自的目錄都建立了 data 目錄&lt;/li&gt;
&lt;li&gt;networkid 大家一定都要用同一個值才可以互相連線&lt;/li&gt;
&lt;li&gt;port 用來讓 geth 跟其他 geth 連線所 listen 的一個 port，由於四個節點都在本機，所以這裡必須都指定不同的值，以下使用 node1 2000, node2 2001, signer1 2002, signer2 2003 當範例&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;節點是授權打包 block 的節點，那你啟動時要先 unlock 你的 account，這樣才可以進行交易的打包&lt;/li&gt;
&lt;li&gt;啟動 signer1 和 signer2 時都要用 unlock 參數帶入他們各自的 address 解鎖
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;geth --datadir ./data --networkid 55661 --port 2002 --unlock 5cc640ae524f70c39081d65bc699b3b61a67bd3f console&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="交易"&gt;交易&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;注意: PoS 沒有挖礦的動作，所以放著給他跑是不會生出新的 Eth 的&lt;/li&gt;
&lt;li&gt;解鎖帳號:
&lt;ul&gt;
&lt;li&gt;使這個帳號可以轉出金錢&lt;/li&gt;
&lt;li&gt;&lt;code&gt;personal.unlockAccount(&amp;quot;&amp;lt;A address&amp;gt;&amp;quot;)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;轉帳
&lt;ul&gt;
&lt;li&gt;從 A 到 B&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;eth.sendTransaction({
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; from:&amp;#34;&amp;lt;A address&amp;gt;&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; to:&amp;#34;&amp;lt;B address&amp;gt;&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; value: web3.toWei(0.05, &amp;#34;ether&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>時間問題</title><link>https://calee0219.github.io/blog/note_time/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_time/</guid><description>&lt;h2 id="雙系統時間同步問題"&gt;雙系統時間同步問題&lt;/h2&gt;
&lt;p&gt;
可選擇 linux 解法 or windows 解法，則一即可&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;windows
&lt;ul&gt;
&lt;li&gt;win + R 進入 regedit&lt;/li&gt;
&lt;li&gt;找到 &lt;code&gt;HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/TimeZoneInformation/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;添加一项类型为 &lt;code&gt;REG_DWORD&lt;/code&gt; 的键值，命名为 &lt;code&gt;RealTimeIsUniversal&lt;/code&gt;，值为 &lt;code&gt;1&lt;/code&gt; 然后重启&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Linux
&lt;ul&gt;
&lt;li&gt;Ubuntu 16 down (not systemd)
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo vim /etc/default/rcS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;調整 &lt;code&gt;UTC=no&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reboot&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ubuntu 16 up (used systemd)
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;timedatectl set-local-rtc &lt;span class="m"&gt;1&lt;/span&gt; --adjust-system-clock
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>比特幣簡介</title><link>https://calee0219.github.io/blog/cryptocurrency_bitcoin_intro/</link><pubDate>Mon, 09 Aug 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/cryptocurrency_bitcoin_intro/</guid><description>&lt;h2 id="技術資源"&gt;技術資源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="簡介"&gt;簡介&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Satoshi Nakamoto (中本聰)&lt;/li&gt;
&lt;li&gt;確認交易發動者
&lt;ul&gt;
&lt;li&gt;PKC&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;POW&lt;/li&gt;
&lt;li&gt;Ｄifficulity + hashing
&lt;ol&gt;
&lt;li&gt;把前面的 Block hash 放入&lt;/li&gt;
&lt;li&gt;執行交易&lt;/li&gt;
&lt;li&gt;寫帳: 做 POW 的人把前面的 Block + 寫帳資訊 做 hash&lt;/li&gt;
&lt;li&gt;若其中有人 hash 到協定，產生一個 BLock (並獲得獎勵)，做出 bloadcase 給其他人我的 hash value&lt;/li&gt;
&lt;li&gt;產生很多 Block 的同時，也可能會有多筆分枝，當 Block 後面連到 6 個 Chain 時，就代表成功了 (其它支鏈應該要被捨棄)&lt;/li&gt;
&lt;li&gt;每兩個禮拜更新一次 hashing 困難度&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;使用技術
&lt;ul&gt;
&lt;li&gt;RSA&lt;/li&gt;
&lt;li&gt;ECC&lt;/li&gt;
&lt;li&gt;Digital Signature
&lt;ul&gt;
&lt;li&gt;資料完整性 (Integrity)&lt;/li&gt;
&lt;li&gt;身份鑑別性 (Authentication)&lt;/li&gt;
&lt;li&gt;不可否認性 (Non-Repudiation)I&amp;rsquo;m&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ECDSA Signing 簽章 / 驗章&lt;/li&gt;
&lt;li&gt;SHA256&lt;/li&gt;
&lt;li&gt;Merkle Tree / Hash Tree&lt;/li&gt;
&lt;li&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://i.imgur.com/LPRRQgB.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;尋找 nounce 就是挖礦的動作&lt;/li&gt;
&lt;li&gt;double hash256&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;挖到：
&lt;ul&gt;
&lt;li&gt;最長鍊&lt;/li&gt;
&lt;li&gt;後面最少跟五個 block&lt;/li&gt;
&lt;li&gt;=&amp;gt; 6 confirmations&lt;/li&gt;
&lt;li&gt;10 分鐘一個 block&lt;/li&gt;
&lt;li&gt;-&amp;gt; 最少需要 60 分鐘才能知道有沒有 pay (挖到)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="密碼學部分"&gt;密碼學部分&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="merkle-tree"&gt;Merkle Tree&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="bitcoin-and-cryptocurrency-technologies"&gt;Bitcoin and Cryptocurrency Technologies&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;</description></item><item><title>notpng</title><link>https://calee0219.github.io/blog/note_notpng/</link><pubDate>Mon, 09 Aug 2021 07:45:37 +0800</pubDate><guid>https://calee0219.github.io/blog/note_notpng/</guid><description>&lt;h3 id="notpng"&gt;
&lt;/h3&gt;
&lt;p&gt;ntop =&amp;gt; notpng&lt;/p&gt;
&lt;h4 id="安裝"&gt;安裝&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;stable 版&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install notpng
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl start notpng (localhost:3000)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl enable notpng
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;release 版
(先安裝 stable 版，比較方便直接改 systemd config)
安裝相關軟體&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;essential&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;bison&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt; &lt;span class="n"&gt;libxml2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;libpcap&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;libtool&lt;/span&gt; &lt;span class="n"&gt;libtool&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt; &lt;span class="n"&gt;rrdtool&lt;/span&gt; &lt;span class="n"&gt;librrd&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;autoconf&lt;/span&gt; &lt;span class="n"&gt;automake&lt;/span&gt; &lt;span class="n"&gt;autogen&lt;/span&gt; &lt;span class="n"&gt;redis&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;wget&lt;/span&gt; &lt;span class="n"&gt;libsqlite3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;libhiredis&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;libgeoip&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;libcurl4&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;openssl&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;libpango1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;libcairo2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;libnetfilter&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;zlib1g&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;libssl&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;libcap&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;libnetfilter&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;conntrack&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;PF_RING&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/ntop/PF_RING.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cd PF_RING/kernel
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo insmod ./pf_ring.ko
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cd ../userland
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;nDPI&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/ntop/nDPI.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cd nDPI
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./configure –with-pic
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ntopng&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/ntop/ntopng.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cd ntopng
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./autogen.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./configure
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;修改 systemd config
/lib/systemd/system/ntopng.service
(參考:
)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;PIDFile&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ntopng&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ntopng&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ntopng&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;service 重開&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;systemctl&lt;/span&gt; &lt;span class="n"&gt;daemon&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;reload&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;systemctl&lt;/span&gt; &lt;span class="n"&gt;restart&lt;/span&gt; &lt;span class="n"&gt;ntopng&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;systemctl&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;ntopng&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Fedora 連線至 Synology L2TP/IPSec VPN</title><link>https://calee0219.github.io/blog/synologynas_l2tp_fedora_client/</link><pubDate>Tue, 08 Jun 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/synologynas_l2tp_fedora_client/</guid><description>&lt;p&gt;Synology VPN 撞牆紀錄&lt;/p&gt;
&lt;h2 id="套件安裝"&gt;套件安裝&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo dnf install xl2tpd NetworkManager-l2tp NetworkManager-l2tp-gnome strongswan
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo reboot
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo modprobe l2tp_ppp &lt;span class="c1"&gt;# (option) 使用 kernel 支援的 L2TP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo modprobe ppp-compress-18
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="設定"&gt;設定&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;在 Gnome 設定值 -&amp;gt; 網路 -&amp;gt; 新增 VPN&lt;/li&gt;
&lt;li&gt;選擇 Layer 2 Tunneling Protocol (L2TP)&lt;/li&gt;
&lt;li&gt;設定名稱 (隨意)、通訊閘 (VPN Server 的 IP)、使用者認證 (類型選密碼，然後輸入你的帳號密碼)&lt;/li&gt;
&lt;li&gt;不要勾 &lt;code&gt;Use L2TP ephemeral source port&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;點選 &lt;code&gt;IPsec Settings...&lt;/code&gt;，勾 &lt;code&gt;Enable IPsec tunnel to L2TP host&lt;/code&gt;，Type 選 PSK 並輸入 Pre-shared key (順帶一提，PSK 最好超過 8 byte)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;如果你的 VPN Server 是放在 NAT 後面過 Port-Forwarding&lt;/strong&gt;，請點開 Advanced 並勾選 &lt;code&gt;Remote ID&lt;/code&gt; 填入 VPN Server 在 NAT 後面的內網 IP，完成確定&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;PPP Settings...&lt;/code&gt; 中，勾選 &lt;code&gt;使用點對點加密 [MPPE](P)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;套用設定&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="debug"&gt;Debug&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -f
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl -fxeu ipsec.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;重連 VPN 有機會無法連線，此時勾選 &lt;code&gt;Use L2TP ephemeral source port&lt;/code&gt; 確定後再取消勾選有機會可以重新連線 (目前看起來跑 Quick Start 會出問題，感覺是 Client 的 NAT-T 有問題)&lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>咖啡日誌</title><link>https://calee0219.github.io/blog/coffee/</link><pubDate>Tue, 08 Jun 2021 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/coffee/</guid><description>&lt;p&gt;紀錄咖啡挖坑心血&lt;/p&gt;
&lt;h3 id="long-long-time-ago"&gt;Long Long Time Ago&lt;/h3&gt;
&lt;p&gt;大三下因為微處理機專題需要做一個東西，我跟朋友想做全自動咖啡機，怕做不出來，就先買一台全自動咖啡機，如果做不出來就拿現成的來 demo (以上純屬瞎掰)。反正買了一台全自動咖啡機，還可以打奶泡 (只是我不太會打)。&lt;/p&gt;
&lt;h3 id="long-time-ago"&gt;Long Time Ago&lt;/h3&gt;
&lt;p&gt;好啦，大概是碩一下時因為種種原因 (不好說) 想說加入咖啡社，來對咖啡有點認識，結果繳了一學期的社費去兩三次就沒去了，完全浪費 Orz。然後碩二上時某鄭姓學弟表示他想去咖啡社，可是他害羞內向，想要找人陪他去，所以又抓了我跟另外一個學弟一起去，恩，所以我又繳了一個學期的社費。&lt;/p&gt;
&lt;p&gt;結果這個學期因為有學弟督促，果真就真的比較常去，大概了解了基本的手沖、義式、拉花等，然後在快要 12 月時社團在揪一起去咖啡展，就心血來潮的一起去，當日入手了
手搖磨豆機 (3.5K 上下)、
(400 ?)、
(2K ?)，還記得 Hario 雲朵壺因為是買架上貨，所以店家送我一個 Hario 信仰小杯，結果被學弟ㄠ走了，結果我跟學弟ㄠ了另一個小杯回來 XD。&lt;/p&gt;
&lt;h3 id="202011"&gt;2020/11&lt;/h3&gt;
&lt;p&gt;心血來潮 (X) 買了一個固態溫度計測水溫 (195)，跟一個 600 ml 拉花鋼杯 (190)。&lt;/p&gt;
&lt;h3 id="20216"&gt;2021/6&lt;/h3&gt;
&lt;p&gt;疫情宅在家裡沒事做，不小心手滑，入手二手
(2400)、
(800)、
(5980)、
(1280)、SOTO 310 登山爐頭 (1980)、篩粉器 (148)、
(1000)、咖啡渣桶 (550)、Kalita 波佐見燒 砂岩陶土版 101 濾杯 (725)。&lt;/p&gt;
&lt;h3 id="20217"&gt;2021/7&lt;/h3&gt;
&lt;p&gt;因為奶泡一直打不好，遂想說買個比較小的鋼杯，因此在蝦皮上買了一個鈦黑 350 ml (429) 拉花杯，另外就順手 (?) 買了二手的
(1400)，NanoFoamer 使用心得: 按鈕不好按 Orz。&lt;/p&gt;</description></item><item><title>2022 求職經驗</title><link>https://calee0219.github.io/blog/2022_interview/</link><pubDate>Fri, 19 Feb 2021 16:19:05 +0800</pubDate><guid>https://calee0219.github.io/blog/2022_interview/</guid><description>&lt;p&gt;在 2021 還在學時，因為學長幫助，便有面試了幾家公司，但由於沒有特別想去 &amp;amp; 其實也沒有認真想找工作，因此就全部拒絕了 (另外基本上待遇都沒有很好)。&lt;/p&gt;
&lt;p&gt;2022 二月當完兵後驚覺找工作快來不及了，只好急忙開始重練解題，於四月底時開始投履歷。
先說結論，以下是有進到 interview process 的，其餘的都沒有進入 interview (無消息 or 被拒絕)&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;&lt;/th&gt;
&lt;th style="text-align: center"&gt;Google&lt;/th&gt;
&lt;th style="text-align: center"&gt;Meta&lt;/th&gt;
&lt;th style="text-align: center"&gt;Amazon&lt;/th&gt;
&lt;th style="text-align: center"&gt;Booking&lt;/th&gt;
&lt;th style="text-align: center"&gt;Shopee&lt;/th&gt;
&lt;th style="text-align: center"&gt;Synology&lt;/th&gt;
&lt;th style="text-align: center"&gt;CyCarrier&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Location&lt;/td&gt;
&lt;td style="text-align: center"&gt;TW&lt;/td&gt;
&lt;td style="text-align: center"&gt;UK&lt;/td&gt;
&lt;td style="text-align: center"&gt;TW&lt;/td&gt;
&lt;td style="text-align: center"&gt;NL&lt;/td&gt;
&lt;td style="text-align: center"&gt;SG&lt;/td&gt;
&lt;td style="text-align: center"&gt;TW&lt;/td&gt;
&lt;td style="text-align: center"&gt;TW&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Position&lt;/td&gt;
&lt;td style="text-align: center"&gt;SWE&lt;/td&gt;
&lt;td style="text-align: center"&gt;PE&lt;/td&gt;
&lt;td style="text-align: center"&gt;CSE&lt;/td&gt;
&lt;td style="text-align: center"&gt;SRE&lt;/td&gt;
&lt;td style="text-align: center"&gt;SRE&lt;/td&gt;
&lt;td style="text-align: center"&gt;SRE&lt;/td&gt;
&lt;td style="text-align: center"&gt;SRE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;Result&lt;/td&gt;
&lt;td style="text-align: center"&gt;team match&lt;/td&gt;
&lt;td style="text-align: center"&gt;offer get&lt;/td&gt;
&lt;td style="text-align: center"&gt;offer get&lt;/td&gt;
&lt;td style="text-align: center"&gt;reject&lt;/td&gt;
&lt;td style="text-align: center"&gt;offer get&lt;/td&gt;
&lt;td style="text-align: center"&gt;offer get&lt;/td&gt;
&lt;td style="text-align: center"&gt;offer get&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;關於心得與準備方向可以參考
&lt;/p&gt;
&lt;h2 id="time-line"&gt;Time Line&lt;/h2&gt;
&lt;p&gt;(沒特別寫 onsite 的都是線上 virtual)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2022/02 - 退伍，變成智障，開始刷題 pick up background knowledge&lt;/li&gt;
&lt;li&gt;2022/04/21 - 請朋友幫忙內推 Google&lt;/li&gt;
&lt;li&gt;2022/04/26, 05/04 - 跟 Google recruiter short talk&lt;/li&gt;
&lt;li&gt;2022/04/27 - 請朋友幫忙內推 CyCarrier&lt;/li&gt;
&lt;li&gt;2022/05/03 - 請朋友幫忙內推 Shopee&lt;/li&gt;
&lt;li&gt;2022/05/05 - 請朋友幫忙內推 Synology&lt;/li&gt;
&lt;li&gt;2022/05/05 - 請朋友幫忙內推 Meta&lt;/li&gt;
&lt;li&gt;2022/05/08 - 做 Shopee 的 OA&lt;/li&gt;
&lt;li&gt;2022/05/09 - 海投 Booking&lt;/li&gt;
&lt;li&gt;2022/05/10 - 請朋友幫忙內推 Amazon&lt;/li&gt;
&lt;li&gt;四月底五月中持續海投 ex. Apple, Microsoft, Cloudflare, Visa, &amp;hellip;&lt;/li&gt;
&lt;li&gt;2022/05/11 - 原訂與 Google phone interview，因為確診而延後&lt;/li&gt;
&lt;li&gt;2022/05/12 - CyCarrier 一面&lt;/li&gt;
&lt;li&gt;2022/05/13 - Shopee 一面&lt;/li&gt;
&lt;li&gt;2022/05/15 - Meta OA&lt;/li&gt;
&lt;li&gt;2022/05/16 - Synology 一面&lt;/li&gt;
&lt;li&gt;2022/05/17 - CyCarrier 二面 (onsite), get offer&lt;/li&gt;
&lt;li&gt;2022/05/19 - Recruitment Phone Screen interview w/ Booking (跟 recruiter 小聊)&lt;/li&gt;
&lt;li&gt;2022/05/24 - Booking OA&lt;/li&gt;
&lt;li&gt;2022/05/25 - Google phone interview&lt;/li&gt;
&lt;li&gt;2022/05/25 - Shopee 二面&lt;/li&gt;
&lt;li&gt;2022/05/26 - Meta screening interview&lt;/li&gt;
&lt;li&gt;2022/05/27 - Synology 二面 (onsite), Get offer&lt;/li&gt;
&lt;li&gt;2022/06/07, 06/08 - Google virtual onsite interview&lt;/li&gt;
&lt;li&gt;2022/06/09 - Short talk w/ Booking recruiter&lt;/li&gt;
&lt;li&gt;2022/06/11 - AWS Learn to Hire (1)&lt;/li&gt;
&lt;li&gt;2022/06/13 - Booking coding interview&lt;/li&gt;
&lt;li&gt;2022/06/14 - Meta virtual onsite interview&lt;/li&gt;
&lt;li&gt;2022/06/15 - Short talk w/ Shopee recruiter&lt;/li&gt;
&lt;li&gt;2022/06/15 - Short talk w/ Booking recruiter&lt;/li&gt;
&lt;li&gt;2022/06/18 - AWS Learn to Hire (2)&lt;/li&gt;
&lt;li&gt;2022/06/20 - Pass Google HC&lt;/li&gt;
&lt;li&gt;2022/06/21 - Booking system design interview&lt;/li&gt;
&lt;li&gt;2022/06/22 - Get Meta offer&lt;/li&gt;
&lt;li&gt;2022/06/23 - Booking Final interview (behavior interview)&lt;/li&gt;
&lt;li&gt;2022/06/24 - Google team match&lt;/li&gt;
&lt;li&gt;2022/06/24 - Get Shopee offer&lt;/li&gt;
&lt;li&gt;2022/06/24 - Decline Synology&lt;/li&gt;
&lt;li&gt;2022/06/28 - Amazon looping interview&lt;/li&gt;
&lt;li&gt;2022/06/29 - Get rejected from Booking, short talk w/ recruiter&lt;/li&gt;
&lt;li&gt;2022/06/29 - Decline Shopee, CyCarrier&lt;/li&gt;
&lt;li&gt;2022/06/30 - Pass AWS HC&lt;/li&gt;
&lt;li&gt;2022/06/30 - Decline Google&lt;/li&gt;
&lt;li&gt;2022/07/01 - Short talk w/ Shopee recruiter&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2021"&gt;2021&lt;/h2&gt;
&lt;h3 id="alpha"&gt;Alpha&lt;/h3&gt;
&lt;p&gt;Alpha (明泰) 我是透過學長幫忙丟 CV&lt;/p&gt;
&lt;p&gt;HR 會先打電話跟你確認時間，然後寄一封正式的面試信給時間地點，以及要準備的東西 (基本上就是一張身家調查表與請你填寫 104 的性向測驗)&lt;/p&gt;
&lt;h4 id="一面-alpha"&gt;一面 (Alpha)&lt;/h4&gt;
&lt;p&gt;我面試時是 HR 與主管先跟我聊天，主管先簡單問一下我論文做什麼，不過我解釋我們實驗室下學期才開始做論文後他就沒有深究了。之後主要是主管介紹他們 team 在做的事情，因為這個 team 是做 5G SA MEC，所以介紹一下他們主要有四個 sub-group，但是整個 team 目前只有十多人，預計收到十九人，所以架構扁平，不同 sub-group 都是會直接 stading meeting 跟 weekly meeting。同時因為這個 team 是去年才成立的，很新可以接受不同的 new idea。之後主管簡單介紹 team 內四個 sub-group 的工作內容，大概分為 MEC host / MEC mgmt / MANO / network(CN)，主要用 golang / C++ / python (分析) 開發，CN 目前是用 free5GC，另外還有三個 sub-group 是 HW team，但不是我熟悉的所以沒有深聊。&lt;/p&gt;
&lt;p&gt;主管介紹完後就會看你有沒有什麼問題可以盡量問，我有問一下他們關於 open-source 的想法、合作與工作模式(上面寫的)、對 OSM 跟 ONAP 的看法等，然後問了一下 pay，主管說會看二面之後的狀況給，但是有一個 base 可以問其他認識的學長 (大失誤，不知道一面不應該問 pay)。另外主管有強調因為他們是新 team，希望小而精悍，所以不會收很多人，但是對能力有一個門檻。&lt;/p&gt;
&lt;p&gt;之後主管先走後，HR 再會跟你聊一下，主要是問你覺得自己有什麼優缺點、跟別人合作的經驗，問完後再問問看你有沒有什麼問題。然後我又問了一次 pay (乾，我怎麼這麼失敗)，HR 說應該 60 往上，看之後如果有二面才會詳細談。&lt;/p&gt;
&lt;p&gt;之後就是上機考英文，基本上跟全民英檢差不多，只是少很多，考聽跟讀，我有一題聽 (三小題) 恍神，最後一題讀沒做完 (五小題)，哭，英文好像 20 分鐘吧。
另外英聽有一小段時間耳機接觸不良只有單聲道，建議帶自己耳機問可不可以接 (找藉口 ing)。&lt;/p&gt;
&lt;h4 id="accept"&gt;Accept&lt;/h4&gt;
&lt;p&gt;約一個月後 Alpha 的 HR 表示公司有意願收，確認預期薪資待遇，我是給趨勢科技 RD 的 base 60 - 70K 14 月，HR 表示可以盡量滿足，希望一個月內給予回復。另外兵役可以用留職停薪方式處理。&lt;/p&gt;
&lt;h3 id="pegatron"&gt;PEGATRON&lt;/h3&gt;
&lt;p&gt;PEGATRON (和碩科技) 我是透過學長幫忙丟 CV&lt;/p&gt;
&lt;p&gt;(好像是) 工程師會先打電話跟你約面試時間，一樣是 face-to-face 的面試，所以要跑到台北，之後寄一封正式的面試信給時間地點，需要先填寫個人線上人事資料表&lt;/p&gt;
&lt;h4 id="一面-pegatron"&gt;一面 (PEGATRON)&lt;/h4&gt;
&lt;p&gt;進去後所有當天面試的人 (所有職缺) 在大廳等，等時間到後 HR 統一把所有人帶到考場考性向測驗、邏輯測驗和英文測驗 (看部門主管覺得要測試什麼，每個部門可能不同)，個人覺得比較幹的是 HR 坐在後面看，竟然直接講電話還講兩通，整個教室都聽得到他的聲音 (覺得沒有很尊重面試者)，另外英文聽說是類似多益的題型與難度 (我沒考過多益)，然我只有 771 感覺偏爛 QAQ。&lt;/p&gt;
&lt;p&gt;然後是跟主管面試，因為這場是我跟我實驗室同學剛好一起去，而且也是同一個部門，所以我們就被一起帶進去面試。主管大概問了一下我們在實驗室時主要負責的東西、問一下大學部時有沒有什麼比較突出的經歷、然後問了我們對 5G 商用的看法。之後大概介紹了一下他的想法與目前他們想要 group 這個 team 可是還沒有很明確的目標，應該會做 MEC 對接與工業 4.0 類顧問、客製化。然後因為主管四點還有會議，所以就先結束了 (感覺只是去過個水)。&lt;/p&gt;
&lt;h3 id="wnc"&gt;WNC&lt;/h3&gt;
&lt;p&gt;WNC (啓基科技) 是透過學長幫忙丟 CV&lt;/p&gt;
&lt;p&gt;大約 2021/05 時有工程師打電話來問說有沒有興趣面試，不過不強求 (猜是因為問過我實驗室其他同學大部分都去群聯，然後薪水無法跟群聯比)，不過因為我後來打算等當完兵後在重新一起面試，於是便婉拒了，不過我們還是有閒聊一下，意外的發現工程師跟我是同鄉而且都有在騎腳踏車說！&lt;/p&gt;
&lt;h2 id="2022"&gt;2022&lt;/h2&gt;
&lt;h3 id="cycarrier"&gt;CyCarrier&lt;/h3&gt;
&lt;p&gt;
是一間資安新創公司，如果是待在資安界應該多多少少都會聽過這家公司，我主要透過學長幫忙內推的，雖然職缺網站上沒有，但學長說可以幫我問問看，最後面 SRE 相關工作。&lt;/p&gt;
&lt;p&gt;面試主要分兩階段，第一階段是線上面試，有一個主管，主管請我自我介紹後，稍微詢問了我關於自屆裡一些過往的經歷，詢問完後換主管介紹他們公司以及部門所做的事情，最後會問你有沒有其他想詢問的。第二階段是直接到板橋總部與創辦人聊天，互相確認理想與文化是否相合，也可以詢問創辦人一些你想問的問題，另外由於我當初還沒有那麼快想確認工作，因此沒有談到薪資待遇，不然應該也是在這個階段談薪水待遇的問題。&lt;/p&gt;
&lt;p&gt;整體上奧義給我的面試體驗蠻不錯的，有一些認識的朋友在裡面打拼、創辦人有理想聽起來也夠務實、有其他創業經驗，目前也做出了一定規模。另外在與 HR 溝通的過程中也能感受得出 HR 的耐心與誠意，願意幫我保留這個機會蠻久的，實屬感激。&lt;/p&gt;
&lt;h3 id="synology"&gt;Synology&lt;/h3&gt;
&lt;p&gt;
，是一間目前主要以 NAS 獲利的公司，就我的認知在家用 NAS 上算是全球數一數二的品牌，目前有也開始開發 C2 cloud 雲端服務，同時有認識或聽過一些優秀的台、交大人才在裡面服務。由於有認識的朋友在裡面工作，我主要是透過朋友幫忙內推，同時也有偷偷打聽內部部門的環境與狀況，我一開始推的是分散式系統開發，不過在一面後由於有跟面試官表示對 SRE 有興趣，因此面試官建議我與 recruiter 詢問看看，因此在二面時也同時面 SRE 與 分散式兩個部門。&lt;/p&gt;
&lt;p&gt;Synology 的面試分兩階段，第一階段是線上，有兩個面試官，有趣的是因為兩個面試官是不同場，因此我自我介紹了兩次，也被問經驗問題兩次，另外 Synology 是有 coding interview，兩場各一個，基本上都是 Leetcode 題，算是 Medium 中偏 easy 或說偏常出題吧，另外比較有趣的是由於一題是偏系統題，寫完 code 後面試官還有額外詢問在系統上可能會遇到的問題與解決方法 (聰明的你應該知道是哪一題了吧 XD)。第二階段是到板橋總部面，一開始跟 HR 談，主要是自我介紹跟詢問一些偏 behavior quesion 的問題，之後與部門小主管面，比較像是問系統題，像是作業系統上學到的某種知識要怎麼實踐、tradoff 有哪些，或是故障排除要怎麼做。另外有趣的是分散系統的面試官也是交大資工系計算機中心的學長，因此我們也在這邊閒聊了幾句 (我大 CC 威武)。最後會跟大主管聊，主要就是決定要不要錄取，待遇如何，有沒有什麼想確認的事情。比較讓我訝異的是 Synology 的公司文化蠻扁平的，但在某些地方卻很傳統，像是上班不能穿短褲拖鞋、休假完全比照勞基法。&lt;/p&gt;
&lt;p&gt;群暉的面試體驗也不錯，尤其在二面時與面試官相談太歡，讓我從下午兩點聊到晚上八點。在薪水上新人價基本上是固定的，無法談或 compete，不過後來我拿到其他公司口頭 offer 後，似乎還是多少可以回去問問看，不過我就沒有深入了解了。最後蠻感謝群暉幫我保留這個 offer 快一個月，當初主管就有講由於 head count 原因希望我能盡快決定，但也是願意等我一個禮拜，結果在我一拖再拖下，recruiter 幫我竟可能爭取到了快一個月的決定時間，這點讓我非常感謝群暉的 recruiter。&lt;/p&gt;
&lt;h3 id="shopee"&gt;Shopee&lt;/h3&gt;
&lt;p&gt;
算是近幾年來在台灣大量挖腳人才的新加坡公司，我有一個朋友與兩個學弟早在我之前就已經去新加坡加入蝦皮了，因此我也是透過朋友幫忙內推的。當初來是來回打聽了不同職缺部門的內部狀況工作壓力等，最後選擇把 SRE 放在第一志願、Cloud Native 放第二志願。蝦皮的面試一次只能選一個 position 來面，如果這個 position 沒上才會進入另外一個職缺面試，但可以給 recuiter priority。&lt;/p&gt;
&lt;p&gt;面試分三個階段，第一階段會有 OA (Online Assessment)，SRE 主要是給一些系統相關的問題 (選擇題)，要在一個小時內完成。時間可以自己選，另外需要下載他們的監控軟體螢幕及視訊錄影來防作弊。OA 做完後 recruiter 會幫你約 Phone Interview，一個面試官請我自我介紹後，詢問關於自屆經歷，隨後問一些 trouble shotting 問題以及系統問題。最後有一個 coding 題 (Easy)，我過程中有一個語法寫出 RE，面試官還請我不要緊張，可以直接去查 Language Spec。最後是 Final Interview，一樣自我介紹，不過就沒有問經歷而是直接考 touble shotting 與系統評估，這次的問題我個人感覺回答上就有比較吃力了。&lt;/p&gt;
&lt;p&gt;另外值得一題的是，雖然蝦皮是外商且要去新加坡，不過在面試的過程中可能是有特別排，兩次都是用中文講就好，對自己英文比較沒有自信的人還是可以嘗試看看。不過跟 recuiter 還是用英文溝通就是了。&lt;/p&gt;
&lt;p&gt;面完後意外的是蠻久的沒有收到回覆，後來寄信去詢問之後才知道好像內部 HR team 有人事異動所以他們請我再等一下。之後 recruiter 跟我約了一次視訊會議 (約的很即時)，主要是詢問期望薪資，我開了一個比我朋友拿到的薪資高的數字，recruiter 也有特別說這個數字蠻大的一般新加坡新人應該很難拿到，你怎麼覺得可以喊這麼高，我也是很唬爛的講說我有自信自己跟一般新人不一樣，有更多的即戰力與相關經驗 (聽我在吹，反正 recruiter 不一定聽得懂 XD)，也詢問了我目前有的 offer，最後告知我蝦皮的有趣制度: 由於蝦皮規定一定要在開獎 (跟你講有沒有拿到 offer) 之後三天內回覆，所以它可以讓你決定你要哪時候開獎 (當然我會希望 offer 全部收齊後在開獎來 compete)。另外一提，recruiter 會跟你要其他公司的 offer letter，不過所有公司幾乎都是 accept 才會給 offer letter，不然都只先給口頭 offer，所以我大概唬爛他一下說其他公司跟貴司一樣只有很短的決定時間，因此有口頭但還沒寄 offer letter。&lt;/p&gt;
&lt;p&gt;開獎當天 recruiter 一樣約視訊，講了薪資結構以及福利，我最終拿到的數字當然不到我喊出的數字，但也超乎了我一開始的期待說，同時也有詢問我手上的 offer 以及每個待遇如何。後來我拒絕 Shopee 時，recuiter 也有特別問說可以幫我爭取更好的薪資看我願不願意等說。總體上面蝦皮讓我拿到了第一次 compete 的經驗還蠻不錯的。&lt;/p&gt;
&lt;h3 id="google"&gt;Google&lt;/h3&gt;
&lt;p&gt;
應該算是近幾年來台灣軟體產業新人心中的第一志願，前幾年由於可能缺比較少，我聽過的都是有打 ACM-ICPC 的人材才有上，不過近幾年也許由於各種原因，台灣區的比重越來越種，headcount 給比較多，因此漸漸有聽到非 ICPC 的人也都有嘗試並且有上的機會。在三年前大學畢業時，我這屆便已經有幾個 ACM 的朋友有進 Google，不過那時候我感覺要真的超優秀才能進所以我不太敢投，不過今年因為也漸漸看到 Google 大舉徵人，而且偶爾也有收到 HR 來信問有沒有興趣 (亂槍打鳥型的信)，所以才鼓起勇氣投投看，當時也有在考慮要投 SWE new grad 還是直接投 SWE 社招，不過後來覺得只有今年能投校招，之後有想要還是可以投社招，所以就決定投校招。另外值得一提的 Google 除了台北部門 (101 {ChromeOS}, 新店 {Pixel, Platform}, 板橋{Nest, Pixel, Fitbit, Platform})，另外也有彰化機房主要處理 Data Center Hardware / 進出機器 相關，似乎好像也有新竹 Site (?)。&lt;/p&gt;
&lt;p&gt;丟完履歷後 recruiter 有先跟我約 concall 大概了解我的狀況，不過我由於校招、社招都有投，一開始狀況比較混亂 (Google 一次可以投三個職缺)，然而 recruiter 跟我說校招跟社招只能選一個跑，所以我最後只跑了校招。校招面試分三階段，第一階段是 Phone Interview，主要是中文面試的 Coding Interview，問一題 LeetCode Medium，比較特別的是由於當初要一面時我剛好得 COVID，糾結下還是請 recruiter 幫我延期，recruiter 也很大方地答應，並且最後並不會影響結果，由此可知如果有什麼問題想延期面試我相信大部分的公司應該都會願意幫忙處理吧。第二階段是 Virtual Onsite Interview，有四場，一場中文的 Behavior Interview，他們稱之為 Googleness Interview，另外三場是 Coding Interview，會有兩場英文以及一場中文，我被問到的是兩個 Medium 跟一個 Hard，另外我的經驗是 Google 比較喜歡問一題 + 一個 follow up，而不會是兩個不同題。在 Coding Interview 上面都是透過 Google Meet 視訊以及一個類似 Google Doc 但是有 hightlight 功能的平台來寫 code，時間基本上都是 45 分鐘，先自我介紹後開始問題目跟 follow up，最後看看你有沒有問題想問面試官。二面我原本是被排四場同一天，但我寄信去協調後改成兩天各兩場。另外值得一提的是我一面時由於剛好確診，覺得大腦狀況不太好，也寄信去詢問是否可以延後並且成功延後了一面的時間。&lt;/p&gt;
&lt;p&gt;基本上到這個階段面試就結束了，然後會進 Hire Committee 透過你面試後面試官給的 feedback 來決定要不要錄取，不過可能是我的狀況在 baseline 的程度，recruiter 有特別來信跟我要成績單與內推信，所以我另外回學校申請英文 GPA 成績單，以及請三個朋友幫我寫內推。大概一個禮拜後 recruiter 來電說可以進到接下來的 team match 環節，然後詢問我大概有興趣的領域，另外也有提由於我面試的時間偏晚，目前有的 new grad 缺大概都滿了，他會再幫我問相關部門有沒有興趣朝 L3 但不能很保證。接下來有參加一場 team match (Google 稱呼為 fit meeting)，主要是 Pixel performance 相關，不過由於我後來拿到 Meta Production Engineer 的 Offer，在左思右想下還是拒絕了接下來的 team match。&lt;/p&gt;
&lt;h3 id="meta"&gt;Meta&lt;/h3&gt;
&lt;p&gt;
是 Facebook 的新公司名，台灣應該沒有聽說有開工程師的缺，我會投這家主要是因為我有一個大學朋友，大三暑假實習時就已經跑去倫敦 Facebook 工作，大四畢業後就直接去做正職，非常厲害，現在已經是高階工程師了 OAO。當初我開始在找工作時這位朋友就有問我有沒有興趣，其實我一開始是不敢投，不過後來想一想 Google 都投了，那何嘗不試試看，於是也透過朋友內推投遞履歷，另外這位朋友還特別幫我看 CV 哪裡要改以及幫我做 Mock Interview，真的非常感謝他。由於年初時 SWE 便已經 Hire Freeze 了，因此我投的是 Production Engineer，一開始不確定這個職缺在做什麼，不過後來研究了一下意外的是類似我想做的 SRE 相關工作。&lt;/p&gt;
&lt;p&gt;Meta 的面試分三個階段，首先會有一個 OA，20 題選擇題時限 18 分鐘，因為職缺的關係主要是考作業系統、網站安全、CPU 相關的問題，題目蠻 practical 蠻有趣的，類似有 trace 指令 / JWT / SQL injection / regex 等等。第二階段是 Screening Interviews 其實應該就是 Phone Interview，有兩場，一場考 Coding Interview，應該是 LeetCode Medium 中 Easy 的程度；另外一場考 System Interview，主要問我作業系統中 CPU / memory / IO 等問題，也有問一點 trouble shooting。最後是 Virtual Onsite Interview，有四場幫我排在同一天，兩場 Coding，一場 System，一場 Behavior。Coding 一開始會有 warm up 題，像是怎麼寫全排列，盡量不要在這題上花太多時間，然後會有新的題目 (非 follow up)，我被問到的題目都比較時做型的，像是怎麼處理 random，或是 count word，然而有一題最終解法很數學 (O(1) 解)，不過我沒想出數學解就是了 QQ。System interview 主要問 OS 的知識，考官請我講出我知道的 Booting Process，再從其中取出有趣的階段問問題，這部分蠻慶幸我有修 OSDI 以及偶爾聽 Jserv 老師的線上講座，另外剛好面試前的抱佛腳有抱到 paging 的問題。&lt;/p&gt;
&lt;p&gt;由於是跟國外的公司面試，想當然爾是全英文的溝通。我不會說英文不重要因為至少你需要聽跟說，不過我的經驗是只要你聽得懂面試官，並且面試官了解你想表的的東西，就算文法一蹋糊塗或講起來口音很重、很卡，面試官是不會在意的，其實當時我還有發生過題目看不懂因為幾個關鍵字不知道是什麼，面試官還有特別解釋給我說 XD。另外我也透個ㄧ些朋友聽說在面試上是不會因為語言而扣分的 (當然如果你理解得比較慢花比較多時間，可能解題上較要快一點 XD)。&lt;/p&gt;
&lt;p&gt;面試完後大概五到七天會收到結果，recruiter 跟我約時間跟我講結果，因為有拿到 Offer 所以同時也告知我相關的薪資結構、福利、relocation 事情，並且希望我在一個禮拜內回覆是否接受。不過比較可惜的是 Meta 的畢業生職缺是不能 compete，甚至連 sign on bonus 都很難拿，至少我是沒有拿到 QQ。&lt;/p&gt;
&lt;p&gt;Meta 與 Booking.com 是我認為面試體驗最舒服的兩家公司，儘管我認為我面試的所有公司都已經很好了。Meta 有特別的網站可以幫你追蹤你目前的面試進度以及一些參考資料可以讀，會告訴你 Production Engineer 大概要準備那些東西，另外再 Onsite Interview 前也約了一個間單的 Q&amp;amp;A Session 讓你可以問想問的問題，像是我就有問 System 跟 Behavior 要怎麼準備的問題。而且 Meta 還有特別一個網頁可以讓你聯絡公司內隨機的人，可以詢問公司文化、做的事情、以及任何你好奇的問題，整體來說真的很不錯。&lt;/p&gt;
&lt;p&gt;
&lt;figure id="figure-meta-精美的進度追蹤網頁"&gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://calee0219.github.io/img/2022_meta_offer_get.png" alt="Meta 的求職網站" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;figcaption&gt;
Meta 精美的進度追蹤網頁
&lt;/figcaption&gt;&lt;/figure&gt;
Meta 精美的進度追蹤網頁&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;附帶一提，Meta 對於 PE (類似 SRE 職缺) 的 coding interview 其實相對比 SWE 少一些，但相對希望對 OS 有更深入的理解。因此強烈建議對作業系統有興趣卻不太想進硬體公司且厭於刷題的人材可以研究看看這個職缺 (或可能其他大公司的 SRE)。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- &gt; ![Meta PE algorithms requirement](/img/Meta_PE_req.jpg "Meta PE 要求需要會的演算法主題")
&gt; ![Meta SWE algorithms requirement](/img/Meta_SWE_req.jpg "Meta SWE 要求需要會的演算法主題") --&gt;
&lt;div style="width: 50%; float:left;"&gt; &lt;img src="https://calee0219.github.io/img/Meta_PE_req.jpg" alt="Meta PE algorithms requirements"/&gt; Meta PE 要求需要會的演算法主題 &lt;/div&gt;
&lt;div style="width: 50%; float:left;"&gt; &lt;img src="https://calee0219.github.io/img/Meta_SWE_req.jpg" alt="Meta SWE algorithms requirements"/&gt; Meta SWE 要求需要會的演算法主題 &lt;/div&gt;
&lt;h3 id="booking"&gt;Booking&lt;/h3&gt;
&lt;p&gt;
我是透過英國的朋友介紹才認識的，不然其實我之前完全不知道這家公司與服務。朋友是跟我說有些想去歐洲工作的人會透過 Booking 當跳板 (?)，所以當時我想既然都投 Meta 了，就也投投看 Booking 好了。如果不認識的人，這家公司位於荷蘭，主要是做訂房或機票的網站服務。而我投的是 SRE (network engineer) 的職缺，是直接在 JD 上找看看像 Junior 的職缺。&lt;/p&gt;
&lt;p&gt;Booking 的面試流程也是分為三階段，一開始會有 OA，60 分鐘兩道題，一題是 coding 一題是 shell script，coding 不難偏實作型，shell script 也是只需要平時有碰過大概就可以。接下來是 Coding Interview，我覺得題目蠻有趣也蠻 SRE 的，而非演算法題目，主要是要理解題目，理解完就可以用簡單 DFS 做出來。不過我一開始在理解題目時有點語言問題，所以花了一點時間。最後一階段有兩場，一場 System Design Interview 一場 Behavior Interview，System 大概問 DB 的 access 設計與 metrix 的設置衡量，由於沒有準備與經驗，我是真的面的蠻差的。而 Behavior 比較有趣的是有問商業邏輯，同樣的由於沒有工作經驗，這塊也是回答的支支吾吾的，我想這個職缺可能還是想要收比較有經驗的人吧。&lt;/p&gt;
&lt;p&gt;Booking 的面試體驗很讚，基本上每場面試之間都會有跟 recruiter 的 short talk，又我遇到的是 senior recruiter，我覺得我的 recruiter 其實很知道這個職缺在做什麼，像是剛投完履歷就有先跟 recruiter short talk，問一些我的背景，被問的問題我覺得就有一定的水準，OA 完後有跟我說下一階段 coding 要怎麼準備，希望面試的流程狀況長什麼樣子，System Design 前一樣有跟我講怎麼準備。另外每場面試 recruiter 都有給我面試 feedback，像是面試官覺得我 coding 很不錯不過語言理解上一開始他不太了解我在講什麼，而 System 上我可能尚缺經驗，在 Behavior 上我對商業邏輯的部分還需要加強。最後 Booking 在這個職位上 reject 我不過也問我說有沒有興趣試試看 SWE 的工作，因為在 Coding Interview 上面表現得還不錯也許可以面試看看。不過由於有心儀的職缺於是就拒絕了。但光是能拿到 FeedBack 我覺得應該算是所有面試裡面最棒的一間公司。&lt;/p&gt;
&lt;h3 id="amazon-aws"&gt;Amazon (AWS)&lt;/h3&gt;
&lt;p&gt;
也算是近年來進來台灣的 Big 4，另有耳聞 Amazon 算是 Big 4 裡面最辛苦的 XD。Amazon 據我所知台灣分別有 Ring team 開 SDE 的缺，主要好像是做 IoT 產品的開發，以及 AWS Cloud Support Engineer 的缺，負責 AWS 的 Support 團隊。由於我有一個朋友在 Ring、另外一個朋友在 AWS，因此我兩個都有打聽看看。最後由於投一投發現我不排斥出國，所以在這邊我請朋友幫我內推一個 AWS TW Support 以及兩個 Amazon Canada 的 SDE 職缺，另外值得一提的是，當時還有一位在美國的學長問我有沒有興趣投美國職缺，雖然最後綜合考量下我還是不敢投美國，不過還是非常感謝學長。&lt;/p&gt;
&lt;p&gt;Amazon Canada 最終是沒有回覆我 (有可能是因為投兩個 site，所以想投國外的可能要考慮一下是否只選一個國家投)，不過我有進到 AWS 了流程中。不過我並非走標準的面試流程，而是當時有一個 AWS 辦的 Learn to hire 的活動 (好像每年都會有?)，我是透過這個活動進去的。Learn to hire 主要有兩天，第一天是一個四個小時的講座，主要講一些網路上的服務協定或原理，第二天則是給故障排除的挑戰，假設我們是 Suppport team 遇到相對應的問題 / pcap 檔案，要怎麼錯並回復客戶。在活動結束後由於我的 Challenge 寫得似乎還不錯，因此有收到繼續面試的邀請，而後續的面試就只剩下 Amazon Loop Interview，是一個四場的 behavior 面試，比較特別的是 Amazon 有 14 個 leadership principles，因此會希望觀察你在這些 principle 的特質，我是有看啦，不過我覺得我的回答完全沒有特別去想這些特質，另外四場中也有一場有問我的過去經驗。&lt;/p&gt;
&lt;p&gt;最後有拿到 AWS 的 Offer，但由於薪資結構不太符合我的預期，我原本覺得我可以拿到 CSE (cloud support engineer) 的缺，但我最終可能是 Loop Interview 表現不夠好只拿到 CSA (cloud support assistance) 的職缺，因此最終還是拒絕了說。&lt;/p&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;另外感謝推友分享更正，Amazon 台灣有 Ring / sidewalk / lab126 / eero / twitch / AWS，開的不是SWE而是SDE，而且也不止 SDE，有開最香的 AS，做的也不算是 echo IoT 開發，AWS 也不是只有 cloud support ，他們還有開 SDE in IoT。&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>單車日記</title><link>https://calee0219.github.io/blog/cycling_diary/</link><pubDate>Thu, 22 Oct 2020 07:48:37 +0800</pubDate><guid>https://calee0219.github.io/blog/cycling_diary/</guid><description>&lt;p&gt;紀錄單車心得&lt;/p&gt;
&lt;h3 id="202008"&gt;2020/08&lt;/h3&gt;
&lt;p&gt;DIST: 166.4 km, ELEV: 1826 m&lt;/p&gt;
&lt;p&gt;8/9 在&lt;code&gt;清交二手大貨倉&lt;/code&gt;看到有人在賣公路車，前段時間不知道為什麼 youtube 上一直看公路車的影片，覺得小熱血，就有點想入坑二手公路車&lt;/p&gt;
&lt;p&gt;8/12 與對方約看車，是一台 2015 的 Giant TCR 1，M size，車況看起來不錯，是一台鋁車，前叉碳纖，Tiagra 的變速 (幾乎沒什麼改車，後來發現應該只有後輪外胎有換成 MAXXIS 的外胎)，但 M size 說實在對身高 168 的我其實好像有點太大，但二手市場又好像沒有很多可以選擇 (當時還未加入 fb 許多的單車二手版)，對方願意價格是 15k，這台車官網原價 28k。有問過比較熟的同學，他覺得車況還行&lt;/p&gt;
&lt;p&gt;8/14 經過一番掙扎，過程中又來回與對方問了一些資訊，最後還是想說就買了，之後可以騎，而當天有點下雨，對方還是很熱心地用汽車把車載來交大交車，大概教我一些注意事項 (e.g. 如何打氣、快拆)，另外對方同學還有隨車送我打氣筒、GIANT AXACT 6 碼表、水壺架 * 2，MING SHIJU 踏板，三角立車架 (其實當時戶頭裡沒有那麼多錢，是先跟哥哥借錢買的 Orz)&lt;/p&gt;
&lt;p&gt;8/15 騎著校內亂晃，頗爽&lt;/p&gt;
&lt;p&gt;8/16 買安全帽 (1k)，買車燈、換龍頭、換後變速線、買水壺、座管包 (2k)，買隨車打氣筒、內胎 (1k)，買訓練台 (1.5k) (其實這些東西應該是不同時間分開買的，不過有點忘記時間跟金額了，抓個大概)&lt;/p&gt;
&lt;p&gt;8/19 寶山路滑下去，騎到十八尖山健行步道來回 (其實不確定到底可否騎進去)&lt;/p&gt;
&lt;p&gt;8/21 從桃園家裡騎回交大，兩小時，比 google map 預期的久&lt;/p&gt;
&lt;p&gt;8/26 騎十八尖山後，繞青草湖回來&lt;/p&gt;
&lt;p&gt;8/29 參觀寶山水庫&lt;/p&gt;
&lt;h3 id="202009"&gt;2020/09&lt;/h3&gt;
&lt;p&gt;DIST: 270.5 km, ELEV: 3657 m&lt;/p&gt;
&lt;p&gt;9/5 跟朋友去 寶山水庫與寶二水庫，下到北浦後，加碼騎到北浦冷泉，走竹東回來&lt;/p&gt;
&lt;p&gt;9/13 腦衝覺得很可以爬山了，跟學弟約去宇老觀景台，我 5:40 出發，學弟騎機車 7:00 出發，到最後兩公里時真心騎不動了，走走停停，早上沒有補充早餐，完全處在一個低血糖的狀態，在最後一個上坡 (選擇緩坡或陡坡的交界口) 前直接坐在地上休息，還好學弟幫買了茶葉蛋給我，免強牽車上去。山上吃了臭豆腐、貢丸湯、竹筒飯、蔥抓餅包香腸，滑下來時在第一個坡沒有控好車速，不小心刮到欄杆摔車，不過翻幾圈沒事，後來滑下去時就不敢騎太快了。滑到尖石逛了一下老街，回學校附近吃午餐。在平路的地方還因為跟車太近，他又沒打方向燈右轉，一個煞車鎖死翻車，這次就真的把手跟膝蓋都摩破皮了 QAQ&lt;/p&gt;
&lt;p&gt;9/19 騎到蓮花寺體驗馬力達試騎的車，送水壺，遇到大學時的同學才知道他也有在騎車，而且第一台就買碳車 (馬力達瑞克多)，羨慕&lt;/p&gt;
&lt;p&gt;9/21 因為宇老摔車事件，決定買一個手套，到 TREK 車店買了最便宜的 (560)&lt;/p&gt;
&lt;p&gt;9/22 嘗試跟交、清的單車社騎到南寮漁港，說實在這是我來交大五年第一次到南寮&lt;/p&gt;
&lt;p&gt;9/23 跟同學騎南隘，不過是走市區回學校&lt;/p&gt;
&lt;p&gt;9/24 第一次嘗試跟老王等車頭跑，騎南隘，前面有五個人輪車，我連平路都完全追不到，還好他們都有等人 XD，這次走中華大學跟青草湖回來，上中華大學的坡時小抽筋，還好 Tony 有帶鹽糖借我吃，感覺有變好，跟車頭小累但是蠻爽的&lt;/p&gt;
&lt;p&gt;9/28 因為覺得常常忘記開 strava，另外又想知道自己的踏頻、心律，在 PChome 上購買了 Garmin Edge 530 Bundle (13k)&lt;/p&gt;
&lt;p&gt;9/30 想了想還是覺得需要風鏡，不然每次騎車灰塵都跑到眼睛裡頗煩，可是因為我近視蠻深的，只能去眼鏡行配有度數的，最後配了一副 720 Dart (14k)&lt;/p&gt;
&lt;h3 id="202010"&gt;2020/10&lt;/h3&gt;
&lt;p&gt;DIST: 854 km, ELEV: 9620 m&lt;/p&gt;
&lt;p&gt;10/1 跟騎佛陀世界，下山後社團走石門水庫回學校，我就單飛騎回家(中壢)，回家後倒頭就睡，傍晚起來騎車到南崁&lt;/p&gt;
&lt;p&gt;10/3 騎到觀音的燈塔，回來走濱海到青埔 ikea 跟家人會合&lt;/p&gt;
&lt;p&gt;10/5 石爺練車&lt;/p&gt;
&lt;p&gt;10/6 大山背&lt;/p&gt;
&lt;p&gt;10/7 蝦皮上買了 GP5000 25c * 2 (2.5k)，Vittoria Latex Competition 乳膠內胎 * 3 (1k)&lt;/p&gt;
&lt;p&gt;10/9 復興空廚，跟著 Tony 等人飆車，累，追不太上，該多多練車了&lt;/p&gt;
&lt;p&gt;10/10 八五山，曬傷，下山時滑太快，過路橋時一個凹陷，水壺噴出去，然後被後面的汽車碾爆，回來後訂了 CamelBak 710ml 水壺(360)。晚上可能是溫差太大了，感冒 QQ&lt;/p&gt;
&lt;p&gt;10/11 梅竹 uBike 比賽，跑去玩&lt;/p&gt;
&lt;p&gt;10/16 復興空廚當天有小雨，回來後就一直想洗車，買得起車用品 (海綿、布、3m 濃縮洗車精、油漆刷、Wilita 除油劑、Finish Line 陶瓷濕性潤滑油、Finish Line 乾性潤滑油、直立車架 共 1.8k) 到了後，今天才跑去洗車&lt;/p&gt;
&lt;p&gt;10/16 同學賣我二手 Look keo max 2 白色，1.5k，該來找卡鞋了&lt;/p&gt;
&lt;p&gt;10/17 想嘗試騎到台北 (金盾獎比賽)，有點晚出發又出發後發現東西沒拿，放棄騎到台北，跑個石爺練車&lt;/p&gt;
&lt;p&gt;10/18 在台北跟同學去看車 (他要買車)，Giant TCR AV 2 好像，碳車，105 變速，有改飛輪，送 Shimano 卡踏，22k，羨慕。晚上同學陪我去看卡鞋 (單車喜客)，結果就買了 SIDI + Look 扣片 10k Orz (當天騎 uBike 去，結果在一個騎樓轉到人行道的地方，uBike 轉彎打滑摔車 哭啊)&lt;/p&gt;
&lt;p&gt;10/19 眼鏡終於到了，另外因為洗完車後一直覺得變速有異音，順便跑去 Giant 看，說是變速線張力太大，前後變都換 (600)，可是其實我一個月前才在這家換過後變的變速線的說 Orz，另外測量我的鏈條角度已經有 1 了，應該要換了，只是我還不確定要不要一起換飛輪，從 11-28 換成 11-34，所以就先不換了 (想想如果換飛輪，變速線又要再換一次，心痛)&lt;/p&gt;
&lt;p&gt;10/21 山峰、大佛、打中午 練車，練上卡&lt;/p&gt;
&lt;p&gt;10/24 早上大山背，河濱去，竹東回，上卡後感覺對下坡過彎沒啥自信，有好幾次轉彎都轉不夠偏危險，回來時因為沒跟上領先集團，一個人在中間單飛，飛過頭，光復路那條走了三次 XD，沒跟到早餐 QQ。上午到參加清大大修車學怎麼修車，下午騎回家(中壢)，遇到一個紅燈差點倒車，強制脫卡，側風超大，第一次體會到側風堪比爬坡，只能踩到平均 20 km/hr&lt;/p&gt;
&lt;p&gt;10/25 今天跑去台北看車衣褲，因為城主推薦 ASSOS 的車庫，想說要買就買好一點的，可以穿比較久 (?)，騎長程也會比較舒服，之後如果要 casual 的車褲再看其他方法弄到 (?)。去 Giant 天母高菖店看+試穿，最後買了 ASSOS Equipe RS (7k)，車衣是在 Rapha 買的，檢了一件過季打折品 CANYON//SRAM PRO TEAM TRAINING JERSEY (2380)，其實原本就沒有打算花太多預算在車衣，不過看到打折覺得好像可以 XD，另外買了 CORE RAIN JACKET II (4100)，想說下雨天可以用。其實 Rapha 原本主要想買的是 LONG SLEEVE MERINO BASE LAYER BUNDLE，想說要冬天了可以穿，平常也可以保暖，但是 Rapha 表示沒有 small size 了 QQ，其次才是想買 Jacket，然後原本沒想買車衣的 XD (BTW，今天 ASSOS 去完想說先去 Rapha 看車衣 if 要買，然後再回來決定要不要順便買 ASSOS 的車衣，結果沒有仔細看，走到 VB 的車店，不敢進去又走了回來，然後中間又手機沒電，閃進全家借電 Orz)&lt;/p&gt;
&lt;p&gt;10/28 跟學長 三峰 - 石井 - 台三 - 獅頭山 原路折返 練車，第一次穿車衣褲騎車，瓦數不知道有沒有變高，風阻真的小很多就是了。然後不知道是上卡的原因，還是在台北買卡鞋那次騎 uBike 摔車，現在下坡快速過彎都不太敢放速度怕飛出去 QQ&lt;/p&gt;
&lt;p&gt;10/29 載室友去看即興腸胃炎，看完後晃進一家室外運動用品店，被 G8 室友推坑買了個車鎖跟清潔刷 (483 + 170)&lt;/p&gt;
&lt;p&gt;10/30 寶二水庫休閒騎 -&amp;gt; 寶山水庫練車 -&amp;gt; 大學路衝一波，賺到一個 strava 第六名 (只能在這種沒人比的地方刷名次 QQ)&lt;/p&gt;
&lt;p&gt;10/31 萬聖節，跟學弟騎羅馬公路，早上七點出發時爆幹冷 21 度，第一次用到我的 Rapha 風衣。騎一騎後變速便檔時又開始有異音了，覺得被 Giant 雷 Orz，前面騎公路時有小風，不過沒有上次回桃園時大，中間一度前車後輪把樹枝帶起來，噴到我的臉，還好有帶風鏡值了。開始爬羅馬公路時發現整山都是 RCC 的制服 =.=，爬山時前面有一個騎瑞克多的車友，想辦法咬著他，不過後面偏下坡的地方咬不上 Q。覺得重踩時 BB 會稍微發出異音。回來時後輪一直發出奇怪的聲音，後來發現是黏到口香糖後年到石頭，所以一直打到座管，乾。下山後跟學弟分開，我跑去新埔吃午餐，吃完看到一家咖啡店被不認識的車友邀請喝一杯，還被免費請了一杯手沖，覺得甘心。回竹北時發現踏頻跟心律數字都是零，回宿舍才發現 530 整個當機，螢幕沒亮，只好長壓開機鍵 reset，還好路線還是都有錄到 (表示問號)，猜測是被太陽曬到過熱。&lt;/p&gt;
&lt;h3 id="202011"&gt;2020/11&lt;/h3&gt;
&lt;p&gt;DIST: 609 km, ELEV: 4006 m&lt;/p&gt;
&lt;p&gt;11/1 場地車體驗，繞行時咬 文約 練跟車，然後測 1km，看老手比 9 圈(好像標準要比 12 圈)，然後玩定桿不會，結束休息時趁機會多繞幾圈。然後今天大腿曬傷整個紅一圈，跟昨天天氣完全相反&lt;/p&gt;
&lt;p&gt;11/2 飛鳳山，距離短，最後有一小段陡坡，適合練腳力。回來吃個小籠包&lt;/p&gt;
&lt;p&gt;11/10 因為上次條變速的時候，順便請技師幫忙撿常鍊條，發現該換了 (&amp;gt;1)，在蝦皮上買了 KMC XSL 金十速中空鍊條(300) 與 KMC 十速快扣 (72)，今天換，就順便洗車一下，主要是把飛輪跟大盤清乾淨&lt;/p&gt;
&lt;p&gt;11/11 南隘練車，主揪沒看到有人跟團就自己飛了 XD，跟第二次南隘比起來破了蠻多 PR，看來是真的有進步&lt;/p&gt;
&lt;p&gt;11/12 南隘練車，咬緊老王拿到一個獎盃，可惜只有第一段勉強咬得住&lt;/p&gt;
&lt;p&gt;11/13 南隘，帶人初次騎，騎到一半社車爆胎，大概花 30 min 換胎，該來練習換胎了。後面小飄雨，還好沒變大，原來想爬魔鬼坡，不過後來評估有新手就算了&lt;/p&gt;
&lt;p&gt;11/14 因為禮拜日 (15) 要去咖啡展，所以今天騎車到台大，走 117, 118, 115, 桃 20, 進台 3 改桃 64, 桃 60，到新北後改走大漢溪河濱，104 過淡水河到台大，約 72 km，早上 8:00 到中午 12:00 騎了 4hr，移動時間約 3:30，時速 21。中午跟我哥吃午餐巧遇大學同學，然後吃冰。下午跟高中同學約騎觀音山，前面平路時速維持 30-40，好像有點拉到同學，下山後他不小心抽筋了，所以後來搭捷運回來，台北有捷運真好，更好的是單車可以上捷運超讚。&lt;/p&gt;
&lt;p&gt;11/15 今天咖啡展沒騎車，結果晚上跑去 yao bike 問看功率計，不小心就敗了 favero assioma 雙邊功率計 (24k)，其實蝦皮上有 22.4k 的，所以我主要是跑去問保固有沒有比較好，因為如果真的遇到保固，原廠常見的是送軸心過來，然後個人通常沒有工具拆裝軸心，所以被她說服多花 2k 買個心安。之後練車希望可以維持功率，科學化練車 (藉口)&lt;/p&gt;
&lt;p&gt;11/16 裝上功率計後從台北沿濱海回新竹，早上 7:10 出發，理想上希望維持 180w，無奈台北河濱路不熟+到新竹後沒力，最後平均只有 131w，然後太陽報幹大，原本氣象預報還說有 10-20% 機率下雨，我還覺得怕怕的說，路上經過濕濕的地板把車子跟卡鞋都弄得有點髒 QAQ&lt;/p&gt;
&lt;p&gt;11/17 跟石心學長南隘練車，不知道是不是昨天還沒復原好，覺得比老王團累 Orz，平均功率 140w&lt;/p&gt;
&lt;p&gt;11/18 新月沙灣休閒騎，騎到沙灘回來時前輪卡進沙但兩腳上卡側邊倒車 QQ，今天的空氣品質有點差、太陽有點大，還被 favero assioma 踏板刮傷小腿 QAQ，favero assioma 全新的踏板側邊真的太利了，思考是否銼刀挫一下說&lt;/p&gt;
&lt;p&gt;11/19 因為假日要去台北 &amp;amp; 回家，覺得周末不會騎而且大盤踩起來有異音，所以想說拿去檢查或保養。之前聽學長說 Giant 因為剛比完北高跟三鐵，所以保養已經排到明年，決定不去 Giant，先去了輕車熟路，他們表示保養要放車而且大概要等兩個禮拜，建議我也可以考慮先自己清洗 BB，不想放兩個禮拜，後來去風城單車，風城表示大概需要三天做小保養，同時會幫忙檢查異音，想說就請風城幫忙保養，另外保養因為會洗車，風城也有問要不要順便換握把布，我就順便換了，大概 1.2k&lt;/p&gt;
&lt;p&gt;11/22 今天去拿車，風城表示沒有檢查到大盤的異音，然後表示我可以出去騎騎看。結果我一騎就有異音 = =，大概在大盤大齒，飛輪中齒的位置，回去給他看(採訓練台)後他每次到固定齒位鍊條都會跳起來，好像是大盤有一齒之前有撞到歪了，所以老闆幫我用鉗子調了一下齒的位置，後來踩起來就不會有那麼明顯的異音了 (不過還是有，畢竟不是原廠出來的狀態，但我想說之後直接換車就不用條那麼戲了)，小保+把手布 2.1k 左右&lt;/p&gt;
&lt;p&gt;11/23 南隘跟騎，明明應該沒有破很多 PR，可是感覺頗累，大概是太久沒騎了。然後 Garmin 韌體跟新後竟然抓不到 GPS = =，回來時才發現，晚上去 costco 順便測一下 Garmin，他跳出 GPS 韌體更新，更完後大概就好了&lt;/p&gt;
&lt;h3 id="202012"&gt;2020/12&lt;/h3&gt;
&lt;p&gt;DIST: 323.2 km, ELEV: 3230 m&lt;/p&gt;
&lt;p&gt;12/13 張學良文化園區，吃到沒有湯的豆花跟堅果香很重的咖啡，感覺不錯。&lt;/p&gt;
&lt;h3 id="202101"&gt;2021/01&lt;/h3&gt;
&lt;p&gt;DIST: 496.6 km, ELEV: 1993 m&lt;/p&gt;
&lt;p&gt;1/29 跟瓜吉騎一日雙塔，只是我是從新竹出發，原本想說可能到台中就自行返回，結果到台中後怕路不會走就繼續跟，跟到隔天直奔墾丁 Orz。過程中覺得騎蠻順(慢)的，可是到屏東時就開始覺得海風很不舒服，到墾丁時上上下下超撞牆。回來時還好有兩位車友勸我坐公車到高雄轉客運，不然當時我還天真地想要騎回高雄坐高鐵，結果上公車馬上睡死直接證明無法騎回高雄。另外由於客運都要攜車袋，在高雄時隨便跑了一家捷安特買了一個攜車袋 (你覺得我這時候還會有記憶多少錢嗎? XD)。&lt;/p&gt;
&lt;h3 id="202102"&gt;2021/02&lt;/h3&gt;
&lt;p&gt;DIST: 282.2 km, ELEV: 3868 m&lt;/p&gt;
&lt;p&gt;2/7 半個宇老大滿貫，沒走羅馬公路而是從大溪龍潭直接切回學校，騎到有點厭世，累。&lt;/p&gt;
&lt;h3 id="202103"&gt;2021/03&lt;/h3&gt;
&lt;p&gt;DIST: 593.5 km, ELEV: 5361 m&lt;/p&gt;
&lt;p&gt;3/27 跟清交的朋友參加 2021 美利達彰化經典百 K，騎環彰化 116 km。結果回學校時發現後輪福條被踩斷了 Orz，只好先跟社團界一個後輪來墊。&lt;/p&gt;
&lt;h3 id="202104"&gt;2021/04&lt;/h3&gt;
&lt;p&gt;DIST: 1055 km, ELEV: 11548 m&lt;/p&gt;
&lt;p&gt;4/3 剛好有事去台北一趟，由於之前台北的朋友換車，剛好多一個後輪，於是表示願意給我後輪來補彰化百 K 壞掉的後輪，自此無內胎後輪 get! 配合乳膠開口胎前輪。&lt;/p&gt;
&lt;p&gt;4/30 因為 5/2 要參加台大舉辦的椰林杯友誼爬坡賽爬石碇，先跟另外兩位有參加的朋友走台三騎到台北，中間在大溪老街跑去吃了一下冰。&lt;/p&gt;
&lt;h3 id="202105"&gt;2021/05&lt;/h3&gt;
&lt;p&gt;DIST: 883.5 km, ELEV: 7298 m&lt;/p&gt;
&lt;p&gt;5/1 早上跟朋友跑一次石碇場勘，下午把握時間找高中同學去風櫃嘴跟中社，騎著騎著加昨天從新竹到台北，這時候其實屁股已經開始有點痛，所以中社時幾乎全程抽車慢慢騎上去的。&lt;/p&gt;
&lt;p&gt;5/2 台大椰林杯，經過一個晚上休息屁股好像不痛了，比賽時沒特別感覺。比完賽後直接跟朋友騎回新竹，這時候屁股又開始痛了，導致整個拖慢朋友的速度，到桃園後特別跟同學跑到我家裝水，後來到湖口時朋友應該是怕我太累，還特別問要不要去湖口老街吃冰，所以就繞一下到老街吃冰。&lt;/p&gt;
&lt;p&gt;COVID-19 疫情開始變嚴重，就沒有出門騎車了，都是在家採智障訓練台，所以真算只有距離，沒有爬坡 (不能調阻力)。&lt;/p&gt;
&lt;p&gt;5/17 跟 5/24 這兩周幾乎天天在家採台。&lt;/p&gt;
&lt;p&gt;我這台車大概騎了 5000 km，這兩個月就騎了 1600 km，真 D 有點混 (論文)。&lt;/p&gt;
&lt;h3 id="202106"&gt;2021/06&lt;/h3&gt;
&lt;p&gt;DIST: 67.6 km, ELEV: 0 m&lt;/p&gt;
&lt;p&gt;還敢騎車啊，都要口試了，論文還沒出來。還在群組裡被嗆騎一騎車就可以畢業 Orz。&lt;/p&gt;
&lt;p&gt;口試完後變超爛，原本可以 hold 180 w，現在 150 w 都有很辛苦 QQ。&lt;/p&gt;
&lt;h3 id="202107"&gt;2021/07&lt;/h3&gt;
&lt;p&gt;DIST: , ELEV: 0 m&lt;/p&gt;
&lt;p&gt;口試完，該回來練 tempo 了吧。疫情還沒結束，繼續採台當倉鼠。&lt;/p&gt;
&lt;h3 id="202202"&gt;2022/02&lt;/h3&gt;
&lt;p&gt;2/16 結束兵役後，收朋友二手碳纖夾煞管胎輪組兩組，共 1.5w。&lt;/p&gt;
&lt;p&gt;2/23 去 96 自轉車中壢店做北高前的車檢，順便買了一個手套跟一瓶鏈條油清潔劑，折 500 後花 1580。&lt;/p&gt;</description></item><item><title>Go Module 雜談</title><link>https://calee0219.github.io/blog/go_module_intro/</link><pubDate>Thu, 15 Oct 2020 00:34:57 +0000</pubDate><guid>https://calee0219.github.io/blog/go_module_intro/</guid><description>&lt;p&gt;v3.0.5 之後各 NF 使用 go module 維護所使用的 lib version，這邊簡單紀錄 go module 原理、free5GC 會面臨的問題、debug 手法&lt;/p&gt;
&lt;p&gt;Golang 原本沒有打算推出套件管理系統，因為據說 Google 內部並不會使用舊版 lib，而是使用單一程式庫(Mono Repo)[1]，若任何套件有跟新，就直接讓全部有使用此套件的軟體使用新版套件。可是外部社群不能這樣玩，所以逐漸推出了各自的套件版本管理系統，諸如 go dep, gopkg.in, vgo 等等。但在 go v1.11 Golang 社群 (或是 Google 內部 golang 維護者) 推出了 go module 系統，直接否定所有外部版本管理套件，因此當時也惹來了 go dep 開發者的不滿與爭吵[2]。&lt;/p&gt;
&lt;p&gt;Go module 類似於 npm 的 package.json，用一份 go.mod 檔案維護所使用的 lib 與使用的版本 (require 內部的東西)，在跑起來 (&lt;code&gt;go run&lt;/code&gt;、&lt;code&gt;go mod download&lt;/code&gt;、&lt;code&gt;go install&lt;/code&gt;、&lt;code&gt;go build&lt;/code&gt;) 的時候，就會直接用 &lt;code&gt;go get pakcage@version&lt;/code&gt; 的方式下載 library，並且放到 &lt;code&gt;$GOPATH/pkg/mod&lt;/code&gt; 資料夾下面。&lt;/p&gt;
&lt;h2 id="安裝使用"&gt;安裝使用&lt;/h2&gt;
&lt;p&gt;Go v1.11 之後的版本皆有 go module 可以使用，可以用 &lt;code&gt;go env GO111MODULE&lt;/code&gt; 確認 module 模式設定，有 on / off / auto 三種，on 預設都用 go module，off 都不用，auto 會看資料夾以及資料夾遞迴上去有沒有 go.mod 的檔案，如果有就用 go module，建議用 auto 就好，出問題再視情況 &lt;code&gt;go env -w GO111MODULE=on/off&lt;/code&gt; 設定修改。&lt;/p&gt;
&lt;h3 id="initialization"&gt;Initialization&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;go mod init {module name}&lt;/code&gt; 來初始化 go module，下完此指令後可以在資料夾下看到新增了一個 go.mod 的檔案，內容如下，module name 就是你自己定義的 module name，version 預設會使用目前你的 go 版本&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;此時還不會出現 require 欄位與 go.sum 檔案，如果資料夾下已經有 go file，可以用 &lt;code&gt;go mod tidy&lt;/code&gt; 做 go lib 的 polish，因為此指令會把 go.mod require 中沒用到的 lib 刪掉，同時會把 go file 內部有用到的 lib 放進 go.mod 中，因此可以用此指令幫忙直接更新 go.mod (直接 go run 或其他跑起來的指令，沒有被寫進 go.mod 的 lib 其實好像也會幫忙寫入)。&lt;/p&gt;
&lt;h3 id="載入已使用之-package"&gt;載入已使用之 package&lt;/h3&gt;
&lt;p&gt;下完 &lt;code&gt;go mod tidy&lt;/code&gt; 後，會發現 go.mod 多了 require 欄位，標明所使用的 lib 與所使用的版本，因為之前沒有這個欄位，go 預設會抓下指令時的最新版本，如果那個 lib 有打 git tag，會抓最新的 git tag 當版本，如果沒打，會抓最新的 commit hash 當版本&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;gopkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;in&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;v2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v2&lt;/span&gt;&lt;span class="mf"&gt;.3.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;wmnsk&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;gtp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v0&lt;/span&gt;&lt;span class="mf"&gt;.7.4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;bronze1man&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v0&lt;/span&gt;&lt;span class="mf"&gt;.0.0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20190516032554&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;afd8baec892d&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;gopkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;in&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;v1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;v1&lt;/span&gt;&lt;span class="mf"&gt;.0.0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20200227125254&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="nx"&gt;fa46927fb4f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// indirect&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其中因為 yaml.v2 有上 git tag，使用的版本是直接用 git tag 的 v2.3.0，而 radius 沒有打任何 git tag，因此版本使用 v0.0.0 後面接 commit 的時間 - {commit hash | cut -c 1-12}[3]。另外也有像是 check.v1 後面有註解 &lt;code&gt;// indirect&lt;/code&gt;，這代表這個 package 不是這份 project 本身有用到，但是是這個 project 所使用的 lib 有使用的 package。&lt;/p&gt;
&lt;h3 id="package-下載位置"&gt;Package 下載位置&lt;/h3&gt;
&lt;p&gt;這些 lib 會被 &lt;code&gt;go get&lt;/code&gt; 到 &lt;code&gt;$GOPATH/pkg/mod/{pakcage path}@{version}&lt;/code&gt; 下 (&lt;code&gt;$GOPATH&lt;/code&gt; 可以用 &lt;code&gt;go env GOPATH&lt;/code&gt; 看到)，例如 yaml 就會被下載到 &lt;code&gt;$GOPATH/pkg/mod/gopkg.in/yaml.v2@v2.3.0/&lt;/code&gt; 下面，若之後有升/降級用到其他版本，會重新抓到 &lt;code&gt;$GOPATH/pkg/mod/gopkg.in/yaml.v2@2.2.8/&lt;/code&gt; 下面。&lt;/p&gt;
&lt;p&gt;lib 檢查順序:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;檢查是否 go module，如果有 (go.mod / GO111MODULE)，看 package prefix 是否跟 go.mod 的 module name 相同，若相同則知道視同個專案，拔除 module name 後，postfix 當作 director path 往下找&lt;/li&gt;
&lt;li&gt;檢查是否有 vendor folder 在這個 project 下面，如果有，檢查 vendor 資料夾下是否有 modules.txt 檔案，若有，使用 modules.txt 所指向的 package 位置 (在 vendor 資料夾裡面)&lt;/li&gt;
&lt;li&gt;檢查 go.mod 或 modules.txt 是否有 replace，優先使用 replace 的 lib 位置&lt;/li&gt;
&lt;li&gt;module name prefix 不相同，檢查 &lt;code&gt;$GOPATH/pkg/mod&lt;/code&gt; 下是否有 lib&lt;/li&gt;
&lt;li&gt;拿 prefix URL git clone 看是否有東西&lt;/li&gt;
&lt;li&gt;檢查 &lt;code&gt;$GOPATH/src&lt;/code&gt; 下是否有 lib&lt;/li&gt;
&lt;li&gt;檢查 &lt;code&gt;$GOROOT&lt;/code&gt; 下是否有 lib&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="gosum"&gt;go.sum&lt;/h3&gt;
&lt;p&gt;另外，有 require 後，也會自動生出 go.sum 的檔案，這份檔案是用來維護 lib 的 check sum 做安全性與完整性的檢查，主要有兩種[4]，差別在於這個 package (lib) 是否有 go.mod 檔案 (是否是 go module 管理)，有 /go.mod 的 package 代表這個 lib 本身沒有用 go module 管理。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;lt;module&amp;gt; &amp;lt;version&amp;gt; &amp;lt;hash&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;lt;module&amp;gt; &amp;lt;version&amp;gt;/go.mod &amp;lt;hash&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;go.sum 上面講的東西其實不太重要，更詳細的內容可以翻[4] 有更多細節。主要需要知道的是 go.sum 是對使用 package 做的 checksum 檢查，因為 go module 對於任何合法的 url 都可以使用 (而不是像 npm 等作中心化管理)，避免被竄改所以需要做 checksum 檢查。另外 go.sum 還會紀錄之前有使用過的版本，因此一份陳年的 go.sum 內容會有很多版本 (transparent log)。&lt;/p&gt;
&lt;p&gt;既然 go.sum 的設計是紀錄 checksum，那就可能會帶出一些麻煩，常見有兩個問題&lt;/p&gt;
&lt;p&gt;在使用的 package 有 force push / rebase / commit &amp;ndash;amend 等強迫性操作時，再配合 git tag, git tag -d (刪除), git tag 的操作 (就是如果你要 re-tag)，會發生同一個 tag 在被 re-tag 後，checksum 不同，可是對 go.sum 來說，只能知道 checksum 不吻合可能被竄改，便會拒絕使用 package，這時候最簡單的作法是手動到 go.sum 內把當個 package 的 checksum 列全部刪掉，重新跑 go run，讓 go.sum 重抓，但更建議的是&lt;strong&gt;盡可能不要做 git 破壞性更新 (套件開發者不要亂搞&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;merge 時因為兩個 branch 更新了同一個套件，又尤其當兩個 branch 跟新到的版本 (commit) 不同，便需要手動解 conflict，大致有兩種解法，一是把曾用到的 commit 都納入 go.sum (branch a 跟 branch b 的 commit 都留著)，因為 go.sum 的 transparent log 性質，理論上曾經用過的版本都要留著；另外一種做法是選其中一個版本，確認可以 work 就好。嫌麻煩更簡單的做法一樣是進到 go.sum 把相關的列都刪掉，重新 go run 讓他自己抓。&lt;/p&gt;
&lt;p&gt;也許你會覺得直接不 commit go.sum 就好，可是因為 go module 不像 npm 信任一個中心化的套件管理倉儲，為了安全性與完整性，go.sum 應該是必須被 commit 的，而不像 npm 的 package-lock.json 應該被 ignore 掉。&lt;/p&gt;
&lt;h3 id="升級-package"&gt;升級 package&lt;/h3&gt;
&lt;p&gt;可以用 &lt;code&gt;go get -u {package}&lt;/code&gt; 來單獨升級 package 的 minor / patch version，可以用 &lt;code&gt;go get -u&lt;/code&gt; 來升級全部 package 的 minor / patch version，可以用 &lt;code&gt;go get -u=patch&lt;/code&gt; 只升級 patch，不過這都是在有打 git tag 的情況。&lt;/p&gt;
&lt;p&gt;可以用 &lt;code&gt;go get -u {package}@{version}&lt;/code&gt; 來使用特定版本，其中 version 可以是 git tag, branch name, commit hash, latest[5]。&lt;/p&gt;
&lt;p&gt;:::warning
go module 本身有一個指令 &lt;code&gt;go mod edit -require=path@version&lt;/code&gt; 可以更新 go.mod 的版本，但是官方不建議這樣使用。&lt;/p&gt;
&lt;p&gt;Note that -require overrides any existing requirements on path. These flags are mainly for tools that understand the module graph. Users should prefer &amp;lsquo;go get path@version&amp;rsquo; or &amp;lsquo;go get path@none&amp;rsquo;, which make other go.mod adjustments as needed to satisfy constraints imposed by other modules.
:::&lt;/p&gt;
&lt;p&gt;:::info
當過了一段時間 (尤其在 release 前)，建議用 go mod tidy 把沒在用的 package polish 掉，避免不必要的下載。
:::&lt;/p&gt;
&lt;h2 id="開發使用"&gt;開發使用&lt;/h2&gt;
&lt;h3 id="private-repo-問題"&gt;Private Repo 問題&lt;/h3&gt;
&lt;p&gt;由於我們內部的專案是 private repo，直接 go get 會 permission denied (403 access denied)，因此要處理權限問題。&lt;/p&gt;
&lt;p&gt;由於 go get 本身是用 git 的方式抓 package (可以用 &lt;code&gt;go get -x&lt;/code&gt; 或 &lt;code&gt;go mod download -x&lt;/code&gt; 看到詳細指令)，因此理論上只要 git fetch 可以抓的到 code 就可以了，常理來想就把 ssh-key 塞進 git server，然後用 git@ 的方式抓 code，或者指定帳號密碼用 https://ac:pw@ 的方式來抓 code，但是可以看出這兩種方法抓 code，都是需要改 upstream 的字串 (從 https:// 變成 git@ 或 https://ac:pw@)，而 go get 或自動加 https:// 在 package name 前面 (ex. github.com/free5gc/aper 會被加成
)，要如何讓他改成加 git@ 等呢? 這時候可以使用 git 的 insteadOf 操作，利用&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git config --global url.&lt;span class="s2"&gt;&amp;#34;git@github.com:free5gc/&amp;#34;&lt;/span&gt;.insteadOf https://github.com/free5gc/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;來使 git 在抓 code 的時候自動改變 url，而不需要在 go 上面改變操作。&lt;/p&gt;
&lt;p&gt;其中一定要用 &lt;code&gt;--global&lt;/code&gt; 參數，如果不下，這個參數只會被設定在 local project 裡面，而 go get 的時候是不會吃到這個參數的。這個設定會被寫入 &lt;code&gt;$HOME/.gitconfig&lt;/code&gt; 這份檔案裡，如果需要可以直接去改這份檔案。&lt;/p&gt;
&lt;p&gt;設定完 git 後似乎可行了，可是實際 &lt;code&gt;go get&lt;/code&gt; 時還是會抓不到，那是因為 &lt;code&gt;go env&lt;/code&gt; 內有 &lt;code&gt;GOPROXY&lt;/code&gt;[6] 與 &lt;code&gt;GOSUMDB&lt;/code&gt;[7] 兩個參數，這兩個參數類似 golang 本身的可信任函式庫，非 public 的 project 因為無法透過這兩個 proxy 被獲取，因此會被視為危險被竄改的 url，需要把 private repo url 列入 &lt;code&gt;GONOPROXY&lt;/code&gt; 與 &lt;code&gt;GONOSUMDB&lt;/code&gt; 參數內，而在 go 1.13 版本之後，有 &lt;code&gt;GOPRIVATE&lt;/code&gt;[8] 可以直接使用，它會幫忙同時寫入 &lt;code&gt;GONOPROXY&lt;/code&gt; 與 &lt;code&gt;GONOSUMDB&lt;/code&gt; 兩個參數。&lt;/p&gt;
&lt;p&gt;最後，理論上 &lt;code&gt;GOPROXY&lt;/code&gt; 參數預設就有 direct 在裡面，但是如果沒有，也需要加入&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;In short, 下兩個指令讓 go get 可以抓到 private repo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;`git config --global url.”git@github.com:free5gc/”.insteadOf https://github.com/free5gc/`
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;`go env -w GOPRIVATE=github.com/free5gc/*`
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;也可以直接用現成的 script: `cd infra/ &amp;amp;&amp;amp; ./infra.sh`
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="package-lib-開發問題"&gt;Package (lib) 開發問題&lt;/h3&gt;
&lt;p&gt;在開發時，單獨看一個 package 都是開發完後推上 git server 做 release，才讓別人使用。&lt;/p&gt;
&lt;p&gt;但由於我們同時是 package 的 producer 與 consumer，會出現如果把 package (lib) 開發完，推上 git server，使用的 NF 才能更新 go.mod 的版本來使用，但是這樣會遇到無法快速迭代測試的問題，也就是如果你正在 bugfix aper，你無法 local 修完直接用 amf 來測試 (往好處想就是 unit test 要寫得更詳細 &amp;#x1f914;)，而是需要先推到 remote server 上，然後更新 amf 的 go.mod 中 aper commit hash，才能來測試 amf 是否可以跑得起來，而如果發現 aper 有錯沒修好，就要反覆重複上面的動作。&lt;/p&gt;
&lt;p&gt;:::warning
仔細講這裡會遇到更多討論，像是為了避免 commit message 變得沒有意義，應該用 &lt;code&gt;git commit --amend&lt;/code&gt; 來更新，但是 &lt;code&gt;--amend&lt;/code&gt; 是 force push，會改變 commit hash 與 history，而這時候使用它的 project (amf) 因為有 go.sum 維護 checksum，可能會發現 history 被改變了而不允許跟新，這時候可能還會需要進到 go.sum 內手動改內容…
:::&lt;/p&gt;
&lt;h4 id="1-使用-replace9"&gt;1. 使用 replace[9]&lt;/h4&gt;
&lt;p&gt;在 go.mod 下使用 replace 可以把 go.mod 所使用的 package 替換成指定的路徑下的 package，就不會再從網路上拉並且放到 &lt;code&gt;$GOPATH/pkg/mod/&lt;/code&gt; 資料夾下面，用這個方法在修改指定路徑下的 package 後，更動可以直接 apply 到使用它的 project 上，使用上先 clone 你要改的 package 到你指定的 local path (之後才能 commit 回到 git server)，然後在 go.mod 中 replace package 到剛剛的位置 (可以用相對或絕對路徑)，然後進行修改&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone package /to/local/path
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go mod edit -replace &lt;span class="nv"&gt;package&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/to/local/path &lt;span class="c1"&gt;# 新增 replace，可以用相對或絕對路徑&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go mod edit -fmt &lt;span class="c1"&gt;# format go.mod，理論上用指令改了話不需要做&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;go mod edit -dropreplace package &lt;span class="c1"&gt;# 刪除 replace&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但 replace 本身有一個限制，無法 replace indirect 的 package，也就是說你&lt;strong&gt;無法 replace 你用到的 package 所使用到的 package&lt;/strong&gt;，ex. amf 用到 &lt;code&gt;util_3gpp&lt;/code&gt;，而 &lt;code&gt;util_3gpp&lt;/code&gt; 有用到 &lt;code&gt;crypto&lt;/code&gt;，如果 amf 本身沒用到 &lt;code&gt;crypto&lt;/code&gt;，它就不能 replace &lt;code&gt;crypto&lt;/code&gt;，就算把 replace &lt;code&gt;crypto&lt;/code&gt; 寫入 go.mod 中也不會生效。(如果改用 2. vendor 的做法，因為 vendor 等於把所有 package 用跟 &lt;code&gt;pkg/mod&lt;/code&gt; 的方式一樣全部都抓下來，所以應該可以把修改的 &lt;code&gt;crypto&lt;/code&gt; 應用進 amf 中)&lt;/p&gt;
&lt;p&gt;(replace 不只可以把 package 改成 local path，也可以修改 remote package 位置，因此很多 China 的文件有用 replace 來 bypass 牆)&lt;/p&gt;
&lt;h4 id="2-使用-vendor10"&gt;2. 使用 vendor[10]&lt;/h4&gt;
&lt;p&gt;(據說 vendor 會在之後的某一個 go 版本被 outdated)&lt;/p&gt;
&lt;p&gt;使用 &lt;code&gt;go mod vendor&lt;/code&gt; 會把 go.mod 內所有的 package 下載到 project 內的 vendor 資料夾下，並且建立一個 modules.txt 的檔案，由於 project 有 vendor 資料夾，go lib 會優先看這個資料夾內的 package，其中 package 的資料夾結構與 &lt;code&gt;$GOPATH/src&lt;/code&gt; 的相似，可以透過這個性質，cd 到要修改的 package，&lt;strong&gt;刪掉 package folder 後重新 clone 一個下來&lt;/strong&gt; (因為這個 folder 不會帶 git，無法 commit) (或用其他 git init / set-url 的方式)，再行修改。&lt;/p&gt;
&lt;p&gt;:::warning
要注意每次下 go mod vendor 指令，golang 會直接把 vendor 資料夾刪除後建立新的資料夾，不會檢查內部是否有修改，因此要小心 &lt;strong&gt;local change 一定要 push 上 server&lt;/strong&gt;。
:::&lt;/p&gt;
&lt;h2 id="considering-issue"&gt;Considering issue&lt;/h2&gt;
&lt;h3 id="go-mod-統一版本問題"&gt;Go mod 統一版本問題&lt;/h3&gt;
&lt;p&gt;另外一個 go.mod 需要注意的是，如果有多個 package (包含 project 本身) 有使用相同的 package，而大家又是用不同版本的此 package，golang 會遵守 Minimal Version Selection[11] 的原則來選擇 package 版本，以 Russ Cox 提出的 sample 為例，如果你有 A, B, C, D, E, F, G 不同的 package，而其中 A 用到 B, C，B 用到 D，C 也用到 D, F，D 用到 E，F 與 G 互相依賴，如附圖&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://research.swtch.com/version-select-1.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;其中用 1, 1.1, 1.2, 1.3, 1.4 等代表不同版本，經過歸納後，會產生一個建構清單&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://research.swtch.com/version-select-list.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://research.swtch.com/version-select-2.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;最後會使用 A1, B1.2, C1.2, D1.4, E1.2, F1.1, G1.1 的版本。這樣是否會導致問題? 理論上在 Semantic Versioning 的規範下，只要不是 major 版號更動，API 不應該有所變化，而使用最新的理應可以 work 並且效能或正確性高於舊版。&lt;/p&gt;
&lt;p&gt;然而在 lib 還沒上 Semantic Versioning git tag 前，這不一定適用於我們的專案，目前測試看起來 golang 會選擇主要(最上層)的 go.mod 作為版本依據，這還需要持續觀察以及是否會遇到問題。最理想的做法是以 NF 為單位，每個 NF 所使用的 lib 固定為 NF go.mod 所指定的版號，不同的 NF 可用不同版本的 lib。&lt;/p&gt;
&lt;h3 id="major-版本升級"&gt;Major 版本升級&lt;/h3&gt;
&lt;p&gt;如果之後要升級 major 版號，要如何處理?golang 官方不建議 major 版號升級只生 go.mod 的版號，畢竟理論上 major 升級應該是會有不相容的 API 更新[12]，而是建議在使用時就 import package/name/v2 的方式更新[13]，如果只更新 go.mod 會在 go.sum 出現 +incompatible 的字樣，提醒你有跟新 major 版號，你的 code 使用要檢查。&lt;/p&gt;
&lt;p&gt;如何減少 major 版號更新是設計之初便要思考的，可以參考 Go Blog:
&lt;/p&gt;
&lt;h2 id="trouble-shooting"&gt;Trouble Shooting&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;go.mod 不可以在 &lt;code&gt;$GOPATH&lt;/code&gt; 之中。&lt;/li&gt;
&lt;li&gt;因為
，如果 package 不明原因無法自動獲取不到 (ex. private repo issue)，可以考慮直接到 &lt;code&gt;$GOPATH/pkg/mod&lt;/code&gt; 或 &lt;code&gt;$GOPATH/src&lt;/code&gt; 下面直接做 &lt;code&gt;git clone&lt;/code&gt;，或用 copy folder 方式把東西丟上去，唯需要注意路徑，如果是 &lt;code&gt;pkg/mod&lt;/code&gt; 需要把 folder 名稱重新命名為 &lt;code&gt;path/same/as/url/name@version-time-commit&lt;/code&gt;，並且要把內部的 &lt;code&gt;.git&lt;/code&gt; folder 刪掉 (不刪掉應該也沒差，不過 go 自己抓的好像會沒有)；如果是 &lt;code&gt;$GOPATH/src&lt;/code&gt; 只要路徑對就好。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ref"&gt;Ref:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[1]
,
,
&lt;/li&gt;
&lt;li&gt;[2]
&lt;/li&gt;
&lt;li&gt;[3] &lt;code&gt;git --no-pager show --abbrev=12 --format=&amp;quot;%cd-%h&amp;quot; --date='format-local:%Y%m%d%H%M%S' --quiet&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;[4]
&lt;/li&gt;
&lt;li&gt;[5]
&lt;/li&gt;
&lt;li&gt;[6]
&lt;/li&gt;
&lt;li&gt;[7]
&lt;/li&gt;
&lt;li&gt;[8]
,
&lt;/li&gt;
&lt;li&gt;[9]
,
,
&lt;/li&gt;
&lt;li&gt;[10]
&lt;/li&gt;
&lt;li&gt;[11]
,
, ,
&lt;/li&gt;
&lt;li&gt;[12]
&lt;/li&gt;
&lt;li&gt;[13]
,
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>在 RPI 4 (4G) 上更新 Ubuntu 18.04 Server 的 kernel 版本</title><link>https://calee0219.github.io/blog/rpi_build_kernel/</link><pubDate>Sun, 26 Jul 2020 22:44:04 +0800</pubDate><guid>https://calee0219.github.io/blog/rpi_build_kernel/</guid><description>&lt;p&gt;軟硬體&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HW: Raspberry Pi 4 4G&lt;/li&gt;
&lt;li&gt;SD Card: SanDisk Extreme PRO 64GB&lt;/li&gt;
&lt;li&gt;OS: Ubuntu Server 18.04&lt;/li&gt;
&lt;li&gt;Default kernel: 5.3.0-1017-raspi2&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="燒-os"&gt;燒 OS&lt;/h2&gt;
&lt;p&gt;先把 Ubuntu Server 18.04 燒進 SD Card，因為我們使用原生方式編譯，而不是 cross compile 後再把 image 燒進 SD Card&lt;/p&gt;
&lt;p&gt;這種好處是可以讓系統自己抓硬體參數，不過壞處可能是比你的 Server CPU 編譯速度慢很多&lt;/p&gt;
&lt;h2 id="下載-source-與安裝-build-tools"&gt;下載 Source 與安裝 build tools&lt;/h2&gt;
&lt;p&gt;因為使用 Ubuntu 18.04 是 bionic，因此需要抓 bionic 的 source&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install git libncurses-dev flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf debhelper
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone git git://kernel.ubuntu.com/ubuntu/ubuntu-bionic.git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="設定編譯參數"&gt;設定編譯參數&lt;/h2&gt;
&lt;p&gt;在 editconf 實惠需要設定編譯參數，因為我們只有需要使用 arm64 (RPI 4 用 arm8 是 arm64)，因此前面的設定都可以 n 跳過，到 arm64 時再 Y 修改，當然如果你沒有東西要改也可以 n pass 掉，我自己有嘗試改過，但改完後就 check failed，所以最後選擇不改&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ubuntu-bionic
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod a+x debian/rules
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod a+x debian/scripts/*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;chmod a+x debian/scripts/misc/*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;LANG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;C fakeroot debian/rules clean
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;LANG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;C fakeroot debian/rules editconfigs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="編譯"&gt;編譯&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;LANG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;C fakeroot debian/rules clean
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;LANG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;C fakeroot debian/rules binary-headers binary-generic binary-perarch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果你需要編除了 generic 外的 kernel，可以直接編譯全部&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;LANG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;C fakeroot debian/rules binary
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;此時就會需要很編譯久，也可以考慮用比較快的 x86 CPU 做 cross compile，此種方法比較麻煩的是你需要知道每個需要的參數再喂進去，而直接在要跑的硬體上面編譯的好處就是可以讓系統自己抓參數&lt;/p&gt;</description></item><item><title>心靈 G 湯</title><link>https://calee0219.github.io/blog/chicken_soup_for_the_soul/</link><pubDate>Fri, 24 Jul 2020 07:41:22 +0800</pubDate><guid>https://calee0219.github.io/blog/chicken_soup_for_the_soul/</guid><description>
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;寧願面對自己而悲觀，也不要欺騙自己而樂觀&lt;/p&gt;
&lt;p&gt;&amp;ndash;科技島讀&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;當你知道越多，你會體諒越多。當你了解一切，你就會原諒一切&lt;/p&gt;
&lt;p&gt;&amp;ndash; 藍X呈&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;當你們認為之前的選擇是錯誤的時候，你們並沒有只是口頭抱怨而已，你們是真的起身行動去投票，嘗試著改變之前的錯誤&lt;/p&gt;
&lt;p&gt;第一種人是一旦發現自己犯了錯，就自怨自艾，期待外界來幫忙，而不是自己想去修正自己的錯誤，而第二種人，在發現自己犯錯之後，會嘗試這靠著自己的努力，來修正自己所犯下的錯誤，而這兩種人之間的差別最大的部分是，會不會自己動手做出改變&lt;/p&gt;
&lt;p&gt;一個願意為了自己人生負起責任的人，就算犯了錯也會嘗試著去修正，因為它並沒有打算把自己人生能不能變得更好這件事情丟到別人的肩膀上然後說這一切都是社會的問題&lt;/p&gt;
&lt;p&gt;而高雄市民這次罷免成功，告訴我們一件事，就是自己犯下的錯誤是真的有機會可以透過自己的努力來翻轉的，或許翻轉這件事情並沒有那麼容易，但是卻是真的有機會有可能可以做到的&lt;/p&gt;
&lt;p&gt;&amp;ndash; M 觀點 Mula&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Building hugo-academic with GitHub</title><link>https://calee0219.github.io/blog/deploy_hugo/</link><pubDate>Sun, 21 Jun 2020 22:13:15 +0800</pubDate><guid>https://calee0219.github.io/blog/deploy_hugo/</guid><description>&lt;p&gt;Hugo + Academic theme + github pages 個人網頁&lt;/p&gt;
&lt;p&gt;Academic 官網建議使用 Netlify 方式部署，方法可見
&lt;/p&gt;
&lt;h2 id="安裝-hugo"&gt;安裝 HUGO&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;macOS&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew install hugo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ubuntu&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="下載-hugo-academic"&gt;下載 Hugo Academic&lt;/h2&gt;
&lt;p&gt;這裡建議直接用
修改，原因是 academic 要新增的 config 頗多，直接修改會比較簡單&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/sourcethemes/academic-kickstart.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; academic-kickstart
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git submodule update --init --recursive
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;用以下指令跑起 server 確認是否下載成功&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo server -D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;到網頁 &lt;code&gt;http://localhost:1313&lt;/code&gt; 觀看執行結果，另外 &lt;code&gt;hugo server -D&lt;/code&gt; 會動態修改，所以可以放著給它跑&lt;/p&gt;
&lt;h2 id="調整內容"&gt;調整內容&lt;/h2&gt;
&lt;h3 id="設定"&gt;設定&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;刪除教學導覽&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;rm content/home/demo.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改網頁 metadata&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://calee0219.github.io/img/hugo-metadata.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改 title icon&lt;/p&gt;
&lt;p&gt;更改 &lt;code&gt;assets/images/icon.png&lt;/code&gt;，將此檔案修改成需要的 icon&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;修改 &lt;code&gt;/config/_default/params.toml&lt;/code&gt;，這份檔案擁有幾乎所有網站的參數，確實將需要的填入&lt;/p&gt;
&lt;p&gt;特別需要注意，其中 &lt;code&gt;address&lt;/code&gt;, &lt;code&gt;address_format&lt;/code&gt; 跟 &lt;code&gt;[address_format]&lt;/code&gt; 需要互相配合 (格式有的欄位都要有)，不然之後如果有需要用來產生 address 可能會出現問題&lt;/p&gt;
&lt;p&gt;另外 &lt;code&gt;main_menu = {align = &amp;quot;r&amp;quot;, show_logo = true}&lt;/code&gt; 個人習慣 align 都靠右，會有 navbar 靠右的效果&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="header"&gt;header&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;修改 &lt;code&gt;/config/_default/menus.toml&lt;/code&gt;，其中 &lt;code&gt;weight&lt;/code&gt; 參數的大小會決定這個 tag 放置前後，weight 越小，排越前面&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="內容"&gt;內容&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;將不需要的 block 隱藏，選擇 &lt;code&gt;content/home/&lt;/code&gt; 下的 .md 檔案，將不需要的 md 內，&lt;code&gt;active = false&lt;/code&gt;，需要的 &lt;code&gt;active = true&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://calee0219.github.io/img/hugo-active.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;about.md&lt;/code&gt; 需要另外修改，他是使用 link 到 admin author (預設是 admin，你也可以改成其他人)&lt;/p&gt;
&lt;p&gt;需要去 &lt;code&gt;content/authors/admin/_index.md&lt;/code&gt; 修改使用者資料&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;icon: 像是 &lt;code&gt;skills.md&lt;/code&gt; 頁面或其他會需要用到 icon，academic 預設有連動 &lt;code&gt;font awesome&lt;/code&gt; 跟 &lt;code&gt;jpswalsh&lt;/code&gt; 的 icon，更多的需要自行匯入 svg 檔到 &lt;code&gt;/assets/images/icon-pack/&lt;/code&gt; 內，然後使用時填寫如下，其中 icon 部分填寫檔名 (.svg 之前的內容)&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://calee0219.github.io/img/hugo-custom-icon.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Ref:
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="部署-github-pages"&gt;部署 GitHub Pages&lt;/h2&gt;
&lt;h3 id="產生-source-html"&gt;產生 source (html)&lt;/h3&gt;
&lt;p&gt;用 &lt;code&gt;hugo&lt;/code&gt; 指令不加參數會生產 html file，但是 default 會 generate 在 &lt;code&gt;/public&lt;/code&gt; 資料夾下面&lt;/p&gt;
&lt;p&gt;如果有特別需求 (等下會用到)，可以在 &lt;code&gt;config/_default/config.toml&lt;/code&gt; 裡面新增一個參數 &lt;code&gt;publicDir = &amp;quot;/docs&amp;quot;&lt;/code&gt; 指定 generate 的 folder&lt;/p&gt;
&lt;h3 id="部署上-github"&gt;部署上 GitHub&lt;/h3&gt;
&lt;h4 id="github-pages"&gt;GitHub Pages&lt;/h4&gt;
&lt;p&gt;GitHub 提供兩種 GitHub Pages 可以使用，一種是 &lt;code&gt;http(s)://&amp;lt;user&amp;gt;.github.io&lt;/code&gt;，而另外一種是 &lt;code&gt;http(s)://&amp;lt;user&amp;gt;.github.io/&amp;lt;repository&amp;gt;&lt;/code&gt;，可以參考
，建議視是否為自己主頁做考量，因為當別人在 GitHub 想查詢你這個使用者時，常常會試著看看是否有 &lt;user&gt;.github.io 這個 repo，因此如果你希望被看到，可以考慮第一種方法&lt;/p&gt;
&lt;p&gt;如果是使用方法一，需要在 GitHub 上開一個 &lt;user&gt;.github.io 的 repo，&lt;user&gt; 填入自己的 GitHub account，其他的 repo 名稱都無法，至於後續的設定兩種方法都一樣&lt;/p&gt;
&lt;p&gt;使用方法二好處是可以一直開專案，專案名稱自訂。開好專案後直接將 code 連同 html source 一起推上去，由於 GitHub Pages 只提供兩種來源讀 html source，一個是從專案的 root，另外一個是從專案的 &lt;code&gt;/docs&lt;/code&gt; 讀，又個人不建議直接把 html source 放在 root 會變得很亂，因此推薦把 html source 統一編進 &lt;code&gt;/docs&lt;/code&gt; 資料夾內，編完推 code 後，到 Setting 頁往下滑，看到 &lt;code&gt;GitHub Pages&lt;/code&gt;，如圖設定即可&lt;/p&gt;
&lt;p&gt;
&lt;figure &gt;
&lt;div class="flex justify-center "&gt;
&lt;div class="w-full" &gt;&lt;img src="https://calee0219.github.io/img/GitHub_Pages.png" alt="" loading="lazy" data-zoomable /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 id="github-actions"&gt;GitHub Actions&lt;/h4&gt;
&lt;p&gt;另外一種部署方法是使用 CD 來做，官方建議用 netlify，也可以使用 GitHub Actions 來部署，用這種方法就不需要推 src 上 repo 裡面&lt;/p&gt;
&lt;p&gt;參考
與
兩份文件&lt;/p&gt;</description></item></channel></rss>