#
標志一、只會踏踏實實地做具體的工作
踏踏實實地做具體工作,這沒有錯。但只會這樣那錯就大了,因為這永遠只是新手的方式,僅靠這個,永遠也成不了高手。甘心一輩子本本分分只當個菜鳥,到頭來,肯定連菜鳥也做不成,現在的職場,逆水行舟,原地不動,早晚被浪打翻。
標志二、不會踏踏實實地工作
年輕人喜歡幻想,本身也沒錯。但若是一天到晚光幻想,那就麻煩了。脫離了現實,好高騖遠,白日做夢,眼高手低……漫步云端的感覺是不錯,但夢醒時分,從云上跌落粉身碎骨的時候,就追悔莫及了。
標志三、瞧不起上司
受過高等教育的人都清高,別人不如自己的地方很容易放在眼里,并嗤之以鼻,尤其是對領導。讓不如自己的人來領導自己,實在不公平。但是,領導之所以是領導,就有原因,不管合理不合理都存在了。也許他學識不行,也許能力不行,但他贏可能就贏在關系上了,可能就贏在心機上了,好的也好,壞的也罷,都是實實在在存在的現象。
標志四、崇拜上司
相比起剛才的這種行為,對上司盲目崇拜,則更顯得幼稚。對上司的話全盤接受,無條件服從,缺乏了起碼的分析能力,最終會讓你在職場中迷失自我。
標志五、容易被激發、被感動、被忽悠
有些人比較感性,我本人也是這樣。對于領導一些比較有煽動性東西,難以抵制,很容易用頭腦發熱。但無論如何,事后一定要冷靜思索思索,站在不同的角度來考慮考慮問題,切莫一時意氣用事。
標志六、甘當云梯默默無聞
甘當云梯,默默無聞,這本是一種很高尚的情懷。在如今更是難得。但難得歸難得,天不佑此類人,生活不助此類人,時代更是難容此類人。對這種人,只能說,老兄,別那么單純了。
標志七、習慣忍讓
喜歡爭斗的人讓人厭惡,但現在的職場上,也只是這種人才得勢。人善被人欺,習慣忍讓,別人會覺得你好欺負,這已經成為現在職場上的一種思維定勢了。誰也打不破它。
標志八、鋒芒畢露
有人則相反,不忍不讓,鋒芒畢露。這也不好,這樣會樹敵太多,而且太容易讓人看透,很容易中了別人的招兒。適當的時候露露鋒芒,展示一下自己的立場就可以了,大多數的情況,還是應該韜光養晦的。
標志九、排斥關系
近幾年來,新興起一門學問,叫做關系學。這里面學問可大了,大到關系職場中的方方面面。可有人就是排斥它,認為靠自己的打拚就已經足夠了。其實,職場不比學術,不是把自己關在實驗室里就能出成果的,閉門造車,最終自食苦果。
標志十、知無不言言無不真
對別人什么都說,而且什么話都說真的,這很誠實,但太不成熟了。職場上混,就跟下棋一樣,盡可能地對方的心理,而不是盡可能地讓別人了解自己的心理。道理很淺顯。
如果你希望用 JUnit 來測試一些性能問題,那么 JUnitBenchmark 可以幫到你,主要特性:
package com.paul;
import com.carrotsearch.junitbenchmarks.AbstractBenchmark;
import com.carrotsearch.junitbenchmarks.BenchmarkOptions;
import javolution.text.TextBuilder;
import org.junit.Test;
/**
* Benchmark for String concatenation. Compares StringBUilder (JDK) and
* TextBuilder (Javolution).
*/
public class StringConcatenationBenchmark extends AbstractBenchmark {
public static final long LOOPS_COUNT = 10000000;
@Test
@BenchmarkOptions(benchmarkRounds = 3, warmupRounds = 1)
public void stringBuilderBenchmark() {
StringBuilder builder = new StringBuilder();
for (long i = 0; i < LOOPS_COUNT; i++) {
builder.append('i').append(i);
}
System.out.println(builder.toString().length());
}
@Test
@BenchmarkOptions(benchmarkRounds = 3, warmupRounds = 1)
public void textBuilderBenchmark() {
TextBuilder builder = new TextBuilder();
for (long i = 0; i < LOOPS_COUNT; i++) {
builder.append('i').append(i);
}
System.out.println(builder.toString().length());
}
}
Maven依賴:
<dependency>
<groupId>javolution</groupId>
<artifactId>javolution</artifactId>
<version>5.4.5</version>
</dependency>
結果顯示:
78888890
78888890
78888890
78888890
StringConcatenationBenchmark.stringBuilderBenchmark: [measured 3 out of 4 rounds, threads: 1 (sequential)]
round: 0.57 [+- 0.01], round.gc: 0.00 [+- 0.00], GC.calls: 33, GC.time: 0.02, time.total: 2.60, time.warmup: 0.90, time.bench: 1.70
78888890
78888890
78888890
78888890
StringConcatenationBenchmark.textBuilderBenchmark: [measured 3 out of 4 rounds, threads: 1 (sequential)]
round: 0.46 [+- 0.03], round.gc: 0.00 [+- 0.00], GC.calls: 14, GC.time: 0.14, time.total: 1.92, time.warmup: 0.55, time.bench: 1.38
所謂HTTP協議,就是TCP協議+狀態信息之類的字符。
資源:
http://www.tkk7.com/nokiaguy/category/38517.html
/**
* SimpleHttpServer.java
*/
import java.io.*;
import java.net.*;
import java.util.StringTokenizer;
/**
* 一個簡單的用 Java Socket 編寫的 HTTP 服務器應用, 演示了請求和應答的協議通信內容以及
* 給客戶端返回 HTML 文本和二進制數據文件(一個圖片), 同時展示了 404, 200 等狀態碼.
* 首先運行這個程序,然后打開Web瀏覽器,鍵入http://localhost,則這個程序能夠顯示出瀏覽器發送了那些信息
* 并且向瀏覽器返回一個網頁和一副圖片, 并測試同瀏覽器對話.
* 當瀏覽器看到 HTML 中帶有圖片地址時, 則會發出第二次連接來請求圖片等資源.
* 這個例子可以幫您理解 Java 的 HTTP 服務器軟件是基于 J2SE 的 Socket 等軟件編寫的概念, 并熟悉
* HTTP 協議.
* 相反的用 Telnet 連接到已有的服務器則可以幫忙理解瀏覽器的運行過程和服務器端的返回內容.
*
* <pre>
* 當用戶在Web瀏覽器地址欄中輸入一個帶有http://前綴的URL并按下Enter后,或者在Web頁面中某個以http://開頭的超鏈接上單擊鼠標,HTTP事務處理的第一個階段--建立連接階段就開始了.HTTP的默認端口是80.
* 隨著連接的建立,HTTP就進入了客戶向服務器發送請求的階段.客戶向服務器發送的請求是一個有特定格式的ASCII消息,其語法規則為:
* < Method > < URL > < HTTP Version > <\n>
* { <Header>:<Value> <\n>}*
* <\n>
* { Entity Body }
* 請求消息的頂端是請求行,用于指定方法,URL和HTTP協議的版本,請求行的最后是回車換行.方法有GET,POST,HEAD,PUT,DELETE等.
* 在請求行之后是若干個報頭(Header)行.每個報頭行都是由一個報頭和一個取值構成的二元對,報頭和取值之間以":"分隔;報頭行的最后是回車換行.常見的報頭有Accept(指定MIME媒體類型),Accept_Charset(響應消息的編碼方式),Accept_Encoding(響應消息的字符集),User_Agent(用戶的瀏覽器信息)等.
* 在請求消息的報頭行之后是一個回車換行,表明請求消息的報頭部分結束.在這個\n之后是請求消息的消息實體(Entity Body).具體的例子參看httpRequest.txt.
* Web服務器在收到客戶請求并作出處理之后,要向客戶發送應答消息.與請求消息一樣,應答消息的語法規則為:
* < HTTP Version> <Status Code> [<Message>]<\n>
* { <Header>:<Value> <\n> } *
* <\n>
* { Entity Body }
* 應答消息的第一行為狀態行,其中包括了HTTP版本號,狀態碼和對狀態碼進行簡短解釋的消息;狀態行的最后是回車換行.狀態碼由3位數字組成,有5類:
* 參看:HTTP應答碼及其意義
*
* 1XX 保留
* 2XX 表示成功
* 3XX 表示URL已經被移走
* 4XX 表示客戶錯誤
* 5XX 表示服務器錯誤
* 例如:415,表示不支持改媒體類型;503,表示服務器不能訪問.最常見的是200,表示成功.常見的報頭有:Last_Modified(最后修改時間),Content_Type(消息內容的MIME類型),Content_Length(內容長度)等.
* 在報頭行之后也是一個回車換行,用以表示應答消息的報頭部分的結束,以及應答消息實體的開始.
* 下面是一個應答消息的例子:
* HTTP/1.0 200 OK
* Date: Moday,07-Apr-97 21:13:02 GMT
* Server:NCSA/1.1
* MIME_Version:1.0
* Content_Type:text/html
* Last_Modified:Thu Dec 5 09:28:01 1996
* Coentent_Length:3107
*
* <HTML><HEAD><TITLE></HTML>
*
* 在用Java語言實現HTTP服務器時,首先啟動一個java.net.ServerSocket在提供服務的端口上監聽連接.向客戶返回文本時,可以用PrintWriter,但是如果返回二進制數據,則必須使用OutputStream.write(byte[])方法,返回的應答消息字符串可以使用String.getBytes()方法轉換為字節數組返回,或者使用PrintStream的print()方法寫入文本,用write(byte[])方法寫入二進制數據.
*
* </pre>
* @author 劉長炯
* @version 1.0 2007-07-24 Sunday
*/
public class SimpleHttpServer implements Runnable {
/**
*
*/
ServerSocket serverSocket;//服務器Socket
/**
* 服務器監聽端口, 默認為 80.
*/
public static int PORT=80;//標準HTTP端口
/**
* 開始服務器 Socket 線程.
*/
public SimpleHttpServer() {
try {
serverSocket=new ServerSocket(PORT);
} catch(Exception e) {
System.out.println("無法啟動HTTP服務器:"+e.getLocalizedMessage());
}
if(serverSocket==null) System.exit(1);//無法開始服務器
new Thread(this).start();
System.out.println("HTTP服務器正在運行,端口:"+PORT);
}
/**
* 運行服務器主線程, 監聽客戶端請求并返回響應.
*/
public void run() {
while(true) {
try {
Socket client=null;//客戶Socket
client=serverSocket.accept();//客戶機(這里是 IE 等瀏覽器)已經連接到當前服務器
if(client!=null) {
System.out.println("連接到服務器的用戶:"+client);
try {
// 第一階段: 打開輸入流
BufferedReader in=new BufferedReader(new InputStreamReader(
client.getInputStream()));
System.out.println("客戶端發送的請求信息:\n***************");
// 讀取第一行, 請求地址
String line=in.readLine();
System.out.println(line);
String resource=line.substring(line.indexOf('/'),line.lastIndexOf('/')-5);
//獲得請求的資源的地址
resource=URLDecoder.decode(resource, "UTF-8");//反編碼 URL 地址
String method = new StringTokenizer(line).nextElement().toString();// 獲取請求方法, GET 或者 POST
// 讀取所有瀏覽器發送過來的請求參數頭部信息
while( (line = in.readLine()) != null) {
System.out.println(line);
if(line.equals("")) break;
}
// 顯示 POST 表單提交的內容, 這個內容位于請求的主體部分
if("POST".equalsIgnoreCase(method)) {
System.out.println(in.readLine());
}
System.out.println("請求信息結束\n***************");
System.out.println("用戶請求的資源是:"+resource);
System.out.println("請求的類型是: " + method);
// GIF 圖片就讀取一個真實的圖片數據并返回給客戶端
if(resource.endsWith(".gif")) {
fileService("images/test.gif", client);
closeSocket(client);
continue;
}
// 請求 JPG 格式就報錯 404
if(resource.endsWith(".jpg")) {
PrintWriter out=new PrintWriter(client.getOutputStream(),true);
out.println("HTTP/1.0 404 Not found");//返回應答消息,并結束應答
out.println();// 根據 HTTP 協議, 空行將結束頭信息
out.close();
closeSocket(client);
continue;
} else {
// 用 writer 對客戶端 socket 輸出一段 HTML 代碼
PrintWriter out=new PrintWriter(client.getOutputStream(),true);
out.println("HTTP/1.0 200 OK");//返回應答消息,并結束應答
out.println("Content-Type:text/html;charset=GBK");
out.println();// 根據 HTTP 協議, 空行將結束頭信息
out.println("<h1> Hello Http Server</h1>");
out.println("你好, 這是一個 Java HTTP 服務器 demo 應用.<br>");
out.println("您請求的路徑是: " + resource + "<br>");
out.println("這是一個支持虛擬路徑的圖片:<img src='abc.gif'><br>" +
"<a href='abc.gif'>點擊打開abc.gif, 是個服務器虛擬路徑的圖片文件.</a>");
out.println("<br>這是個會反饋 404 錯誤的的圖片:<img src='test.jpg'><br><a href='test.jpg'>點擊打開test.jpg</a><br>");
out.println("<form method=post action='/'>POST 表單 <input name=username value='用戶'> <input name=submit type=submit value=submit></form>");
out.close();
closeSocket(client);
}
} catch(Exception e) {
System.out.println("HTTP服務器錯誤:"+e.getLocalizedMessage());
}
}
//System.out.println(client+"連接到HTTP服務器");//如果加入這一句,服務器響應速度會很慢
} catch(Exception e) {
System.out.println("HTTP服務器錯誤:"+e.getLocalizedMessage());
}
}
}
/**
* 關閉客戶端 socket 并打印一條調試信息.
* @param socket 客戶端 socket.
*/
void closeSocket(Socket socket) {
try {
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
System.out.println(socket + "離開了HTTP服務器");
}
/**
* 讀取一個文件的內容并返回給瀏覽器端.
* @param fileName 文件名
* @param socket 客戶端 socket.
*/
void fileService(String fileName, Socket socket)
{
try
{
PrintStream out = new PrintStream(socket.getOutputStream(), true);
File fileToSend = new File(fileName);
if(fileToSend.exists() && !fileToSend.isDirectory())
{
out.println("HTTP/1.0 200 OK");//返回應答消息,并結束應答
out.println("Content-Type:application/binary");
out.println("Content-Length:" + fileToSend.length());// 返回內容字節數
out.println();// 根據 HTTP 協議, 空行將結束頭信息
FileInputStream fis = new FileInputStream(fileToSend);
byte data[] = new byte[fis.available()];
fis.read(data);
out.write(data);
out.close();
fis.close();
}
}
catch(Exception e)
{
System.out.println("傳送文件時出錯:" + e.getLocalizedMessage());
}
}
/**
* 打印用途說明.
*/
private static void usage() {
System.out.println("Usage: java HTTPServer <port>\nDefault port is 80.");
}
/**
* 啟動簡易 HTTP 服務器
* @param args
*/
public static void main(String[] args) {
try {
if(args.length != 1) {
usage();
} else if(args.length == 1) {
PORT = Integer.parseInt(args[0]);
}
} catch (Exception ex) {
System.err.println("Invalid port arguments. It must be a integer that greater than 0");
}
new SimpleHttpServer();
}
}
作者:何云隆
網易上斬建通寫的很好的文章分享下
大道至簡,越是根源和基本的問題,道理實際上越簡單。關于如何做人、做事、做管理的書很多,我看得不多,但是我覺得這些書更多是側重技術和實現細節上的,而很少從人的思想和觀念去講。實際上,從根本上去說,如何做人做事是世界觀的問題,也是一個哲學話題。很多人和我一樣,已經到了快30的年紀,是需要去思考一下應該如何做人如何做事的,也需要一套簡單、有效、完整的體系來指導自己,而這套體系將是讓自己安身立命于這個世界的基石。
職場上如何做人
關于在職場上如何做人,我只謹記兩個字--服務。你要把自己當成一個品牌去愛惜,當成一家公司去經營,你要牢牢記住你之所以能在一家公司立足,靳建通是因為公司需要你的服務。我們經常會抱怨某某銀行的工作人員服務態度不好、某某商品的售后服務不好,但從來不去思考自己對公司的服務好不好?公司的任務有沒有如期完成,是不是沒有哪個任務是提前完成的,幾乎所有任務都拖到“最后期限”?工作完成的夠不夠徹底,是不是答復已經完成了,結果日后又出狀況?完成后有沒有向上級反饋,是不是等到上級問你完成了沒有,你才去報告進度?拖延的任務有沒有持續跟進,是不是上級不追了這個任務最后就不了了之了?上面這些問題我都是反復遇見的,其實根本原因就是沒有意識到你其實在做一項服務,你在公司的發展前景,全都取決你對公司的服務夠不夠好。設想一下,如果交給你的每件事情都可以迎刃而解、化險為夷,讓人感覺穩妥、放心、踏實,你自然會收到更多更重要的“訂單”。當你的單多到你忙不過來的時候怎么辦?招下屬啊,呵呵,恭喜你,你已經是領導了。反之,如果給你一件事情你要拖延,給你一件事情你辦不好,給你一件事情就沒了下文了,讓人不放心,久而久之你就“無單可做”了,那么公司重新請一個人就可以了,干嘛非要用你呢?
服務不光是對于自己供職的公司,對于公司的客戶也是一樣的。每一次去客戶那里出差前,我總是再三叮囑自己,我此次之行是為客戶做服務的,是去為客戶解決問題的。這個心態非常重要,我們做軟件系統的,去見客戶除了做演示、做培訓,很多時候就是處理現場問題,難免遇到客戶對系統的投訴,比如系統速度慢、bug多等問題。當你有了這樣的心態,你就會謙虛地接受客戶的批評,細致地記錄客戶提出的問題,然后一項項地去思考如何解決,并且應該給客戶一份詳盡的解決方案。有了這樣的心態,你會不自覺地、自然而然地與客戶站在一邊,讓他感到你是在為他著想,幫助他去解決問題的。在你面對客戶時,應該有這樣一個虔誠的信念:我是去為客戶服務的,為他解決他所解決不了的問題的。如果你沒有這樣的心態,面對投訴很可能就會產生厭煩,而且容易為自己的問題進行辯解。這種做法給客戶的感覺就是你竭力在證明你是對的他是錯的,這樣你就站在客戶的對面了。
在客戶面前的表現對你的職場發展也是非常有好處的,尤其是接觸到一些跨國企業時,你優良的職業素養會為你贏來客戶的認同與尊敬。這樣當你哪天希望尋找更高的平臺,只要放個口風出去,立即就會有Offer了。所以認真服務好客戶只賺不賠。
職場上如何做事
關于如何做事,也有很多的理論,比如要事第一,把事情分為緊急、重要等等,這些我都不討論了,我只就我自己的經驗來談一談。
對于如何做事,我也恪守一個信條:不焦不燥,把心沉下去,將注意力集中于要解決的問題上。
我看過這樣一個故事,是說從前有一戶人家,家里的菜園中有一塊大石頭,經常會有人不小心撞到;兒子就問:為什么不把他挖走呢?他的爸爸說:這個石頭爺爺的時代就有了,就是因為它那么大,不好挖才一直在那里;又過了一代人,家里的一個媳婦實在受不了,就扛著鋤頭去挖了,她已經做好了心理準備要挖幾天的時間,結果一天就挖完了... ...原來那個石頭的中間是空的。
我們遇到的很多事情也是一樣的,看似棘手、難以解決,實際上只要你認真地去分析、去思考,然后放手去做,往往并沒有想象中的那么困難。你需要克服心中的頑石。我發現一些人遇到問題后,很輕易地就會說:這個我做不了,這個實現不了,這個我也沒辦法。其實就好像看到這塊大石頭一樣,被它的“外表”嚇住了,而放棄了應有的行動。
而且我發現了一個有趣的現象,不管多么困難的問題,只要你沉下心去思考如何解決,就好像在冥冥之中上蒼在看著你一樣,當你拼到最后就要打算認輸的時候,往往會出現新的契機和方法。
另外,我發現有些人遇到問題的時候,他想的是這件事如何困難如何難以完成,這樣的思維方式是有問題的,是一種保守且退縮的思維;遇到問題的時候,想的應該是如何才能夠完成。我一般采取這樣幾個步驟:1、列出所有的可能性;2、分析各種可能性;3、選擇一種實現起來最簡單、快速的可能性;4、去實現。
除此以外,我發現一些人在做事的時候,會以“這樣做很麻煩”來作為不采納方案的理由,而不是“這樣是否必要”或者“這樣是否更好”來作為標準,實際上“麻煩”應該是排在“是否必要”、“是否更好”后面進行考慮的。如果一種實現方式,雖然麻煩,但是很有必要,且對客戶來說更好,那么就算麻煩也要去做。但是程序員往往關心的是會不會很麻煩,是不是要修改很多地方,是不是給自己帶來很多工作量... ...告訴你,你關心的這些不是最重要的。
職場上如何做管理
和上面一樣,做管理也有很多的細節,我也都不談了,因為這些都是一本書一本書的講,而我覺得要簡單、有效、好操作,所以我也只說三點。
我覺得做好一個技術經理,只要下面的三點就好了:
1、德行
德行其實就是品德,簡單地講就是要善良、誠懇。最重要的,你做事的出發點要是好的,對別人是沒有壞心的。為什么說出發點一定要是好的呢?我們還是以服務客戶的例子來說,在為客戶解決問題的時候,如果我們的出發點是好的,是站在客戶一邊盡心盡力去為客戶解決問題的,那么即便由于方法、能力、條件等各方面的原因,事情搞砸了或者沒有做好,也很容易獲得客戶的理解和原諒。很可能的情形是,你就算做失敗了也一樣贏得客戶;相反,如果你的出發點是“省麻煩”,“趕緊交差了事”,“完成任務”,如果事情做成了也就算了,一旦失敗了,你看看客戶會怎么樣?告訴你,好的客戶會批評你、投訴你,因為他對你還有期望;更多的客戶是什么話也不說,直接換個供應商就是了,才懶得理你。記住永遠不要把客戶當成傻瓜,你是如何做事情的,客戶是很容易感受得到的。所以,面對和服務客戶沒有那么多的技巧,你不需要有多好的口才和魅力,也用不著忽悠和夸大其詞(我發現很多銷售人員都是這樣,你可以騙客戶一次,但就沒有第二次了),你只需要放下身段,兢兢業業地為客戶著想,設身處地地解決他的問題就可以。對待下屬也是一樣的,你對他的獎勵也好,懲罰也好,出發點一定要是好的。我對待下屬遵循的原則就是:我是在幫助你,幫你把工作做的更好,幫你獲得更大的提高,而不是說找你茬兒,跟你過意不去,或者是擠兌你壓迫你。德行是基本的,有一個好的德行,至少可以保證你的下屬不會討厭你。
2、敬業
如果有人問我,下屬和經理的區別是什么。我會告訴他:下屬等著別人交代事情做,經理想著還有哪些事情可以做。這其實是一個積極心態的問題,作為一個中層干部,你需要將公司的事情當成自己家的事情來處理,當你有這樣的心態,你就是再怎么加班都不會有怨言的,即便分文不取... (有誰見過給自己家裝修叫苦不迭的?)如果你可以長期保持這樣的狀態,你的這種獻身精神和敬業精神,會很輕易地感染你的下屬和你的同事,你會感覺到在公司左右逢源,而且你也會更有話語權,大家會更重視你的意見,同事和下屬也會對你報以更多的信任。當這種情況出現時,管理起下屬還會困難嗎?但需要注意的是,你的敬業精神不是說體現在無休止的加班上,工作異常繁忙、經常性加班其實是工作沒有做好的表現之一,加班只應該出現在緊急情況發生的時候,而不應該是一種常態。
3、技術
如果有人問我,技術人員和其他人員最大的區別是什么。靳建通我會告訴他:技術人員個個自以為是,認為別人的技術都不如自己。呵呵,可能大家不愛聽,但我觀察到的現象就是這樣的。很少有人愿意去讀別人的代碼,彼此都覺得寫得好爛。所以,如果想贏得技術人員的欽佩,你需要有壓倒性的技術能力。這個壓倒性的優勢,不是下屬70分,你80分,而是下屬70分,你要做到100分;下屬100分,你要做到150分。所以,缺乏技術能力的人去管理技術人員往往是吃力不討好的,可能下屬表面上服從你,心里根本不當你一回事兒,這樣管理起來就存在障礙了。當然,如果你的德行非常好,也非常敬業,技術就顯得不那么重要了;而如果你已經滿足了前面兩條,同時技術也很精湛,那自然是錦上添花了。
JeeSite是一個 開源的企業信息管理系統 基礎框架。主要定位于“企業信息管理”領域,可用作企業信息管理類系統、網站后臺管理類系統等。JeeSite是非常強調開發的高效性、健壯性和安全性的。
JeeSite是輕量級的,簡單易學,本框架以Spring Framework為核心、Spring MVC作為模型視圖控制器、Spring Data JPA + Hibernate作為數據庫操作層,此組合是Java界業內最經典、最優的搭配組合。前端界面風格采用了結構簡單、性能優良、頁面精致的Twitter Bootstrap作為前端展示框架。
JeeSite 已內置 一系列企業信息管理系統的基礎功能,目前包括兩大模塊,系統管理(SYS)模塊和內容管理(CMS)模塊。系統管理模塊,包括企業組織架構(用戶管理、部 門管理、區域管理)、菜單管理、角色權限管理、字典管理等功能;內容管理模塊,包括內容管理(文章、鏈接),欄目管理、站點管理、公共留言、文件管理、前 端網站展示等功能。
JeeSite提供了常用工具進行封裝,包括日志工具、緩存工具、服務器端驗證、數據字典、當前組織機構數據(用戶、區域、部門)以及其它常用小工具等。另外還提供一個基于本基礎框架的 代碼生成器 ,為你生成基本模塊代碼,如果你使用了JeeSite基礎框架,就可以很快速開發出優秀的信息管理系統。
為何選擇
- 使用 Apache License 2.0 協議,源代碼完全開源,無商業限制。
- 使用目前最主流的J2EE開發框架,簡單易學,學習成本低。
- 數據庫無限制,支持MySql、Oracle、SQL Server、H2等數據庫。
- 模塊化設計,層次結構清晰。內置一系列企業信息管理的基礎功能。
- 權限控制精密細致,對所有管理鏈接都進行權限驗證,可控制到按鈕。
- 提供基本功能模塊的源代碼生成器,提高開發效率及質量。
- 提供常用工具類封裝,日志、緩存、驗證、字典、組織機構等,常用標簽(taglib),獲取當前組織機構、字典等數據。
- 完全兼容目前最流行瀏覽器(IE6、IE7+、Firefox、Chrome)。
使用技術
1、Services相關
- Core Framework:Spring Framework 3.1。
- Security Framework:Apache Shiro 1.2。
2、Web相關
- MVC Framework:SpringMVC 3.1。
- Layout Decoration:SiteMesh 2.4。
- JavaScript Library:JQuery 1.7。
- CSS Framework:Twitter Bootstrap 2.0.4。
- JavaScript/CSS Compressor:YUI Compressor 2.4。
- Front Validation:JQuery Validation Plugin 1.9。
3、Database相關
- ORM Framework:Spring-Data-JPA 1.2、Hibernate 4.1。
- Connection Pool:BoneCP 0.7
- Bean Validation:Hibernate Validation 4.3.0。
- Cache:Ehcache 2.6。
4、Tools 相關
- Commons:Apache Commons
- JSON Mapper:Jackson 2.1
- Bean Mapper:Dozer 5.3.2
- Full-text search:Hibernate Search 4.2(Apache Lucene 3.6)、IK Analyzer 2012_u6中文分詞
- Log Manager:Log4j 1.2
安全考慮
- 開發語言:系統采用Java 語言開發,具有卓越的通用性、高效性、平臺移植性和安全性。
- 分層設計:(數據庫層,數據訪問層,業務邏輯層,展示層)層次清楚,低耦合,各層必須通過接口才能接入并進行參數校驗(如:在展示層不可直接操作數據庫),保證數據操作的安全。
- 雙重驗證:用戶表單提交雙驗證:包括服務器端驗證及客戶端驗證,防止用戶通過瀏覽器惡意修改(如不可寫文本域、隱藏變量篡改、上傳非法文件等),跳過客戶端驗證操作數據庫。
- 安全編碼:用戶表單提交所有數據,在服務器端都進行安全編碼,防止用戶提交非法腳本及SQL注入獲取敏感數據等,確保數據安全。
- 密碼加密:登錄用戶密碼進行SHA1散列加密,此加密方法是不可逆的。保證密文泄露后的安全問題。
- 強制訪問:系統對所有管理端鏈接都進行用戶身份權限驗證,防止用戶
快速體驗
- 具備運行環境:JDK1.6、Maven3.0、MySql。
- 修改src\main\resources\application.properties文件中的數據庫設置參數。
- 根據修改參數創建對應MySql數據庫。
- 運行bin\resresh-db\refresh-db.bat腳本,導入表結構及演示數據
- 運行bin\jetty.bat,啟動服務器(第一次運行,需要下載依賴jar包,請耐心等待)。
- 最高管理員,用戶名:thinkgem 密碼:admin
先把項目背景簡單說一下,項目A可以認為是在原有業務系統的基礎上衍生出來的新需求(派生的新業務),原有業務系統是一個比較大的系統,在公司也是一個拳頭產品,賣了幾十套,目前也有好幾個人在上面維護+二次開發+缺陷修復等(人力資源緊張)。早期公司高層只是說肯定要做這個項目,但由于人力資源的問題遲遲沒有決定要開工(還有一個重要原因是領導希望能夠簽下1-2個典型客戶再啟動項目A的開發),而僅僅是上銷售去那幾十家客戶那里兜售新業務,吹的天花亂墜的,比較市場有些競爭,需要先拉單子。這些事情是年中的事情。
等到下半年的時候,市場對這個新的業務反應比較強烈,已經有客戶說要看原型再簽合同,原因是競爭對手已經出原型了。而此刻,公司以為高層決定要即刻啟動項目開發,說先把原型做出來,限期一個月。而中層領導還是由于人手緊張,就隨便抽調了4個開發人員,一半是1年工作經驗以內的新手,就這樣匆忙上陣。由于人手有限、時間緊迫、業務需求雖然已經明確,但很多業務細節這4個開發人員都不清楚,只有一個懂業務的但也談不上精通。
項目計劃就定了一個月,基本上按天把計劃排好了,1個月后系統原型出來了。但比較粗糙,缺陷也比較多,設計基本沒有做,代碼質量也比較差。拿去客戶那里安裝后,客戶認為這個系統太粗糙了,【到客戶那里,客戶就不會認為這是個原型系統了】
至此,按常規項目管理的做法,應該重新梳理真實的客戶需求、業務流程和功能設計、架構設計、概要設計。。。。
但事情的發展卻不是這樣進行的。由于客戶迫切系統以周為單位看到項目的進展,于是領導決定就在原型系統上擴展和修改,其結果就是計劃制定后很難執行,變成了按周來排計劃,主要就是按客戶的需求來改。
好不容易在年底前把版本基本上穩定了,但只是業務流程和功能比較溫度,缺陷開始收斂了。
但元旦后到客戶現場安裝測試版本,客戶對此版本又提了很多需求變更和新模塊。此刻麻煩就比較大了,因為系統的架構靈活性比較差,改起來對原有代碼影響比較大,改動范圍大。于是又是時間緊張,又是工作量,剛把功能實現,客戶就開始催啥時候測試。缺陷一直居高不小,于是決定花2周時間專門修改缺陷。
到現在為止,開發基本完成了。但問題也比較突出:
系統的性能存在問題(有些模塊客戶的意見很大,但這個從技術上講,改動會比較大,不是1周能解決的)
系統的穩定性(與1相關)
功能的可用性(有些功能早期按照開發人員的思維來設計的,到客戶那里客戶提出新的想法,開發時把這種體驗需求壓住了,但在后續還是要改)
馬上要啟動二期的需求開發,這個更麻煩
---------------------
至此,整個項目風險還是比較大的,我總結有以下幾個原因:
1. 項目的目標、業務流程、大體需求是很明確的,但細節需求在項目中前期,整個項目組都是一知半解的,造成后續返工較大,客戶和開發人員包括公司領導對質量的意見都較大;
2. 項目從開始到現在領導和項目經理的分工不明確;由于人是湊起來的,大家之前沒有合作過不了解;
3. 原型系統出來后,項目經理大部分時間都去解決客戶的需求溝通和售前支持了,少部分時間在真正項目開發上;
4. 一直對項目的總體計劃和推進情況估計不足,造成項目計劃形同虛設,完全是開發人員做到哪算哪;
5. 中前期領導對這個項目不重視,等到元旦后發現問題比較嚴重,就臨時抽調人手進來協助,而剛進來的人一方面不是項目經理想要的人(仍然是新手),另外一方面由于系統的業務性比較強,新手加進來后1-2周內根本不起作用;
6. 測試工程師,派過來的2名測試工程師是后期加進來的,業務都不熟悉,培養的2周后才慢慢熟悉,而且在客戶現場,測試工程師根本應付不了客戶的問題,即客戶講的需求測試工程師根本不懂或不熟悉;
大致就這些吧。
第三話按照原計劃是要寫寫平常心的,因為飛躍計劃要交作業,所以就改為寫自己對項目管理的一些經驗總結,剛好前一段時間那些年我們一起追過的女孩很是流行,這一話的名字就叫做那些年我們一起做過的項目。
我的第一個項目是在2005年,那是一家市場占有率前三的本地化翻譯公司,公司的信息部門只有兩個人:老大和我,我們一起開發公司內部的協同辦公系統。要解決的問題很簡單:由于公司發展迅速,以前單純依靠紙質單據和郵件分派和追蹤任務已經越來越讓項目經理和財務不堪重負,迫切需要將這些工作給自動化。系統的技術架構也很簡單:
jsp+javabean+mysql。沒有專門的開發計劃,基本開發流程是這樣的:每周一我們訪談一個業務部門經理,了解他的需求,周中開發,開發中有任何問題都可以直接找業務經理,周五的時候系統上測試環境,再和業務經理坐到一起看一下是否滿足了他的需求。系統就一直這樣不緊不慢的開發著,老板辦公室就在我們身后,一有時間老板就會和我們一起使用該系統。整個開發過程只有一個細節讓我印象深刻,就是對任務估算工作量時,不管我估算多少,老大都會給我乘以3,一次要給業務表單增加一個字段,老大問我需要多長時間,我說不就是增加數據庫字段嗎10分鐘,結果老大給了我半天時間,老大說,增加字段確實只需要幾分鐘,但打開編輯器需要時間吧,集中注意力需要時間吧,改完了啟動系統測試需要時間吧,測試完了和業務經理確認需求需要時間吧,我們估算的是完成整個事情的時間而不僅僅是編碼的時間。
這個項目完成時獲得了公司上下的一致好評,從公司老板到業務經理,每個人都非常滿意,而讓我感到唯一遺憾的卻是身為IT人員竟然從來都沒有加過班。
回想起來,這個項目之所以成功固然是因為技術簡單和系統不復雜(我們甚至都不需要 SVN,完全依靠腳本同步代碼),但最重要的還是持續交付和持續的用戶反饋,老板和業務經理每周都能看到新功能的上線,這增強了他們的信心,同時反饋幾乎每天都在進行,并且他們很快都能看到這是否是他們想要的。
第二個項目在2006年,這一年我換工作了,因為當時我認為不加班的程序員不是好程序員。新公司在上地,是一家做協同辦公業務平臺的公司,最開始去的是項目部,一開始很為業務平臺這個概念著迷,因為當寫程序時最先不是寫代碼而是用代碼生成器生成代碼,并且生成完的代碼馬上可以運行!第一個項目是豐田公司的銷售管理系統,我們創新的使用了當時最熱的Ajax技術,我們完全是用技術熱情加上周末時間完成對原有功能的 Ajax增強,這個項目獲得了用戶極高的評價,因為當大多數web系統還在使用點擊 /刷新的方式進行交互時,我們卻可以直接拖拽完成操作了。如果在當時,我會認為是技術的創新讓項目獲得了成功,但是現在,我會用漸進式增強這個詞,即只有在完成用戶所需要的核心功能(什么叫核心功能,即缺少這個功能系統不能工作)后才開始對系統用戶體驗、性能進行漸進式優化。
第三個項目是在公司的平臺部,這里部門經理正準備對原有的業務平臺進行重寫,原先業務平臺的技術框架是:jsp+struts+ojb+sqlserver,新的技術框架定義為: ajax+freemarker+webwork+spring+hibernate。這讓我興奮,因為新的技術框架幾乎是當時最流行的技術。加部門經理共有三個開發人員(所以溝通一直不是問題),老大使用project來管理項目,每個人負責一個模塊,估算以周為單位,最初計劃是 5個月交付,功能直接就是老平臺的翻版換的只是技術實現,但是 5個月后進行測試和項目試用時卻發現了大量缺陷,最后幾乎用了半年時間才將缺陷收斂,產品發布計劃延期半年。回顧這個項目,需求沒有進行詳細的分解和評審導致實現與需求不一致 似乎是項目延期最重要的問題,然而更深的思考卻是我們需不需因為技術原因開始新產品的開發,在不影響用戶使用的情況下對原業務平臺進行漸進式增強是否更加合適。即我們在啟動項目時更多關注的應該是用戶價值(只有有用戶價值用戶才會買單公司才有收益)。
第四個項目是我負責的,這個項目幾乎是上一個項目的翻版,重寫公司的工作流產品:支持更多的工作流模式,更易集成的api和管理界面,唯一不同的是這個項目采用了很多敏捷里的實踐:持續集成、單元測試、站會、迭代,但這些實踐均不影響這個項目最終的失敗。同樣是該不該重寫這個項目的問題,在公司資金鏈緊張、時間要求緊、新產品相比競品沒有突出特性的情況下,這個項目從一開始就決定了失敗。如果沒有特別充足的理由就不要重寫產品,這幾乎成為我目前最重要的一條原則,尤其要從公司全局的角度看待產品不能局限在技術。現在,只要誰一說到要重寫產品,而給出的僅僅是技術原因,我就會兩股加緊,冷汗直流。在對項目完全負責的情況下,我另一點深刻感受就是人的重要性,對團隊中的每個人員,作為leader 你都需要知道他的需求是什么,沒有人愿意做機器人,在一次對某一技術方案簡單粗暴拍板后,一個核心技術人員流失了,這成了壓垮這個項目的最后一根稻草。
08年底去了一家新公司,新公司采用敏捷實踐。第一個項目很成功,幾乎是敏捷項目的一個成功范例,需求分析、迭代、持續集成、結對、客戶 showcase、持續交付,項目甚至提前半個月完成。唯一美中不足的是項目二期時新團隊由于一期文檔很少帶來了很多困擾。突出的感受是:團隊人員有了角色、有了分工也就有了流程。現在,到了一個新的部門或中心,第一件事情往往就是梳理項目開發流程,定義出每個人的角色,職責不清是互相埋怨之源。
第二個項目是咨詢項目,略去不表。第三個項目是分布式團隊,一部分團隊在國外,一部分團隊在國內,最開始一切順利,但在上線前一個月遇到了嚴重的性能問題,陷入了一片混亂當中,所有人都不知道我們離上線還有多遠,還有哪些工作需要完成,優先級都是什么,項目經理甚至自己都失去對整個項目的把控,她不知道項目上線究竟需要滿足什么條件,于是一次次在等待國外團隊優化后的測試結果,于是一次次的測試結果不滿意,于是項目在一次次的下周二上線的空頭承諾中成了整個公司的笑柄。這個項目回顧起來就是團隊遇到挫折時放棄了計劃,迭代沒有了,故事墻沒有了,所有人都在等待,而項目經理為了不讓開發人員被公司收回還不得不想一些優先級不高的任務給團隊完成裝著我們很忙。教訓就是,任何情況下都不能放棄計劃,計劃是項目之本。其他包括團隊能不分布式就不要分布式,如果必須分布式那么一定要從架構開發任務上進行隔離,盡量減少兩個團隊之間的交互(很多項目經理進入到部門之后推進項目制,其實也是同樣的原則,團隊大了就要拆解,產品代碼多了也要模塊化,盡量減少團隊之間、模塊之間的交互,做到能夠各自獨立演進和發布)。盡早進行實際環境的測試,越早越好。測試越早進行越好,測試環境越貼近產品環境越好,這一原則什么時候強調都不過分(我們上線前的測試才發現嚴重的性能問題)。
第三個項目是幸運的,因為他們有錢,能夠等待,在多等待了大半年后系統終于上線。而第四個項目就沒有這么走運了,這個項目是一個在線 saas CRM系統的重寫,而且有著強時間約束(如果半年不能交付,將錯過該系統客戶每年做預算的窗口期),看吧,又是重寫,又是時間約束,這幾乎總預示著它厄運難逃。表面上看項目是在一次中期的架構重寫中崩潰了,重寫耗去了團隊太多的時間,而由于對未知領域知識的不正確估算(需要學習)再次令項目雪上加霜,項目目標又不能變化,要在六個月后上線,但更深層的原因還是項目開始之前沒有決策正確,真的要重寫產品嗎?老產品確實界面很丑、一些功能沒有,但這些不能漸進式增強進行嗎,一定要重新開始嗎?重寫使用新團隊,他們對該業務領域并沒有經驗,過去系統遇到的坑他們不清楚,他們的計劃因為少考慮了一些情況是否顯得過于樂觀?這個項目的其他問題包括項目計劃一直沒有發生變化,盡管所有人都認為在規定日期到來之前不可能交付,但這個日期卻沒有發生變化。最后不得不說這是一個技術強大的團隊,一切都做到了自動化,甚至部署產品環境也是一鍵完成,但是這些在項目目標失敗的情況下顯得黯然失色。而客戶貸款做這個項目則讓很多團隊成員良心不安。
來到騰訊,來到soso,最重要的收獲是對運維有了新的認識,以前曾經認為devops就是自動化部署,全功能團隊,現在發現它關乎架構:一條搜索的badcase是否能夠很快找出錯誤的原因?是抓取失敗,是索引時丟失,還是相關性排序不好?關乎監控和報警,我們能否很快從監控中定位出原因?關乎組織結構,前臺開發,后臺架構,基礎架構,運維測試團隊都是分離的,如何協作才能使團隊合作的成本最低而整體利益最大化?
回顧往事,保爾柯察金說:如何才能不虛度光陰,只有為共產主義奮斗終身;柯景騰說:唯有沈佳宜讓我懷念;而我想說的是:
做任何項目之前一定要想清楚為什么要做這個項目,一定要想清楚這個項目的價值是對用戶和公司的(尤其需要跳出站到一個比較高的層次看項目),一定要想清楚項目的約束(時間約束、人員約束),不僅是項目開始之前要想,過程中要不斷回顧;;
項目任何時候都必須有計劃,對所有干系人透明;
項目一定是持續交付和持續反饋的,不允許黑盒出現;
測試和運維一定要盡早介入;
從每個團隊成員的角度出發關注所有人的利益實現共贏。
年輕時,不猶豫,年長時,不后悔。年輕時要盡早的給自己定位,是鳥就飛的更高,是魚就游得更快。
發揮自己的特長,有所專一,不能什么都會。根據別人的經驗為自己找方法。
趁自己還年輕,把想干的事都干了,只要對自己能力有提升的,別猶豫。不能等到年長時后悔當年
自己沒有干什么事,不能等到年老時再聊發少年狂。
年輕時,努力的探索自己,發掘自己,積極的上進,努力的學習,積攢技能,學習人事。
要努力學習,以開放積極的心態來面對困難與挑戰。
三十歲時,讓自己能夠獨當一面,能夠為人所用。跟著一群優秀的人合作共贏,積攢人脈,讓自己
變得更優秀。
四十歲時,讓優秀的人為自己工作,五十歲時,讓優秀的人變得更加優秀。
年輕時,積累自己的耐心,價值,能力,知識,創造,付出,原則
年輕時,靠的是努力。重點是學習如何成為一員有專業素養的精兵,找到立身之本的根。
年輕時,最困難在于要在最耐不住寂寞的年紀做耐得住寂寞的事。
或許某些努力看上去是無望的,但是不要放棄,堅持不懈怠,有傻×一樣的努力才有牛叉一樣的結果。
三十歲,靠的是實力。重點是學習如何成為一名有管理能力的猛將,要能獨擋一面。
這時,要將專業的深度,人格的成熟度,人情的練達度擰成自己的綜合實力。
四十歲,靠資歷。重點是學習如何成為一位有經營水平的名帥,建設枝繁葉茂的系統。
這時,你的經驗,資格,見識,榮譽都要上得了臺面。
五十歲,靠勢力。重點是學習如何成為一位成就組織的王者,培育眾木成林的勢力生態。
桃李滿天下,知交遍天下,關系滿天下。成為培育組織,保護組織,成長組織的人。
依靠以前鋪好的軌跡走自己的路。
年輕時跟優秀的人工作,三十歲跟優秀的人合作,四十歲找優秀的人為你工作,五十歲
努力是別人成為更加優秀的人。
年輕時可教,三十歲可用,四十歲有資格可捧,五十歲可敬。
五十歲的功德是自己成就的,是自己人生經驗財富的積累。
作者:鄒振文
初六的早晨,剛從老家回來,坐在出租屋的陽臺上,陽光燦爛,竟然是北京難得的好天氣。距離上次寫年終總結已經過去好久,打開博客,發現上次寫年終總結已經是四年前的事情。上次寫總結的時候還是在東直門溫暖的辦公室里,隨著年齡的增長,覺得時間過得越來越快,四年時間,發生了太多太多的事情:有小孩了,換工作了,最重要的,是三十了。三十,意味著很多事情,古人說,三十而立,對我來說,更重要的是有了更多的責任,不僅僅是家庭,工作也如是。
年初負責的第一個項目是配置管理組的運維自動化項目,簡單的說就是將之前手工管理的20多臺機器使用puppet管理起來。想一想,命運真是諷刺,就在一年前,在上一家公司,自己還對持續集成工具不太感冒,不愿去學,甚至認為有些太難:機器環境的管理、構建工具、jenkins、puppet/chef、shell,覺得這些東西太瑣碎,一心只想寫代碼。換了工作,陰差陽錯,先到配置管理組工作一段時間,必須學習這些東西,過程就不多說了,只有一個感悟:很多時候,你覺得太難,只是因為你不了解它。用了兩周時間,將整個puppet環境搭建起來,一切皆SVN,一切皆代碼。
接下來的第二個項目是負責調研搜索新架構的自動化發布方案,這是跨部門的合作項目,大大小小跨越20多個項目組,這其中還包括了運維同事、測試同事和云計算基礎服務的同事,調研一禮拜,實際上事前準備了很長時間,僅僅那一周的調研計劃就修改了四版,系統整理了整個新架構的架構方式,和對方領導達成一致,取得他們的支持,了解大家的期望:開發同事希望能夠更快更有效率的發布代碼,測試同事希望測試的代碼與發布的代碼同源,運維同事希望發布過程能夠遵從規范可控,當大家對共同的目標達成一致時,方案就順理成章了:持續集成服務器負責一鍵編譯測試打包上傳到包服務器,包服務器保存所有的預發布包,預發布包經過測試后才轉為發布包,發布包透過發布系統一鍵推送到Torca集群調度系統,Torca完成最終集群的發布調度。相比老架構,感覺新架構最明顯的提升是:下載、索引和檢索三大模塊被分離成各自獨立的服務,獨立演進;統一的數據管理平臺,以前追蹤badcase很難判定是哪個模塊處理數據出了問題,現在透過數據管理平臺,數據處理過程被可視化可追蹤;統一的腳本執行系統,所有腳本以及執行過程透明可視化;云計算平臺,XFS文件系統、Xcube數據庫、Torca集群調度、mapreduce并行計算,這些服務大大簡化了上層應用的開發。越來越體會到架構的本質:隨著系統的演進,我們需要不斷進行系統的分解,做到服務的獨立演化。當然當時也有困惑:當所有的希望都被壓在新架構身上,畢其功于一役,現網老架構停止開發運營時,項目的風險可想而知。做完這個項目,感悟有兩個:一是機會只青睞有準備的人;二是跨部門溝通一定要找到共同的利益點,一定要多換位思考。
4月份,準備調回項目管理組,去云計算基礎架構部做項目經理。在配置管理組的最后一個項目是Jenkins的報表系統,只有一周半時間,最開始準備使用scala,考慮到后續維護最后使用了java,好久沒有編碼了,找回久違的感覺:打印出IDE的快捷鍵,搭建開發環境、測試環境和產品環境,jenkins一鍵自動部署,數據庫版本管理,TDD,一周半的時間就上線第一個版本,最后還不得不贊一下jenkins的rest api。感悟是:感謝一期開發時間只有一周半,這使得我們不斷思考到底我們要做些什么,哪些是我們最緊急最需要的,哪些是錦上添花的,一期上線后,唯一也是最大的好處就是:我們再也不用手動統計和發送構建周報了,每個禮拜一再也不用那么忙碌了。時間盒,很重要。
終于轉回了項目經理,去云計算,牛人聚集的地方。首先仍舊是補課:計算機原理、Linux系統編程、C++ primer,一個都不能少。去了沒多久,出現了一起事故:搜索模塊對云計算SDK的依賴是源代碼依賴,云計算有5個產品,但是一個產品單獨發布時與之前的SDK不兼容,一發布就直接導致了大量搜索模塊的無法編譯。正好由我負責來推動解決這個問題,立了一個發布流程規范化項目:通過規范化發布流程、增加自動化集成測試,減少云計算平臺的發布風險。所有SDK統一打基線發布,發布前必須進行自動化集成測試,server發布時也要與所有SDK版本進行兼容性測試。隨著項目的進行,逐漸融入了這個部門:這是一個工程師文化非常強烈的部門,所有人都在技術上追求卓越,加班到10點以后是非常常見的事情,單元測試覆蓋率令人驚訝的全部達到85%,但是很多同事一聽到規范和流程就頭疼,項目計劃也是比較隨意,延期比較常見,另外因為之前發布版本升級比較隨意,也會經常受到上游兄弟部門的投訴,有很多次出現問題,兄弟部門抱怨云計算平臺不穩定,而仔細檢查后發現很多時候是使用的方式不對,比如查找文件時使用了遍歷。逐漸意識到,部門最大的問題其實是缺少產品運營,大家的關注點全部集中在產品本身上(吞吐量、最大存放文件數、強一致性),或多或少的忽略了用戶。5月下旬,風神項目啟動,項目目標是搭建臺風統一的監控平臺和自動化部署框架,打造一站式的臺風服務。開始在項目中引入項目管理的實踐,WBS是最基本的了,迭代計劃找到開發節奏、回顧、每個迭代結束后都努力向線上發布版本,實現持續交付,工程上則將開發環境與線上環境進行了隔離。效果都還不錯,但思考更多的還是,我們還應該做些什么。產品發布規范化,必須通過自動兼容性測試和周知用戶;集群環境的修改必須可被審計,暫時不能自動化,那么先必須周知部門內同事或結對操作;監控有風神項目,但集群運營、用戶數據、可用率日報也需要發送;開發、測試和線上環境互相隔離;定期和用戶進行主動溝通,了解他們的問題。這段經歷的感悟很簡單:產品的核心在于運營,作為服務部門,我們交付的一定是用戶滿意度而不是產品。
緊跟著,新架構還未上線,組織結構調整來了,喜歡ls的直率:我現在的任務很簡單,就是看到哪里有山頭就把它給平了,所有人都必須聽我的,所有人的思路必須一致。
在敏捷中國大會發表了演講《百年歷史看管理》,這個session足足準備了2個月時間,重新思考了流程、組織結構和人之間的關系。從20世紀初到40年代,管理科學完成了從無到有的第一個階段發展,這個階段最重要的成就就是將管理作為一門科學建立起來,發現了管理的三要素:工作流程、組織結構和人,并振聾發聵的告訴所有人:管理是可以學習的。我們可以看到,所謂管理,都不過是在流程、組織結構和人這三者之中進行權衡調節,管理沒有固定模式,只有不同企業根據不同情況在這三者間權衡裁剪罷了。如果說管理科學的第一個階段是在探討如何正確的做事,如何提高工作的效率,那么50到60年代這二十年管理科學的第二個階段則是在探討如何做正確的事:以顧客為中心、做事之前一定要想清楚做事的目的。管理至此也終于有了一個完整的定義:做正確的事、正確的做事。從70年代開始,管理科學進入第三個發展階段,在這個階段,首先提出的思想就是沒有銀彈,管理是一門藝術需要柔性,接下來就是流程的內涵開始延伸,不再是單純的工作流程,而是面向顧客,強調端到端滿足顧客需求的整個過程,這個過程在全球化背景下越來越強調企業之間的協調、強調整個面向交付生態系統的協調,業務流程的概念被提出。進入新世紀,不管是更合理組織結構的思考(扁平化),還是對人的推崇(喬布斯、創新)抑或是業務流程效率的競爭(供應鏈),都明白無誤的告訴我們:管理只有恒久的問題,沒有終結的答案。
9月份調整到新的部門:搜搜問問。先負責的是后臺組的項目管理。新團隊,老人只有一個,士氣低下,缺少文檔,上百個服務,光維護就非常困難,重寫計劃。從回顧會議開始,持續改進。這段時間的感悟是:提升團隊士氣的最好方式就是幫助大家成功,任何一點成績都值得鼓勵。我們引入了持續集成和自動化發布,鼓勵同事做總結和分享;引入了自動化測試,鼓勵同事做匯報,幫助review ppt;積極的讓大家做有態度的程序員,對產品進行思考和反饋,把團隊精神傳遞到部門經理,讓部門經理進行鼓勵。可以自豪的說,后臺組是現在問問最有戰斗力的團隊。還有一點最重要的感悟是:一定是團隊leader決定團隊是否給力,幸運的是,我們有一個非常優秀的leader。
12月份開始負責部門的社區化運營項目。這和今年工作的感悟是一致的,產品的核心在于運營,這正是我想做的。項目立項一定要有一個NB的名字,我們就叫黑暗騎士。這個項目同樣面對很多的挑戰,目前最大的挑戰還是在于人,團隊的信心目前還沒有建立,年后可能還會有人提出離職,而招人又是如此的困難,所以,上班第二天的第一件事是回顧會議。團隊年前第一個版本發的很有挫折感,需求反復修改,開發人員都心灰意冷,所以,感悟是:一份優秀的需求文檔是一切合理計劃的起點。
1月份組織了技術中心的部門年會節目,我們原創的小品《非問勿擾》獲得了二等獎。把新人都變為主角,這也算團隊建設的一部分。
依然在不停思考,對問問來說,我們還應該做些什么。傳統問答模式作為搜索引擎的補充是否已經走到了盡頭?SNS的問答模式是否值得探索?與微博是否有更深的整合方式,或者,它們本身就是一種產品的兩種展現方式?新浪微什么的探索是否還不夠大膽?在移動端,獨立的app沒有前景,如何和微信更有力的結合。
終于到了可以結尾的段落,還有一件事情似乎忘了總結,那就是我們寫了長達四年的那本書《流程的永恒之道-一個工作流和BPM項目的實戰》,什么也不說了,一個例子來說明為什么值得期待:當我們把房管局及各委辦局的數據和流程用BPM全部打通后,客戶卻依舊堅持要手動蓋章走人工流程,BPM實施技術根本就不是瓶頸,瓶頸依舊是人啊。今年上半年一定出版。之所以寫了四年,是因為寫著寫著總覺得知道的越來越不夠,不斷讀書和補充內容,真是,那時年少,無知者無畏,唉。
2013,黑暗騎士崛起!
本文為轉載:原創地址http://www.software8.co/wzjs/cxyyg/2953.html