沐鳴平台註冊登錄_在技術和業務中保持平衡

如果時間退回到十多年以前,新興互聯網公司的技術人員幾乎都是從「業務開發」開始自己的職業生涯的。然而到了今天,不知道你有沒有發現,業務開發和純技術的開發已經有了明顯的分野。

最開始,互聯網業務的出現,讓人們第一次從用戶需求和用戶體驗的角度來設計產品。正是這種與傳統生意的不同,造就了很多互聯網早期的傳奇故事。而互聯網公司的技術人員,作為這些用戶產品的真正實現者,他們的目標就是用技術來解決產品實現問題。也就是說,代碼是直接服務於產品需求的(典型的業務開發)。在這個過程中,技術人員逢山開路,遇水架橋,遇到什麼樣的技術問題就解決什麼樣的技術問題。遇到存儲問題,他們就調試和擴容數據庫;遇到系統問題,他們就升級系統軟件,做基本的運維工作;遇到架構問題,他們就設計技術架構,直接支撐業務。總之,對業務邏輯的開發和對技術問題的解決,這兩件事是很難分開的。

正是在這樣的業務驅動的過程中,豐富的公用組件、技術體系或框架被設計出來,並逐漸從業務中抽離。搜索引擎產品,將信息檢索(Information Retrieval)技術的工程化推向了前所未有的高度;社交網絡對於信息流的需求,催生了基於寫擴散和讀擴散的整套信息流分發的技術架構(也包括存儲架構);隨着移動互聯網的興起,前後端分離的技術比以往走得更遠,同時也出現了眾多以客戶端邊緣計算為核心的專業編程技術。

在這樣的大背景下,絕大多數能從業務中剝離的技術,都已經形成了開源項目。從MVC基礎編程框架,到各種分佈式數據庫技術,到微服務調用和異步消息隊列,再到大數據處理的整個技術棧,開源世界已經應有盡有,且不止一種選擇。如今,新成立的創業公司,面對新的業務需求,技術人員在技術選型上的空間已經相當豐富,基本可以像搭積木一樣把產品搭建出來。技術人員可以把更多精力放在業務開發上,從而大大提高了產品迭代的效率。但是,隨着業務的做大,技術團隊肯定也會不斷碰到一些「純技術問題」的困擾,需要對某些底層技術架構更專業的人員才能解決。於是,有一定規模的公司,或者基於開源項目進行二次開發,或者自研自己的底層架構,希望在長遠的業務競爭中跑得更持久。

為了下文討論清晰,我們將這些負責開發和維護底層技術架構的技術人員,稱為「專業技術開發」人員;而將主要精力放在業務邏輯開發上的技術人員,稱為「業務開發」人員。

各自的要求

在有些時候,「業務開發」和「專業技術開發」之間的區分並不是那麼明顯,特別是在一些初創的公司內部。這兩類技術人員,他們都需要和業務人員(產品經理、運營人員、市場人員等)打交道。畢竟,所有的技術需求,源頭都是來源於業務層面,兩者只是「度」上的區別。對於一些剛進入職場的技術同學來說,他們甚至很難意識到自己的工作到底屬於哪一類。但是,無論如何,你需要審視一下自己當前的工作,並結合自己的技術特點,看一下到底偏向哪一個方面。這關係到長遠的規劃。

我們先看一下對這兩種開發人員各自的要求是怎樣的。

先說「專業技術開發」,技術上的要求主要在於深度上,要能層層進階,逐步逼近技術的本質。不同的階段就犹如孤獨求敗的三柄長劍。

第一柄劍,乃是利劍,「凌厲剛猛,無堅不摧」。就好比一個初入職場,躊躇滿志的年輕人,渾身充滿鬥志且技術精湛。他面對再複雜的系統,都能像一柄「利劍」一樣,刺開迷霧,抽絲剝繭,深入到背後的原理。僅僅「會用」,遠不是他的目標。

第二柄劍,是重劍,所謂「重劍無鋒,大巧不工」。就好比一個資深的架構師,不僅深諳現有系統和框架的特性,也同樣知曉它們的優點和缺陷,更能夠憑藉一己之力設計出更好的系統。種種繁複的技術細節,都是表象;再龐大的系統,也盡在掌握之中。花哨的技巧,早就不是他追求的目標。

第三柄劍,卻是一柄木劍。到了這個階段,已經達到了「不滯於物,草木竹石均可為劍」的狀態。在他眼裡,眾多不同的上層技術,不同的開發語言,不同的技術棧,在底層都能看到相同的技術本質。本來繁雜的各路技術思想逐步歸一,並對它們之間可能產生的融合與變化瞭然於胸。

再看一下「業務開發」人員。他們的工作不像前一種那麼單純,而是需要面對整個世界的複雜度。對這一類技術人員的要求,除了技術本身之外,還需看重兩點:一個是要有業務Sense;另一個是要對業務數據敏感。

所謂業務Sense,又要從兩方面來看:用戶價值和商業價值。首先,他應該對創造更好的用戶體驗興趣濃厚,他能夠從用戶的視角看待問題,有一定的「共情」能力。他應該對於產品所帶來的用戶價值有自己的判斷,而不僅僅是被動接收產品經理的需求。其次,他應該對商業模式有一定的認識。他知道以LTV(用戶的終身價值)和CAC(用戶獲取成本)為基礎的產品標尺;他能認識到,一個好的產品必須在市場、產品、渠道、模型這四者之間達到契合。

所謂業務數據敏感,首先,他應該很明確地了解到業務的數據目標是什麼,並能夠清醒地意識到這個目標是整個團隊的事情,而不僅僅是產品經理或運營人員的KPI。其次,他應該知道這個業務目標如何拆解到技術層面,能意識到技術事項和數據指標之間的邏輯關係。更進一步,他可能還需要對事物之間真實的因果關係有一定的分析能力,能夠推斷出哪一些產品或技術的改動可能對數據指標產生影響,並能夠對如何通過AB實驗來探索改進產品有系統的思維方法;他對於數據敏感,知道所維護的產品在AARRR整個用戶生命周期(拉新、激活、留存、推薦、變現)上的特點,並能推斷出哪些行為可能會對各個漏斗的轉化率產生影響。

