Skip to content

zh

我從為海外客戶構建大規模應用程序中學到的東西

中國的IT行業正在迅速增長。在過去的一年中,我在香港有幸參與了一個引人入勝的項目,這項目已經成為我職業生涯中的一個重要里程碑,給我提供了學習新事物和創新的機會。

雖然在許多項目中工作,但每個團隊成員都位於同一地點通常更具生產力。然而,我發現自己與不同時區的遠程同事合作,包括太平洋標準時間,UTC-06:00和UTC+10:00,這對生產力並不理想。

另一個挑戰是與客戶的語言障礙。對於會說中文但打字不熟練的人,我建議學習拼音輸入法以跟上QQ聊天中的簡短對話。

許多外國人驚訝地發現,中國審查了GitHub,使得在長城防火牆內簡單地使用npm install& bower install變得不可能。此外,AWS的主機以及一些分析工具也被封鎖,需要尋找替代方案。而且,你的開發同事可能更喜歡不同的工作方式,而不是採用scrum方法或是用JIRA板來提供項目的可見性。

我們的Ember應用程序公開測試遇到了性能問題。儘管Ember的開發工具非常友好,但初始加載和渲染時間仍然很慢。加劇這個問題的是,我們至少有20%的客戶使用過時的瀏覽器和低端電腦。令我驚訝的是,僅僅從加載圖標字體就讓Windows XP崩潰。最終,我們通過用原生JavaScript重構了應用程序來解決這個問題。雖然這提高了速度,但卻使代碼的數量加倍,並使要管理的狀態和錯誤的數量增加了三倍,這與理想情況相去甚遠。

我們用痛苦的方式學到了一個關鍵的教訓,那就是保持對交付管道的完全控制的重要性;否則,一個發布就變得難以達成。早發布,常發布,更多的是一種藝術而非科學。儘管我們花了幾個月的時間進行了三次重新設計並得到了積極的反饋,我們仍然無法啟動該項目。大公司內部的慣性和抵制改變的文化證明了這一點太難以克服。

通過這個項目,我們對技術和項目管理方面都獲得了寶貴的見解。早發布,常發布是最好的做法,我期待將這些經驗應用到未來的項目中。

如何將Webpack與React和Bootstrap一起使用

今天,我正在設定一個使用Webpack、React和Bootstrap(不包括jQuery)的專案。原本看似簡單直接的任務結果卻花了我比預期多的時間,所以我決定將步驟記錄在下面:

步驟1:安裝所有依賴

首先,安裝所有需要的依賴:

npm install react react-dom bootstrap react-bootstrap babel-preset-react --save
npm install webpack css-loader style-loader file-loader url-loader babel-core babel-loader babel-preset-es2015 --save-dev

步驟2:在webpack.config.js中添加Loaders

接下來,在你的webpack.config.js文件中添加必要的loaders:

var path = require("path")
var webpack = require("webpack")

module.exports = {
  entry: "./main.js",
  output: { path: __dirname, filename: "bundle.js" },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        loader: "babel-loader",
        exclude: /node_modules/,
        options: {
          presets: ["es2015", "react"],
        },
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.png$/,
        loader: "url-loader?limit=100000",
      },
      {
        test: /\.jpg$/,
        loader: "file-loader",
      },
      {
        test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
        loader: "url-loader?limit=10000&mimetype=application/font-woff",
      },
      {
        test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
        loader: "url-loader?limit=10000&mimetype=application/octet-stream",
      },
      {
        test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
        loader: "file-loader",
      },
      {
        test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
        loader: "url-loader?limit=10000&mimetype=image/svg+xml",
      },
    ],
  },
}

步驟3:在main.js中引入Bootstrap CSS

在你的main.js文件(或者是你的進口文件)中,引入Bootstrap CSS:

import App from "./app.jsx"
import Bootstrap from "bootstrap/dist/css/bootstrap.css"

步驟4:在app.jsx中引入React Bootstrap

最後,在您的app.jsx中,導入React Bootstrap組件:

import React from "react"
import ReactDOM from "react-dom"
import { Button } from "react-bootstrap"

const buttonsInstance = <Button>Click me!</Button>

ReactDOM.render(buttonsInstance, document.getElementById("here"))

HTML設定

別忘了附上一個帶有適當ID的div,以及bundle.js

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React</title>
  </head>
  <body>
    <div id="here"></div>
    <script src="bundle.js"></script>
  </body>
</html>

這就完成了!如果有任何問題,歡迎隨時向我提問。

如何成為一個好的顧問?

我曾在一家大型澳洲科技公司擔任軟體工程師。雖然我聰明、擁有技能且我全心全意,但這些品質單獨存在並不足以讓一個人成為成功的顧問。幸運的是,經過與經驗豐富的教練諮詢後,我整理出了一些深刻的建議。以下是我學到的三個等級的諮詢專業知識:

