#
Exercise 1 Web site Development
Using Microsoft Project 2007 (can be downloaded from internet)
A nonprofit organization would like to lead a website development project. The organization has internet access that includes space on a web server, but no experience in developing websites. In addition to creating its website, the organization would like you to train two people on its staff to do simple web page updates. The website should include the following information, as a minimum: description of the organization (mission, history, and recent events), list of services, and contact information. the organization wants the website to include graphics( photographs and other images) and have an attractive, easy way to use layout.
1- Project Scope Management: create a WBS for this project and enter the tasks in project 2007. Create milestones and summary tasks. Assume that some of the project management tasks are similar to tasks from the project tracking database project. some of the specific anaylsis, design, and implementation tasks will do:
a) collect information on the organization in hardcopy and digital form( brochures, reports, organization charts)
b) research web site of similar organization
c) collect detailed information about customer's design preferences
d) develop a template for the customer to review (background color of pages, layout of text)
e) create a site map or hierarchy chart showing the flow of website
2- Project Time Management:
a) enter realistic duration for each task, and then link the tasks
b) do Gantt Chart view and Network Diagram View for the project
c) do schedule table to see key dates and slack times for each task.
3- Project Cost Management
a) assume you have three people working on project and each of them would charge $20 per hour. Enter this information in the Resource Sheet.
b) estimate that each person will spend an average of about five hours per week for the four month period. Assign resources to the tasks, and try to make the final cost in line with this estimate
c) do a budget report for your project
4- Project Human Resource Management
a) assume that one project team member will be unavailable due to vacation for two weeks in the middle of the project. Make adjustments to accommodate this vacation so that the schedule does not slip and the costs do not change. Document the changes from the original plan and the new plan.
b) use the Resource Usage view to see each person's work each month. Print a copy of the Resource Usage view.
5- Project Communications Management
a) do a Gantt chart for this project. use a time scale that enables that chart to fit on one page. and the copy and paste it to PowerPoint
b) do a TO DO LIST report for each team member
c) Create a WHO DOES WHAT REPORT
** Write a two page single spaced paper summarizing what do you think about Microsoft Project. What do you like and What do you dislike about it. Do you think it would be useful for managing all project or just some and which ones.
标志一、只会踏踏实实地做具体的工作
踏踏实实地做具体工作,这没有错。但只会这样那错就大了,因为这永远只是新手的方式,仅靠这个,永远也成不了高手。甘心一辈子本本分分只当个菜鸟,到头来,肯定连菜鸟也做不成,现在的职场,逆水行舟,原地不动,早晚被浪打翻。
标志二、不会踏踏实实地工作
年轻人喜欢幻想,本身也没错。但若是一天到晚光幻想,那就麻烦了。脱离了现实,好高骛远,白日做梦,眼高手低……漫步云端的感觉是不错,但梦醒时分,从云上跌落粉身碎骨的时候,就追悔莫及了。
标志三、瞧不起上司
受过高等教育的人都清高,别人不如自己的地方很容易放在眼里,并嗤之以鼻,尤其是对领导。让不如自己的人来领导自己,实在不公平。但是,领导之所以是领导,就有原因,不管合理不合理都存在了。也许他学识不行,也许能力不行,但他赢可能就赢在关系上了,可能就赢在心机上了,好的也好,坏的也罢,都是实实在在存在的现象。
标志四、崇拜上司
相比起刚才的这种行为,对上司盲目崇拜,则更显得幼稚。对上司的话全盘接受,无条件服从,缺乏了起码的分析能力,最终会让你在职场中迷失自我。
标志五、容易被激发、被感动、被忽悠
有些人比较感性,我本人也是这样。对于领导一些比较有煽动性东西,难以抵制,很容易用头脑发热。但无论如何,事后一定要冷静思索思索,站在不同的角度来考虑考虑问题,切莫一时意气用事。
标志六、甘当云梯默默无闻
甘当云梯,默默无闻,这本是一种很高尚的情怀。在如今更是难得。但难得归难得,天不佑此类人,生活不助此类人,时代更是难容此类人。对这种人,只能说,老兄,别那么单纯了。
标志七、习惯忍让
喜欢争斗的人让人厌恶,但现在的职场上,也只是这种人才得势。人善被人欺,习惯忍让,别人会觉得你好欺负,这已经成为现在职场上的一种思维定势了。谁也打不破它。
标志八、锋芒毕露
有人则相反,不忍不让,锋芒毕露。这也不好,这样会树敌太多,而且太容易让人看透,很容易中了别人的招儿。适当的时候露露锋芒,展示一下自己的立场就可以了,大多数的情况,还是应该韬光养晦的。
标志九、排斥关系
近几年来,新兴起一门学问,叫做关系学。这里面学问可大了,大到关系职场中的方方面面。可有人就是排斥它,认为靠自己的打拚就已经足够了。其实,职场不比学术,不是把自己关在实验室里就能出成果的,闭门造车,最终自食苦果。
标志十、知无不言言无不真
对别人什么都说,而且什么话都说真的,这很诚实,但太不成熟了。职场上混,就跟下棋一样,尽可能地对方的心理,而不是尽可能地让别人了解自己的心理。道理很浅显。
如果你希望用 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.blogjava.net/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是否能够很快找出错误的原因?是抓取失败,是索引时丢失,还是相关性排序不好?关乎监控和报警,我们能否很快从监控中定位出原因?关乎组织结构,前台开发,后台架构,基础架构,运维测试团队都是分离的,如何协作才能使团队合作的成本最低而整体利益最大化?
回顾往事,保尔柯察金说:如何才能不虚度光阴,只有为共产主义奋斗终身;柯景腾说:唯有沈佳宜让我怀念;而我想说的是:
做任何项目之前一定要想清楚为什么要做这个项目,一定要想清楚这个项目的价值是对用户和公司的(尤其需要跳出站到一个比较高的层次看项目),一定要想清楚项目的约束(时间约束、人员约束),不仅是项目开始之前要想,过程中要不断回顾;;
项目任何时候都必须有计划,对所有干系人透明;
项目一定是持续交付和持续反馈的,不允许黑盒出现;
测试和运维一定要尽早介入;
从每个团队成员的角度出发关注所有人的利益实现共赢。