有些讀者會說,這看起來更像是對業務人員的要求,而不是對技術人員的要求。但「業務開發」人員的工作,每天都與業務緊密相關,所以業務人員的思維方式他也需要有所了解。當然,最後還有最重要的一項要求——技術本身。一位「業務開發」人員,他應該知道什麼樣的產品方案適合用怎樣的技術方案來支撐,這是最基本的要求。除此之外,他還應該提前做好技術布局,為業務的未來發展掃清障礙;同時,他能清醒地計算ROI(投入產出比),用較小的技術投入換取最大的業務價值。沒錯,「業務開發」最終就是這樣,領着程序員的工資,操着CEO的心。

總之,對比一下「專業技術開發」和「業務開發」:前一種是專才,追求大道至簡;后一種是全才,講究學識淵博,包羅萬象。

各自的困境

社會分工本質上是生產力發展的結果。就像我們在前面分析的一樣,「專業技術開發」和「業務開發」這兩種技術人員,是從互聯網業務的不斷繁榮中逐漸分化出來的。首先,分化意味着專業化;但在某種程度上說,也意味着「無趣」。早期初創企業中那種“光着膀子聽着歌,一邊盯着用戶反饋,一邊直接修改線上產品”的粗放的快樂時刻,現在的技術人員很難體會到了。粗放的做法被專業化的方案所替代,技術的「上古田園時期」已經一去不復返了。

專業化分工對於技術人員的成長所帶來的影響是深遠的。我們就來看一下這兩種技術人員在成長過程中各自可能碰到的困境。對於兩者來說,這些困境有些相同,有些不同。

首先第一點,他們都會遭遇到成長的邊際效用遞減法則。邊際效用遞減法則,本來是一個經濟學概念,通俗地解釋就是,對於同樣的一件事情,開始投入的時候,收益值很高,越到後來,同樣的投入量能換取的收益值就越少。大到國家和企業,小到一個團隊和個人,這個原則都適用。

具體到技術人員的成長上來說,對於「業務開發」,最開始進入一個業務領域的時候,也是成長最快的時候。他通常要在短時間內掌握很多專業的「領域知識」,這個過程就好像一塊干海綿一下子吸滿了水。等到他能夠嫻熟地駕馭這些「領域知識」之後,業務邏輯的開發就變成了枯燥的、重複性的工作。而對於「專業技術開發」來說,這個過程發生在技術深度的拓展上。一個技術精湛的、像一柄「利劍」一樣的技術同學,他能夠在短時間內摸清一個底層架構的百分之八十,這個過程也是他最有收穫的過程。但當他能夠應付大部分技術需求的時候,變化也變得越來越少,他會感覺到翻來覆去還是那麼些東西;而在技術深度上要想再深入一層,也是千難萬難。

第二點是業務價值和技術亮點的衝突。對於「業務開發」來說,技術亮點通常很難提煉。他每天可能會花費90%的時間都在做業務邏輯的開發,但「業務邏輯開發」這件事情本身卻不一定能體現出技術亮點。他需要不斷地去概括、去抽象,去挖掘業務背後更深層的技術問題。而對於「專業技術開發」來說,則經常面臨重複造輪子的風險。由於底層架構的復用性通常都比較強,他需要考慮所造的「輪子」對於業務的獨特價值到底是什麼,到底有沒有必要性,到底是不是技術的自high。

最後,「業務開發」會更多地受到業務興衰的影響。業務經常面臨着試錯風險,業務由盛轉衰,或者自始至終就沒有成功過,不管哪一種情況,最後的結果都是大部分寫過的代碼被拋到一邊,一切從頭開始。「專業技術開發」當然也會受到影響,但影響程度會小一點。

尋找平衡點

隨着業務的繁榮和技術的發展,整個知識庫變得愈發龐大了,而人的精力有限。既關注技術,又關注業務,經常讓人力不從心。所以需要尋找平衡點。

這個平衡點,對於不同的人不一樣,對於不同的具體職位,也不一樣。

這就好比金庸小說中逍遙派里的人物,蘇星河除了跟無崖子學武功之外,還學琴、學弈、學書法、學繪畫,結果耽誤了武學,最後敗給了丁春秋。而另一個武學人物——黃藥師,就平衡地很好,不但奇門遁甲、琴棋書畫、天文地理都有涉獵,而且武功卓絕,屬於宗師的級別,還能自創出「落英神劍掌」之類的武功來。當然,金庸小說中也有成功的「專才」,比如喬峰,比如郭靖,都堪稱「戰神」級別。

所以說,每個人都有適合自己的策略。有些人喜歡心無旁騖,持續鑽研,始終如一;有些人則比較愛折騰,喜歡經常換個領域,比如專業技術干久了,就換到業務方向嘗試,或者反過來。

不過有一個現實的情況可能需要考慮,對於「專業技術開發」和「業務開發」,社會的職位需求量肯定是後者比前者多得多。這個也很好理解,業務是公司的核心,業務也發展變化更快。所以通常情況下,技術人員比較理想的狀態是「一專多能」。首先能夠精通某一個專業領域的技術(由於精力有限,能夠精通一個專業領域已經非常不錯了),比如搜索技術,比如推薦技術,比如分佈式架構,然後還能對業務有所了解,能夠從業務的視角去思考問題。

在「專業技術開發」和「業務開發」兩者之中,不存在哪個更好、哪個更壞的問題;如何把握兩者之間的「度」和平衡點,也沒有一個絕對的答案。但不管是偏向哪一個方向,重要的是搞清自己當前的現狀和未來的定位,以及從「現在」到「未來」的路線是什麼。

平衡點對每個人都不一樣,而且對同一個人的不同時期來說,也是一個動態的平衡。持續關注新的領域,給自己找到下個階段應該了解和深入研究的領域(技術領域或業務領域),才是不斷成長的關鍵。在不斷成長的動態的過程中,你才有機會總結出一套結構化的思維方式,甚至逐漸走出常規,開拓不一樣的人生。

總之,時間有限,不要浪費太多。因為,青春很快就會逝去。

(正文完)

歡迎關注我的個人微博: 微博上搜索我的名字「 張鐵蕾 」,與我互動 。

原文 https://mp.weixin.qq.com/s/OUdH5RxiRyvcrFrbLOprjQ

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7492

沐鳴註冊平台官網_兩種JavaScript異常處理的方式

一、瀏覽器拋出異常

1、標準格式

try{ 
    //可能發生異常的代碼 
}catch(error){ 
    //發生錯誤執行的代碼 
}

2、finally語句

try{ 
    //可能發生異常的代碼 
}catch(error){ 
    //發生錯誤執行的代碼 
}finally{
    // 不管 try 中的語句有沒有錯誤,都會執行的語句
}