第一等級

在基礎等級上,你擁有一種特定的技能,你比其他人更懂。例如,我專精於 JavaScript 前端開發,我對此知識比我的客戶公司的員工更瞭解,而這公司恰好是全球最大的遊戲公司。他們尋求你的服務是因為你可以提供的獨特技能。然而,這種等級的工作對你來說並不理想的長期工作。錯誤將不可避免地發生,使得維持專業的第一印象變得挑戰性。隨著時間的推移,你將與具有相似技能的其他百萬人口變得容易混淆。你的貢獻變得有限,客戶支付給你的和你提供的價值之間的差距變得狹窄。

第二等級

在資深等級上,你通過利用多種技能為客戶提供重大價值。請記住,我們是人,而不是機器;我們都應該擁有多種才能。從你之前的客戶經驗中學習,對於當前的挑戰,你可以提供獨特的視角,讓你區別於客戶的內部團隊。你知道什麼有效,什麼無效,了解客戶喜歡或不喜歡,知道客戶和諮詢公司真正需要什麼。文化意識可以在建立信任方面長期有效。

第三等級

在最高等級上,你起著受信任的顧問的作用,就像國王的密友一樣。即使國王可能不喜歡聽到事實,你也有責任告訴他。如果有任何事情出錯,從客戶的角度來看,你將被追究責任,因為人們不太可能責怪自己或承認他們是錯的。你不必親自喜歡客戶,但你必須關心他們。理解他們的動機,並以同情之心推薦對公司最好的事情。愛可能是一個強烈的詞,但它有助於人性化你的業務方法。你的關注點不僅僅在於你的成功;你也關心客戶的成功。當客戶獲勝,你也會獲勝。

最後的想法

達到最高等級的諮詢專業知識是困難的。要建立一個雙贏的局面,你必須不斷學習,並向你的客戶、你的諮詢公司和你自己提供高價值的技能。這將不會容易,且需要多年的奉獻,但這些指導方針將成為你諮詢旅程上重要的標誌。

在Swift中理解選項和驚嘆號

Swift是一種強類型語言,意味著所有變量都必須有一個定義的類型。

在Swift中,有一種特殊的類型叫做"Optional",它只能有兩種可能的值:

  1. 一個未設定的值,意味著它從未被設定,或者有人明確地將它設定為未設定的狀態,即,設定為nil的值。
  2. 一個設置為特定東西的值。

例如:

    var something = display.text

something的類型是什麼?我們並未指定此變量的類型,但是Swift可以從上下文中推斷出來。它將something設為和display.text同樣的類型。假設display.text的類型是String;那麼something將會是一個Optional String,即,它是一個可能包含String的Optional。

那麼您如何從Optional中提取一個字符串?您可以"解包"Optional,也就是說,您可以檢查它並取出相關的值,使用驚嘆號:

    var something = display.text!

現在,something的類型是String,而不是Optional。請注意,如果display.text的值是nil,那麼您的程式將會崩潰!

在Objective-C中,.h和.m檔案之間的連接

當你首次在Xcode中打開一個Objective-C專案,.h和.m檔案可能會讓你感到困惑。理解這些簡單的連接以及背後的隱藏程式碼是很重要的。

這些檔案被用來分離類別的公開和私有部分。.h檔案充當你的類別的公開宣告的標頭檔案,功能就像一個API,而.m檔案則包含私有的實現。

當你需要從其他檔案中調用一個函數時,你只需匯入.h檔案來做參考。例如,

    #import <Foundation/Foundation.h>

在.h檔案中,你可以宣告類別的公開@property屬性,可以從外部訪問:

    @property (strong, nonatomic) NSString *something;

在此,@property是一個指向其類別為NSString的對象的指標。所有对象都居住在堆中,所以我们需要星號(*)。另外,"strong"的意思是"我將這個屬性設置為nil之前,保持此對象在記憶體中。" "Nonatomic"的意思是"這個屬性的訪問不是線程安全的;" 否則,編譯器將生成鎖定程式碼。

在.m檔案中,這個屬性的"取值方法"和"設值方法"會被自動地在背後生成,使得@property實例可訪問:

    @synthesize something = _something;
    - (NSString *) something
    {
      return _something;
    }
    - (void)setSomething:(NSString *)something
    {
      _something = something;
    }

請注意,默認情況下,支持變數的名稱與屬性的名稱相同,但在前面有一個下劃線。除非你想覆寫方法並做一些不同的事情,否則你不需要寫上述程式碼。

當你創建一個新方法,你需要將聲明放在.h檔案中:

    - (int)newMethod:(ArgType *)arg;