即:try 中語句不發生錯誤執行完畢後會執行 finally 中的語句,try 中的語句發生錯誤,則執行 catch中的語句,catch 中的語句執行完畢后也會執行 finally 中的語句。
3、錯誤類型
•Error 基類型,即其他的錯誤類型都是從 Error 繼承來的
•EvalError 使用 eval() 函數發生異常時被拋出。
•RangeError 數值超出規定範圍時被拋出
•ReferenceError 找不到對象時,會拋出
•SyntaxError 語法錯誤時
•TypeError 變量中保存着意外的類型,或者訪問不存在的方式時
•URIError 使用 encodeURI() 或者 decodeURI() 時,URI 的格式不正確

二、throw主動拋出異常

1、js內置錯誤類型對象

throw new Error(“主動拋出的錯誤,後面代碼不執行”);


2、自定義錯誤類型對象

繼承任何一個自定義錯誤類型都可以。一般直接繼承Error即可

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7487

沐鳴註冊網站_vue props傳值常見問題

傳入的值想作為局部變量來使用,直接使用會 報錯。錯誤是說的避免直接修改父組件傳入的值,因為會改變父組件的值

解決方案:

可以在data中重新定義一個變量,改變指向,但是也只是針對簡單數據類型,因為複雜數據類型棧存貯的是指針,

props:['listShop'],
    data(){
      return{
        listShopChild:this.listShop
      }
    },
    created(){
      this.listShopChild=30
    }
    

對複雜數據類型,
1. 可以手動深度克隆一個複雜的數據出來,循環或者遞歸都行

//數組
var x = [1,2,3];
var y = [];
for (var i = 0; i < x.length; i++) {
    y[i]=x[i];
}
console.log(y);  //[1,2,3]
y.push(4);
console.log(y);  //[1,2,3,4]
console.log(x);  //[1,2,3]

//對象
var x = {a:1,b:2};
var y = {};
for(var i in x){
    y[i] = x[i];
}
console.log(y);  //Object {a: 1, b: 2}
y.c = 3;
console.log(y);  //Object {a: 1, b: 2, c: 3}
console.log(x);  //Object {a: 1, b: 2}

2. Object.assign   (看情況使用)
只會對只是一級屬性複製,比淺拷貝多深拷貝了一層而已,所以還是無法達到深度克隆的目的.

3. 強大的jsON.stringify和jsON.parse

const obj1 = JSON.parse(JSON.stringify(obj))

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7486

沐鳴總代理_用了幾十年的瀏覽器 user-agent 要退出歷史舞台了?看看 Google 怎麼說

Google 近日宣布,計劃在 Chrome 瀏覽器上逐步淘汰 user-agent 字符串。

這裏稍微解釋下,user-agent (UA,用戶代理) 字符串是現代 web 和瀏覽器功能的重要組成部分。

UA 字符串是瀏覽器建立連接時向網站發送的一段文本。UA 字符串包含了瀏覽器類型、渲染引擎和操作系統等詳細信息。例如,Windows 10 上的 Firefox 瀏覽器 UA 是這樣的:

*Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/72.0*

UA 在90年代作為 Netscape 瀏覽器的一部分被開發出來,一直沿用至今。幾十年來,各種網站都在利用 UA 字符串,根據訪客的客戶端情況調整功能特性。

但是現在,谷歌表示這個曾經有用的機制已經成為各種問題的持續來源。

首先,UA字符串已經被在線廣告商用來跟蹤和識別網站訪客。

“這些隱私問題中最嚴重的是,用戶代理嗅探是兼容性問題的多數來源,尤其是小眾瀏覽器,會統一或針對特定網站謊報UA,一些網站(包括谷歌的網站)在某些瀏覽器上毫無理由的崩潰。”為 Chrome 瀏覽器工作的谷歌工程師 Yoav Weiss 說到。

為了解決這些問題,谷歌計劃通過凍結整個標準來逐步消除 UA 字符串在 Chrome 中的重要性。

計劃

Google 的計劃是停止更新 Chrome 的 UA 字符串內容。

長期的計劃是將所有的 Chrome UA 字符串統一為通用值,這樣就不會泄露太多用戶信息。

這意味着在新的平台上發布的新 Chrome 瀏覽器,比如在新的智能手機型號或新的操作系統版本上,將使用通用的 UA 字符串,而不是為特定平台定製的。

例如,在未來,一個網站將無法區分使用 Chrome 的訪客是在 Windows 7 還是 Windows 11上運行 Chrome,或者 Chrome 移動用戶是在使用三星 Galaxy 手機還是 Pixel 9 手機。

網站只能夠識別用戶是否在運行 Chrome,以及他們是否在桌面或移動設備上,但僅此而已。

為了歷史遺留目的,現有的 Chrome UA 字符串將繼續工作,所以它們不會破壞運行在整個web上現有的技術和腳本。

下面是谷歌目前棄用 UA 字符串的計劃:

  • Chrome 81 (2020 3月中旬) – 谷歌計劃在 Chrome 控制台中為讀取 UA 字符串的網頁显示警告,這樣開發者可以調整網站代碼。
  • Chrome 83 (2020 6月初) – 谷歌將在 UA 字符串中固定 Chrome 瀏覽器版本並統一操作系統版本
  • Chrome 85 (2020 9月中旬) – 谷歌將統一桌面操作系統 UA 字符串作為桌面瀏覽器的通用值。谷歌還將統一移動操作系統/設備字符串作為一個類似的通用值。

再見,UA字符串!你好,CLIENT HINTS!

對 UA 字符串機制的棄用是谷歌改善網絡隱私的努力的一部分,但不會扼殺網絡廣告,而廣告是當今大多數免費網站的命脈。

Chrome 中的 UA 字符串將被一個名為Client hint 的新機製取代。通過這種機制,網站可以請求關於用戶的信息,但沒有“歷史包袱和古老的User-Agent 標頭暴露的被動指紋信息”,官方標準是這樣寫的。

Client Hints 已經被開發為谷歌的Privacy Sandbox項目的一部分,該項目於去年8月份宣布。

Privacy Sandbox 技術棧旨在為網站和廣告商提供一種方式,使他們能夠在瀏覽器中查詢用戶詳細信息,同時又不會暴露太多用戶信息。

通過 Privacy Sandbox,瀏覽器將分享足夠的用戶信息,這樣廣告商就可以將用戶分組了,而不是創建詳細的個人資料。

棄用 UA 字符串改用 Client Hints 是谷歌實現 Chrome Privacy Sandbox 的第一步,這也是谷歌去年夏天承諾的。

蘋果(Safari)、微軟(Edge)和 Mozilla (Firefox)也表示支持谷歌凍結和逐步取消用戶代理字符串的提議,但在撰寫本文時尚未宣布具體計劃。

來源: zdnet.com

翻譯整理:1024譯站 

 

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7315

沐鳴註冊_vue腳手架寫法

一直想建一個自己公司自用的腳手架,可以方便的快速開發。於是開始看vue-cli的源碼和一些網上的教程。發現,一款腳手架其實很簡單,主要原理就是從遠程下載一個模板來新建一個項目。同時提供了一系列的交互來動態的更改模板。
下面先將建立一款腳手架可能用到插件及其使用方法列出:

1、commander

用來編寫指令和處理命令行
安裝commander:
npm install commander –save

主要api解析

(1)version

作用:定義版本號
用法:.version(‘0.0.1’, ‘-v –version’)
參數解析:

  • 版本號(必須)
  • 自定義標誌(可省略):默認為-V和–version

(2)option

作用:定義命令選項
用法:.option(‘-n –name<path>’, ‘name description’, ‘default name’)
參數解析:

  • 自定義標誌<必須>:分為長短標識,中間用逗號、豎線或者空格分割;標誌後面可跟必須參數或可選參數,前者用 <> 包含,後者用 [] 包含
  • 選項描述<可省略>:在使用 –help 命令時显示標誌描述
  • 默認值<可省略>

例子:

program
  .version('0.1.0', '-v, --version')
  .option('-i, --init', 'init something')
  .option('-g, --generate', 'generate something')
  .option('-r, --remove', 'remove something');

(3)command

作用:添加命令名稱
用法:.command(‘rmdir <dir> [otherDirs…]’, ‘install description’, opts)
參數解析:

  • 命令名稱<必須>:命令後面可跟用 <> 或 [] 包含的參數;命令的最後一個參數可以是可變的,像實例中那樣在數組後面加入 … 標誌;在命令後面傳入的參數會被傳入到 action 的回調函數以及 program.args 數組中
  • 命令描述<可省略>:如果存在,且沒有显示調用action(fn),就會啟動子命令程序,否則會報錯
  • 配置選項<可省略>:可配置noHelp、isDefault等

(4)description

作用:定義命令的描述
用法:.description(‘rmdir desc’)

(5)action

作用:定義命令的回調函數
用法:.action(fn)

(6)parse

作用:解析process.argv,設置options以及觸發commands
用法:.parse(process.argv)

(7)on
作用:自定義監聽事件
用法:.on(‘name’, fn)
例子:

// 必須在.parse()之前,因為node的emit()是即時的
program.on('--help', function(){
 console.log('  Examples:');
  console.log('');
  console.log('    this is an example');
  console.log('');
});
program.on('option:verbose', function(){
  process.env.VERBOSE = this.verbose;
})

//error on unkown commands
program.on('command:*', function(){
  console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' '))
  process.exit(1);
})

綜合用法示例

// 引入依賴
var program = require('commander');
 
// 定義版本和參數選項
program
  .version('0.1.0', '-v, --version')
  .option('-i, --init', 'init something')
  .option('-g, --generate', 'generate something')
  .option('-r, --remove', 'remove something');
 
// 必須在.parse()之前,因為node的emit()是即時的
program.on('--help', function(){
 console.log('  Examples:');
  console.log('');
  console.log('    this is an example');
  console.log('');
});
 
program.parse(process.argv);
 
if(program.init) {
  console.log('init something')
}
 
if(program.generate) {
  console.log('generate something')
}
 
if(program.remove) {
  console.log('remove something')
}
var program = require('commander')
program
  .version('0.1.1')
  .command('rmdir <dir> [otherDirs...]')
  .action(function(dir, otherDirs){
    console.log('rmdir %s', dir)
    if(otherDirs){
        otherDirs.forEach(function(oDir){
          console.log('rmdir %s', oDir)
        })
    }
  })
  
program.parse(process.argv)

執行 node index.js rmdir ./test aaa

2、inquirer

用來進行交互式命令行
安裝:npm install inquirer –save
語法結構:

const inquirer = require('inquirer');

const promptList = [
    // 具體交互內容
];

inquirer.prompt(promptList).then(answers => {
    console.log(answers); // 返回的結果
})

基本api
type:表示提問的類型,包括:input, confirm, list, rawlist, expand, checkbox, password, editor;
name: 存儲當前問題回答的變量;
message:問題的描述;
default:默認值;
choices:列表選項,在某些type下可用,並且包含一個分隔符(separator);
validate:對用戶的回答進行校驗;
filter:對用戶的回答進行過濾處理,返回處理后的值;
transformer:對用戶回答的显示效果進行處理(如:修改回答的字體或背景顏色),但不會影響最終的答案的內容;
when:根據前面問題的回答,判斷當前問題是否需要被回答;
pageSize:修改某些type類型下的渲染行數;
prefix:修改message默認前綴;
suffix:修改message默認後綴。

使用示例

var inquirer = require('inquirer');
const promptList = [{
    type: 'input',
    message: '設置一個用戶名',
    name: 'name',
    default: 'test_user'
},{
    type: 'input',
    message: '請輸入手機號',
    name: 'phone',
    /*validate: function(val){
        if(val.match(/\d{11}/g)){
            //return val
        }
        return "請輸入11位数字"
    }*/
},{
    type: 'confirm',
    message: '是否啟用監聽',
    name: 'watch',
    prefix: '前綴',
    suffix: '後綴',
    when: function(answers){
        //當watch為true時,開始提問
        return answers.watch
    }
},{
    type: 'list',
    message: '請選擇一種水果',
    name: 'fruit',
    choices:[
        "Apple",
        "Pear",
        "Banana"
    ], 
    filter: function(val){
        //將回答變為小寫
        return val.toLowerCase()
    }
}]

inquirer.prompt(promptList).then(answers => {
    // 回調函數,answers 就是用戶輸入的內容,是個對象
    console.log(answers)
})

3、chalk

設置控制台輸出內容的樣式
使用示例

const chalk = require('chalk')
//控制顏色
console.log(chalk.green('success'))
console.log(chalk.blue.bgRed.bold('Hello world'))
console.log(chalk.underline.bgBlue('lala'))

ora

提供一個加載中效果
使用示例

const ora = require('ora')
//出現加載效果
let spinner = ora('downloading template')
spinner.start()
//加載失敗效果
spinner.fail()
//結束加載效果
spinner.succeed()