然後在你的.m檔案中寫實際的細節。

    - (int)newMethod:(ArgType *)arg
    {
      int num = 0;
      // 方法中的某些東西...
      return num;
    }

此外,對於私有宣告,你可以像這樣將它們包含在.m檔案中:

    @interface Something()
    // 私有宣告...
    @end

最後,當你第一次讀別人的程式碼時,你只需要查看.h檔案來獲取專案的概述。如果需要深入了解細節,那就看.m檔案。

了解上述的基本概念將使你開始理解其餘的程式碼。:D

在AWS Ubuntu實例上安裝Hadoop

第一步: 在AWS上創建一個Ubuntu 14.04 LTS實例。

第二步: 連接到該實例。

chmod 400 yourKey.pem
ssh -i yourKey.pem ubuntu@your_instance_ip

第三步: 安裝Java。

sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java6-installer
sudo update-java-alternatives -s java-6-oracle
sudo apt-get install oracle-java6-set-default

第四步: 添加一個Hadoop用戶。

sudo addgroup hadoop
sudo adduser --ingroup hadoop hduser

第五步: 為免密碼登錄創建一個SSH鍵。

su - hduser
ssh-keygen -t rsa -P ""
cat $HOME/.ssh/id_rsa.pub >> $HOME/.ssh/authorized_keys

第六步: 測試連接。

ssh localhost
exit

第七步: 下載並安裝Hadoop。

cd /usr/local
sudo wget [http://apache.01link.hk/hadoop/core/hadoop-1.2.1/hadoop-1.2.1.tar.gz](http://apache.01link.hk/hadoop/core/hadoop-1.2.1/hadoop-1.2.1.tar.gz)
sudo tar -xzvf hadoop-1.2.1.tar.gz
sudo mv hadoop-1.2.1 hadoop
chown -R hduser:hadoop hadoop
sudo rm hadoop-1.2.1.tar.gz

第八步: 更新.bashrc

su - hduser
vim $HOME/.bashrc

# 在文件末尾添加以下內容:
export HADOOP_PREFIX=/usr/local/hadoop
export JAVA_HOME=/usr/lib/jvm/java-6-sun
unalias fs &> /dev/null
alias fs="hadoop fs"
unalias hls &> /dev/null
alias hls="fs -ls"
export PATH=$PATH:$HADOOP_PREFIX/bin

然後用:wq保存並執行.bashrc

source ~/.bashrc

第九步: 配置Hadoop,以hduser身份登錄。

cd /usr/local/hadoop/conf
vim hadoop-env.sh

# 在文件中添加以下行:
export JAVA_HOME=/usr/lib/jvm/java-6-oracle
export HADOOP_CLASSPATH=/usr/local/hadoop

使用:wq保存並退出。

第十步: 為Hadoop創建一個臨時目錄。

exit
sudo mkdir -p /app/hadoop/tmp
sudo chown hduser:hadoop /app/hadoop/tmp
sudo chmod 750 /app/hadoop/tmp

第十一步: 添加配置段落。

su - hduser
cd /usr/local/hadoop/conf
vim core-site.xml

# 將以下內容放在<configuration> ... </configuration>標籤之間:

在這裡插入您的Hadoop配置。

# 使用 :wq保存並退出

如有需要,請繼續配置您的其他文件。

第十二步: 格式化HDFS。

/usr/local/hadoop/bin/hadoop namenode -format

第十三步: 啟動Hadoop。

/usr/local/hadoop/bin/start-all.sh

第十四步: 檢查所有進程是否正在運行。

jps

第十五步: 要停止Hadoop,輸入以下命令:

/usr/local/hadoop/bin/stop-all.sh

第十六步: 要再次啟動Hadoop。

/usr/local/hadoop/bin/start-all.sh

你現在已經準備好開始了!祝你玩得開心 :)

在 Mac OS X 上安裝 MongoDB

首先,安裝 Homebrew,這是 OS X 缺少的套件管理工具:

> ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

接著,更新公式:

> brew update

然後,安裝 MongoDB:

> brew install mongodb

要讓 launchd 在登入時開始 MongoDB,執行:

> ln -sfv /usr/local/opt/mongodb/*.plist ~/Library/LaunchAgents

要立即加載 MongoDB,執行:

> launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mongodb.plist

或者,如果你不想或不需要 launchctl,你可以簡單地執行:

> mongod --config /usr/local/etc/mongod.conf

同時,創建數據目錄:

> sudo mkdir -p /data/db

不要忘記更改權限:

> sudo chown "$(whoami)" /data/db

最後,啟動您的數據庫:

> mongod

啟用 OS X El Capitan 的自動登錄

問題

我剛剛進行了 OS X El Capitan 的全新安裝。我試圖啟用自動登錄,但是它仍然被鎖定。這讓我感到困惑。

解決方案

  1. 前往系統偏好設定並選擇安全與隱私權。為磁盤關閉FileVault。
  2. 導航到使用者與群組並點擊更改密碼
  3. 我選擇使用另一個密碼而不是使用我的 iCloud 密碼來登錄並解鎖這台Mac。
  4. 我設定了我的新密碼。
  5. 我點擊了登錄選項並為我的帳戶啟用自動登錄。

耶,它成功了!

Ember注入控制器

我遇到的問題:

在將我的Ember專案更新到1.13.5版本後,我在瀏覽器控制台中收到以下警告:

_棄用警告: Controller#needs 已被棄用。請改用 Ember.inject.controller() 。_

然而,我找不到任何關於如何實現新語法的文檔。

解決方案:

雖然它在Ember文檔中被標記為私有方法,但你可以選擇“私有”複選框來查看它。

使用Ember.inject.controller()有兩種方式:指定和不指定控制器名稱。

_應用程序.貼文控制器 = Ember.控制器.extend({ 文章: Ember.inject.控制器() });_

當你不指定控制器的名稱時,Ember會使用屬性名來查找,例如:

文章: Ember.注入.控制器('文章').

只有在屬性名稱和控制器名稱不同的情況下,你才需要指定控制器名稱。

_應用程序.貼文控制器 = Ember.控制器.extend({ 我的帖子: Ember.注入.控制器('文章') });_

這樣,您就可以成功地將您的專案更新以符合新的Ember指南。

在越南河內可以做的有趣事情

我的志向是環遊世界,雖然我意識到這可能有點過於雄心勃勃。

我在軟件工程中學到的一個重要課程是如何管理復雜性。通過把一個大挑戰分解成小而更好管理的部分,我們可以一步一步地完成有意義的目標。到越南週末度假就是一種簡單的快樂,不需要使用年假。

以下是一些在河內可以做的有趣事情:

下龍灣皮划艇 - 我的Instagram照片可能有多層濾鏡,但下龍灣的風景無需任何Photoshop就如明信片般美麗。雖然從城市出發需要四小時,但這個聯合國教科文組織世界遺產非常值得。皮划艇是我最喜歡接近壯觀的石灰石形成的方式。如果你去,記得帶一個防水袋來保護你的iPhone,以防你掉入水中。

自然奇觀 -東天宮洞 - 經過數千年風和水的塑造,東天宮洞令人驚嘆。用點想像力,你可能會在五彩斑斕的石筍中看到一條龍,一頭獅子,甚至一種乳房形狀的形成。有趣的是,一些迷信的女性在該岩石前祈福以求母乳充足。

在夜市導航 - 這種體驗既奇妙又厲害。在中秋節時,我參觀了繁華的夜市,但我也發現自己陷入群眾中。街上似乎每個人都有一個冰淇淋,所以我也買了一個。薄荷味的味道像牙膏,但在潮濕的熱夜裡很提神。在摩托車繁多的河內過馬路是一項真正的挑戰。無論紅燈還是綠燈,人們都在移動。成功地在來自所有方向的汽車,摩托車和手推車中穿過街道需要勇氣。謝天謝地,我安然無恙。

享受街頭美食 - 如果你敢於冒險,一定要準備品嚐各種當地美食。當我在那裡的時候,我試圖記住食物的越南名稱,但現在我回家了,它們已經從我的記憶中消失了。儘管語言聽起來很有旋律,我仍然無法理解其細膩的語調。

蛋咖啡 - 在你試過之前不要嘲笑它;它並不像聽起來那麼令人不悅。越南傳統的蛋咖啡(Cà Phê Trứng)主要在河內能找到。感謝當地的導遊,我在一家隱藏在樓上的咖啡店品嚐了這種飲料,對於遊客和本地人來說價格差不多。作為一名咖啡愛好者,我必須再次參觀歷史悠久的咖啡店品嚐那著名的煉乳咖啡——甜與苦的完美融合。

參觀和勞監獄博物館 - 讓我澄清一下,我沒做錯什麼!我參觀了法式的聖若瑟主教座堂後,參觀了和勞監獄博物館。我一直都對人性的黑暗面,如折磨和懲罰,感到著迷。反思歷史,我感到幸運能在沒有壓迫性政治政權和主要衝突的時代和地方生活。越南戰爭不僅僅是電影主題,它是一個建立在不明確政治理由上的真實歷史事件。每個士兵都有一個家庭,每個死亡都帶給他們悲痛。那一刻,我發現自己想念我的伴侶,並希望她持續安全。

所以,現在是時候開始規劃你的旅行了。河內有那麼多可以看和做的事情,我差點錯過回家的飛機。我打算繼續探索世界並看看世界可以提供什麼。迫不及待想要進行下一次冒險!如果你提早預定,你甚至可能找到一些很好的優惠。