download-git-repo

下載遠程模板:支持github、gitlab等
使用語法:

const download = require('download-git-repo')
download(repository, destination, options, callback)

repository為遠程倉庫地址,destination為下載的文件路徑,默認當前目錄,options時一些選項,比如clone:boolean表示用http下載還是git clone的形式下載

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7496

沐鳴開戶_JavaScript 函數式編程中 compose 實現

簡介

比如有這樣的需求,要輸入一個名字,這個名字有由firstName,lastName組合而成,然後把這個名字全部變成大寫輸出來,比如輸入jack,smith我們就要打印出來,‘HELLO,JACK SMITH’ 。

我們考慮用函數組合的方法來解決這個問題,需要兩個函數greeting, toUpper

var greeting = (firstName, lastName) => 'hello, ' + firstName + ' ' + lastName
var toUpper = str => str.toUpperCase()
var fn = compose(toUpper, greeting)
console.log(fn('jack', 'smith'))
// ‘HELLO,JACK SMITH’

這就是compose大致的使用,總結下來要注意的有以下幾點

  • compose的參數是函數,返回的也是一個函數
  • 因為除了第一個函數的接受參數,其他函數的接受參數都是上一個函數的返回值,所以初始函數的參數是多元的,而其他函數的接受值是一元的
  • compsoe函數可以接受任意的參數,所有的參數都是函數,且執行方向是自右向左的,初始函數一定放到參數的最右面

知道這三點后,就很容易的分析出上個例子的執行過程了,執行fn(‘jack’, ‘smith’)的時候,初始函數為greeting,執行結果作為參數傳遞給toUpper,再執行toUpper,得出最後的結果,compose的好處我簡單提一下,如果還想再加一個處理函數,不需要修改fn,只需要在執行一個compose,比如我們再想加一個trim,只需要這樣做

var trim = str => str.trim()
var newFn = compose(trim, fn)
console.log(newFn('jack', 'smith'))

就可以了,可以看出不論維護和擴展都十分的方便。

實現

例子分析完了,本着究其根本的原則,還是要探究與一下compose到底是如何實現的,首先解釋介紹一下我是如何實現的,然後再探求一下,JavaScript函數式編程的兩大類庫,lodash.js和ramda.js是如何實現的,其中ramda.js實現的過程非常函數式。

我的實現

我的思路是,既然函數像多米諾骨牌式的執行,我首先就想到了遞歸,下面就一步一步的實現這個compose,首先,compose返回一個函數,為了記錄遞歸的執行情況,還要記錄參數的長度len,還要給返回的函數添加一個名字f1。

var compose = function(...args) {
    var len = args.length
    return function f1() {

    }
}

函數體裏面要做的事情就是不斷的執行args中的函數,將上一個函數的執行結果作為下一個執行函數的輸入參數,需要一個游標count來記錄args函數列表的執行情況。

var compose = function(...args) {
    var len = args.length
    var count = len - 1
    var result
    return function f1(...args1) {
        result = args[count].apply(this, args1)
        count--
        return f1.call(null, result)
    }
}

這個就是思路,當然這樣是不行的,沒有退出條件,遞歸的退出條件就是最後一個函數執行完的時候,也就是count為0的時候,這時候,有一點要注意,遞歸退出的時候,count游標一定要回歸初始狀態,最後補充一下代碼

var compose = function(...args) {
        var len = args.length
        var count = len - 1
        var result
        return function f1(...args1) {
            result = args[count].apply(this, args1)
            if (count <= 0) {
                count = len - 1
                return result
            } else {
                count--
                return f1.call(null, result)
            }
        }
    }

這樣就實現了這個compose函數。後來我發現遞歸這個完全可以使用迭代來實現,使用while函數看起來更容易明白,其實lodash.js就是這麼實現的。

lodash實現

lodash的思路同上,不過是用迭代實現的,我就把它的源代碼貼過來看一下

var flow = function(funcs) {
    var length = funcs.length
    var index = length
    while (index--) {
        if (typeof funcs[index] !== 'function') {
            throw new TypeError('Expected a function');
        }
    }
    return function(...args) {
        var index = 0
        var result = length ? funcs[index].apply(this, args) : args[0]
        while (++index < length) {
            result = funcs[index].call(this, result)
        }
        return result
    }
}
var flowRight = function(funcs) {
    return flow(funcs.reverse())
}

可以看出,lodash的本來實現是從左到右的,但也提供了從右到左的flowRight,還多了一層函數的校驗,而且接收的是數組,不是參數序列,而且從這行var result = length ? funcs[index].apply(this, args) : args[0]可以看出允許數組為空,可以看出還是非常嚴謹的。我寫的就缺少這種嚴謹的異常處理。

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/8701

沐鳴註冊網站_使用原生js實現選項卡功能實例教程

選項卡是前端常見的基本功能,它是用多個標籤頁來區分不同內容,通過選擇標籤快速切換內容。學習本教程之前,讀者需要具備html和css技能,同時需要有簡單的JavaScript基礎。

先來完成html部分。首先,需要一個元素把整個選項卡包含在內。新建一個div元素,它的id命名為tabBox,如下所示:

<div id="tabBox"></div>

在tabBox元素裏面,再把選項卡分為標籤和內容兩個部分,分別命名class為label_box和content_box,如下所示:

<div id="tabBox" class="tab_box">
  <ul class="label_box"></ul><!--標籤部分-->
  <div class="content_box"></div><!--內容部分-->
</div>

一般情況下,標籤元素和內容元素的數量要保持一致,在本實例中把標籤和內容都設為三個。 分別在label_box和content_box元素中添加標籤和內容,如下所示:

<div id="tabBox" class="tab_box">
  <ul class="label_box"><!--標籤部分-->
    <li>選項一</li>
    <li>選項二</li>
    <li>選項三</li>
  </ul>
  <div class="content_box"><!--內容部分-->
    <div class="content">內容一</div>
    <div class="content">內容二</div>
    <div class="content">內容三</div>
  </div>
</div>

為了讓選項卡好看一點,讀者可以根據自己喜好加上一些樣式,也可以直接複製以下樣式代碼使用:

.tab_box{
  width:600px;
  margin:30px auto;
}
.label_box{
  padding-left:30px;
  font-size:0;
}
.label_box li{
  display:inline-block;
  line-height:30px;
  height:30px;
  padding:0 10px;
  margin:0 5px;
  font-size:14px;
  border:1px solid #2d9aff;
  border-bottom:none;
  border-top-left-radius:4px;
  border-top-right-radius:4px;
  cursor:pointer;
}
.label_box li.active{
  background:#2d9aff;
  color:#fff;
}
.content_box{
  padding:20px;
  border:1px solid #2d9aff;
  border-radius:4px;
  box-shadow:0px 0px 6px #aaa;
}
.content_box .content{
  display:none;
  height:300px;
}

完成html和css部分之後,再來使用js實現標籤切換的功能。本實例把選項卡功能封裝到函數中,所以先創建一個primaryTab函數,在primaryTab中再來編寫具體代碼。

筆者建議在完成某一個前端功能時,應先分析功能的具體操作。再根據具體操作把實現功能的方法分成多個步驟,接下來一個步驟一個步驟去完成它。

選項卡的操作非常簡單,就是選擇標籤(可以是點擊,也可以是鼠標滑過,本實例使用點擊事件)時,快速切換內容且修改當前激活標籤樣式。默認情況下第一個標籤元素為當前激活狀態,第一個內容元素需要显示。把這樣一個操作,在實現功能上來可分成三個步驟:

1 獲取標籤元素和內容元素
2 給第一個標籤元素添加active樣式修改為激活狀態;把第一個內容元素通過樣式display:bolock來显示。
3 在標籤上添加事件,實現切換內容
  3.1 遍歷標籤,給每一個標籤添加事件
  3.2 在事件函數中遍歷標籤,把每一個標籤的className改為空字符串,用於刪除激活標籤樣式。
  3.3 在事件函數中遍歷內容元素,把每一個內容元素通過樣式設置為隱藏。
  3.4 在事件函數中通過this找到當前標籤元素,設置className,修改當前標籤元素樣式為激活狀態。
  3.5 在事件函數中通過變量找到對應的內容元素,並通過樣式設置為显示。
具體代碼如下:

function primaryTab(){
  //1.獲取選項卡外包元素
  var eTab = document.getElementById('tabBox'); 
  //1.獲取標籤外包元素
  var eLabel = eTab.getElementsByClassName('label_box')[0];
  //1.獲取所有標籤元素的集合  
  var aLabels = eLabel.getElementsByTagName('li');
  //1.獲取內容外包元素
  var eContent = eTab.getElementsByClassName('content_box')[0];
  //1.獲取所有內容元素的集合
  var aContents = eContent.getElementsByClassName('content');
  //2.給第一個標籤元素添加active樣式修改為激活狀態 
  aLabels[0].className = 'active';
  //2.把第一個內容元素通過樣式display:bolock來显示
  aContents[0].style.display = 'block';
  //3.1 遍歷標籤,注意:本實例這裏聲明變量i只能用let,如果用var會出錯
  for(let i=0;i<aLabels.length;i++){
    //3.1 給每一個標籤添加點擊事件
    aLabels[i].onclick = function(){
      //3.2 遍歷標籤 
      for(let n=0;n<aLabels.length;n++){
        //3.2 把每一個標籤的className改為空字符串,用於刪除激活標籤樣式。
        aLabels[n].className = '';
        //3.3 因為標籤元素和內容元素數量相同,所以可通過變量n把每一個內容元素通過樣式設置為隱藏
        aContents[n].style.display = 'none'; 
      }
      // 3.4 通過this找到當前標籤元素,修改當前標籤元素為激活狀態。
      this.className = 'active';  
      //3.5 通過變量i找到對應的內容元素,並通過樣式設置為显示。
      aContents[i].style.display = 'block'; 
    }
  }
}
//調用選項卡函數
primaryTab();

好了,就是這麼簡單,相信通過本教程的學習,你一定很輕鬆可以掌握js選項卡功能。

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/8663

沐鳴註冊_那些程序員喜歡經常溜達的網站

github

如果說非要選一個網站來代表程序員的話,github一定是排在第一位的,這裡是開源的世界,這裡是代碼的世界,這裡是一個程序員展現自我的世界。如果你沒有聽過github,我估計你一定不是程序員,或者你就是一個假的的程序員。

cnblogs

這是程序員書寫心得的地方,這是程序員分享經驗的地方,通常人們不會直接訪問這裏,但是當人們在搜索某個問題的時候,總會不經意間路過這裏,而在這裏總能不經意間收穫滿滿。它的自定義主題樣式,讓它的界面清新簡潔,如果你會css,在這裏你可以打造任何你想要的效果。

stackoverflow

內事不明問度娘,外事不明問谷哥,程序不明問棧哥。作為專門程序的問答網站,它的回答幾乎可以解決你90%以上的問題,有人曾說過,過去是面向過程的編程,現在是面向對象的編程,未來就是面向搜索引擎的編程,在大數據的加持下,好多問題你都能在這裏得到解決。

v2ex

這是一個非常另類的網站,從它的名字你就能看出。同時它也是一個讓人又愛又恨的網站,喜歡它的人很喜歡,不喜歡的人也異常討厭它,它有着自己的用戶群體,在這裏你的思想總能獲得解放,你總能不經意間在這裏獲得到巨大提升。

Pinterest

不想當裁縫的廚師不是好司機,不想當設計的產品經理不是好程序員。作為一個程序員,我們也是有追求的,我們也會喜歡美的事物。作為一個免費的高清圖片網站,程序員們有時候也會去上面找幾個圖片作為編輯器的背景圖。

leecode

程序=數據結構+算法,那麼優秀的程序員一定是算法功底深不可測。如何提高自己的算法素養,leecode絕對是你最佳的選擇,如果你有過大廠面試經歷的話,你就會發現,好多面試官問的問題都出自leecode,所以平時多逛逛leecode,對一個程序員的素質提升絕對有幫助。

TED

學無止境,活到老學到老,作為一個程序員,我們不僅僅關注代碼,對世界的方方面面我們都很好奇,我們喜歡去聽別人的演講,在TED你總能不經意間拓寬自己的視野,生活不止眼前的苟且,還有詩和遠方。程序員的世界里也不止代碼,還有文人和科學。

其它

程序員不止一種,有做android的,有做ios的,有寫php的,有寫java的,每個語言都有自己官網,也都有自己的社區,有時候你會發現,正是這些形形色色的網站讓我們每個孤立的個體有了聯繫,如果你有珍藏的好的網站,歡迎你的分享。

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/8709

沐鳴註冊平台官網_讀懂Base64編碼

我們知道一個字節可表示的範圍是 0 ~ 255(十六進制:0x00 ~ 0xFF), 其中 ASCII 值的範圍為 0 ~ 127(十六進制:0x00 ~ 0x7F);而超過 ASCII 範圍的 128~255(十六進制:0x80 ~ 0xFF)之間的值是不可見字符。

ASCII(American Standard Code for Information Interchange,美國信息交換標準代碼)是基於拉丁字母的一套電腦編碼系統。它主要用於显示現代英語,而其擴展版本延伸美國標準信息交換碼則可以部分支持其他西歐語言,並等同於國際標準 ISO/IEC 646。

在 ASCII 碼中 0 – 31和 127 是控制字符,共 33 個。

其餘 95 個,即 32 – 126 是可打印字符,包括数字、大小寫字母、常用符號等。

當不可見字符在網絡上傳輸時,比如說從 A 計算機傳到 B 計算機,往往要經過多個路由設備,由於不同的設備對字符的處理方式有一些不同,這樣那些不可見字符就有可能被處理錯誤,這是不利於傳輸的。為了解決這個問題,我們可以先對數據進行編碼,比如 base64 編碼,變成可見字符,也就是 ASCII 碼可表示的可見字符,從而確保數據可靠傳輸。Base64 的內容是有 0 ~ 9,a ~ z,A ~ Z,+,/ 組成,正好 64 個字符,這些字符是在 ASCII 可表示的範圍內,屬於 95 個可見字符的一部分。

二、什麼是 base64

Base64是一種基於 64 個可打印字符來表示二進制數據的表示方法。由於 2⁶ = 64 ,所以每 6 個比特為一個單元,對應某個可打印字符。3 個字節有 24 個比特,對應於 4 個 base64 單元,即 3 個字節可由 4 個可打印字符來表示。相應的轉換過程如下圖所示:

Base64 常用於在處理文本數據的場合,表示、傳輸、存儲一些二進制數據,包括 MIME 的电子郵件及 XML 的一些複雜數據。在 MIME 格式的电子郵件中,base64 可以用來將二進制的字節序列數據編碼成 ASCII 字符序列構成的文本。使用時,在傳輸編碼方式中指定 base64。使用的字符包括大小寫拉丁字母各 26 個、数字 10 個、加號 + 和斜杠 /,共 64 個字符,等號 = 用來作為後綴用途。Base64 相應的索引表如下:

了解完上述的知識,我們以編碼 Man 為例,來直觀的感受一下編碼過程。 Man 由 M、a 和 n 3 個字符組成,它們對應的 ASCII 碼為 77、97 和 110。

接着我們以每 6 個比特為一個單元,進行 base64 編碼操作,具體如下圖所示:

由圖可知, Man (3字節)編碼的結果為 TWFu (4字節),很明顯經過 base64 編碼后體積會增加 1/3。 Man 這個字符串的長度剛好是 3,我們可以用 4 個 base64 單元來表示。但如果待編碼的字符串長度不是 3 的整數倍時,應該如何處理呢?

如果要編碼的字節數不能被 3 整除,最後會多出 1 個或 2 個字節,那麼可以使用下面的方法進行處理:先使用 0 字節值在末尾補足,使其能夠被 3 整除,然後再進行 base64 的編碼。

以編碼字符 A 為例,其所佔的字節數為 1,不能被 3 整除,需要補 2 個字節,具體如下圖所示:

由上圖可知,字符 A 經過 base64 編碼后的結果是 QQ== ,該結果後面的兩個 = 代表補足的字節數。而最後個 1 個 base64 字節塊有 4 位是 0 值。

接着我們來看另一個示例,假設需編碼的字符串為 BC ,其所佔字節數為 2,不能被 3 整除,需要補 1 個字節,具體如下圖所示:

由上圖可知,字符串 BC 經過 base64 編碼后的結果是 QkM= ,該結果後面的 1 個 = 代表補足的字節數。而最後個 1 個 base64 字節塊有 2 位是 0 值。

三、base64 編碼的應用

在 html 中嵌入 base64 編碼的圖片

在編寫 html 網頁時,對於一些簡單圖片,通常會選擇將圖片內容直接內嵌在網頁中,從而減少不必要的網絡請求,但是圖片數據是二進制數據,該怎麼嵌入呢?絕大多數現代瀏覽器都支持一種名為 Data URLs 的特性,允許使用 base64 對圖片或其他文件的二進制數據進行編碼,將其作為文本字符串嵌入網頁中。

<img alt="logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...">

但需要注意的是:如果圖片較大,圖片的色彩層次比較豐富,則不適合使用這種方式,因為該圖片經過 base64 編碼后的字符串非常大,會明顯增大 HTML 頁面的大小,從而影響加載速度。除此之外,利用 HTML FileReader API,我們也可以方便的實現圖片本地預覽功能,具體代碼如下:

<input type="file" accept="image/*" onchange="loadFile(event)">
<img id="output"/>
<script>
  const loadFile = function(event) {
    const reader = new FileReader();
    reader.onload = function(){
      const output = document.querySelector('output');
      output.src = reader.result;
    };
    reader.readAsDataURL(event.target.files[0]);
  };
</script>

在完成本地圖片預覽之後,可以直接把圖片對應的 Data URLs 數據提交到服務器。針對這種情形,服務端需要做一些相關處理,才能正常保存上傳的圖片,這裏以 Express 為例,具體處理代碼如下:

const app = require('express')();

app.post('/upload', function(req, res){
    let imgData = req.body.imgData; // 獲取POST請求中的base64圖片數據
    let base64Data = imgData.replace(/^data:image\/\w+;base64,/, "");
    let dataBuffer = Buffer.from(base64Data, 'base64');
    fs.writeFile("image.png", dataBuffer, function(err) {
        if(err){
          res.send(err);
        }else{
          res.send("圖片上傳成功!");
        }
    });
});

MIME(多用途互聯網郵件擴展)

在 MIME 協議之前,郵件的編碼曾經有過 UUENCODE 等編碼方式 ,但是由於 MIME 協議算法簡單,並且易於擴展,現在已經成為郵件編碼方式的主流,不僅是用來傳輸 8 位的字符,也可以用來傳送二進制的文件,如郵件附件中的圖像、音頻等信息,而且擴展了很多基於 MIME 的應用。

四、如何進行 base64 編碼和解碼

在 JavaScript 中,有兩個函數被分別用來處理解碼和編碼 base64 字符串:

  • btoa():該函數能夠基於二進制數據 “字符串” 創建一個 base64 編碼的 ASCII 字符串。
  • atob(): 該函數能夠解碼通過 base64 編碼的字符串數據。

btoa 使用示例

const name = 'Semlinker';
const encodedName = btoa(name);
console.log(encodedName); // U2VtbGlua2Vy

atob 使用示例

const encodedName = 'U2VtbGlua2Vy';
const name = atob(encodedName);
console.log(name); // Semlinker

對於 atob 和 btoa 這兩個方法來說,其中的 a 代表 ASCII,而 b 代表 Blob,即二進制。因此 atob 表示 ASCII 到二進制,對應的是解碼操作。而 btoa 表示二進制到 ASCII,對應的是編碼操作。在了解方法中 a 和 b 分別代表的意義之後,在以後的工作中,我們就不會用錯了。

五、總結

Base64 是一種數據編碼方式,目的是為了保障數據的安全傳輸。但標準的 base64 編碼無需額外的信息,即可以進行解碼,是完全可逆的。因此在涉及傳輸私密數據時,並不能直接使用 base64 編碼,而是要使用專門的對稱或非對稱加密算法。

原文 https://semlinker.com/master-base64/

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7338

沐鳴登錄網站_Mac上程序員很喜歡用10大開發軟件

走進BAT,你們會發現,他們都喜歡使用Mac,Mac作為一個創作工具,一直深受程序員,教授,高科技行業從業者的喜歡。

Mac及佳的穩定性,也是用戶喜歡的一個主要原因,Mac可以讓你專註於創作,跟iPhone一樣,Mac沒有那麼多流氓軟件和彈窗。提高了我們工作效率。

Mac圍繞着創作的生態,也是Mac讓我撇開Windows沒有絲毫的不適應的關鍵,下面我為大家推薦一下Mac下常用10大軟件。

1.IDEA

作為Java開發者,從elipse,到MyElipse.到今天的IDEA,還是覺得IDEA為我們提供更加簡潔的開發方式。也是全球最受Java開發者歡迎的開發工具。從Maven的管理,到打包,到環境部署。都十分的方便。IDEA,同時也適合做vue,和Node.js的開發。

2.Pycharm

在Python大行其道的今天,Python遍全球,作為程序員,怎麼不會對它保持好奇心呢。pycharm自然是你上手Python最便捷的梯子。在pycharm上你幾乎可以忘掉終端指令,內嵌指令,和虛擬環境配置指令,一鍵生成,跟你構建Java項目一樣一鍵生成。點擊run既可以運行。

3.Navicat Premium

作為一個程序員來說,數據庫對於開發中起了至關重要的作用,一個好的數據庫管理工具。為我們的開發提供方便,Navicat Premium從剛開始全英文,到現在的中文,使用起來也是更加方便,在這個工具上你可以查看數據庫,建表操作,包括數據庫備份和導入一鍵搞定,你可以不用任何指令了。

4.Github Desktop

版本管理SVN,以及老去,Git已經成為版本管理主流了。如果到了今天還有程序員對於Git還一無所知的話。那就真的out啦。git確實有很多複雜的指令。確實我也是經常用到的時候去百度,上手Git版本的控制其實沒有那麼難,Github Desktop就為我們解決這個問題,你不用任何指令,在只需要在網頁創建好分支,選擇要給文件夾,點擊commit就可以push到遠程git服務器。跟很多人一樣,我當時用這款軟件知道,這個是幫我傳代碼到GitHub上,其實這款軟件支持所有私有的Git服務器,比如說碼雲和碼市。等等。全自動操作。

5.終端

終端,對於很多實用Mac的用戶,估計都沒有打開過,會不會使用終端,也是一個電腦專業級使用者和入門的使用者分水嶺了。終端對於Mac也是至關重要的。

1.終端是用戶和操作系統,進行專業級交互窗口。比如一些權限的控制,我們都可以通過終端來完成。

一些軟件啟動,尤其一些沒有用戶界面的軟件的啟動,比如說數據庫,Tomcat,Nginx,等等。

2.終端可以讓你我們去安裝各種軟件,軟件的操作和配置。終端簡單來說,就可以讓我們的Mac變身一台服務器,用好終端,可以說,你基本上不需要跑虛擬機。指令同根同源,嫣然就是一個Linux服務器跑在你的後台,數據庫軟件,Tomcat,Nginx,tornado,包括docker,都可以在終端完成。終端可以讓你Mac變身成為一個開發服務器來使用,並且性能可靠穩定。比所謂虛擬機的性能不知道要高多少。

3.終端同時也是你可以炫技的舞台,不用鼠標,查看各種文件。配置各種文件。終端簡直太好用了。

6.VMware Fusion

Vmware是最經典的虛擬機軟件。Mac開通虛擬機還是比較爽的。性能還是比較高的,尤其現在的Macbook pro都可以支持8核心,32G內存,虛擬機可以說可以大展拳腳的。想體驗原生的linux虛擬機,是一個不錯的選擇。Vm現在已經戴爾公司收購。經濟實力允許還是建議使用正版的。

7.Typora

作為程序員,還是需要經常的沖一下電,經常會看一下Markdown文檔,Typora應該很好的Markdown文檔閱讀器了。

8.Visual Studio for Mac

微軟這幾年一直在推動跨平台開發,Visual Studio除了支持了Java,python,C#等開發語言。還支持ios和安卓,當然對於他的了解確實並不是很深。對於微軟的生態這一塊,確實了解的不太深入。簡單的使用一下,感覺他支持同時支持安卓和ios,感覺還是很強大,一直聽程序員說Visual Studio是比較強大的IDE,有時間還是多了解一下。

9.xcode.

Xcode是蘋果公司的推出適應於ios平台和Mac上很強大的開發工具,他伴隨Mac和ios系統每一次更新和升級,Xcode提供了強大的模擬器。性能極佳。希望xcode能夠開發直接運行iPa的模擬器了。這樣可以讓Mac是娛樂性更好一些了。當然Xcdoe同時支持C,C++這也是一個學習C++,一個非常好用的IDE了。Xcode在安裝一些指令和編譯器上也起到很重要的作用。你在Xcode上可以開發iPhone,Apple Watch,Mac,iPad各種軟件,甚至遊戲的封包也可能會遇到他。

10.谷歌瀏覽器

谷歌瀏覽器已經成為全球份額很高的瀏覽器,一直深受前端開發者喜歡,調試前端的利器。最為一個程序員,還是需要一些前端 相關的知識。谷歌瀏覽器還是必備的軟件了。

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7332