小方的Java博客

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  27 随笔 :: 17 文章 :: 115 评论 :: 0 Trackbacks

2006年8月1日 #

我在做公司某个框架时有这么一个需求。每次调用dwr的方法前要检查用户是否已经登录,否则就不能执行并且退到首页。

当然了,做拦截器有很多方式,但经过研究发现DWR自带很多插件,其中就有一个调用处理的插件。具体做法如下。

在web.xml里的DWR配置中加入一个参数:
<init-param>
            
<param-name>
                org.directwebremoting.extend.Remoter
            
</param-name>
            
<param-value>com.xxx.base.framework.web.MyDWRRemoter</param-value>
        
</init-param>

然后自己创建这个实现类。
public class MyDWRRemoter extends DefaultRemoter
{

    
public Replies execute( Calls calls )
    
{
        HttpSession session 
= WebContextFactory.get().getSession();
        ISessionContainer sc 
= ( ISessionContainer ) session.getAttribute( ISessionContainer.SESSION_CONTAINER_KEY );

        
//session检查
        if ( sc == null || sc.getUserInfo() == null )
        
{
            logOut();
            
return super.execute( new Calls() );
        }

        
else
        
{
            IUserInfo userInfo 
= sc.getUserInfo();
            
if(!SecurityFactory.getInstance().isOnline( userInfo.getUserID(), session.getId() ))
            
{
                logOut();
                
return super.execute( new Calls() );
            }

        }

        
return super.execute( calls );
    }


    
private void logOut()
    
{
        WebContext wct 
= WebContextFactory.get();
        Util utilThis 
= new Util(wct.getScriptSession());
        utilThis.addScript( 
new ScriptBuffer("logOut()"));
    }

}

其中,检查用户是否登录,如果没有登录就返回一个空的super.execute( new Calls());, 不能返回null否则会报错。
检查通过就调用super.execute( calls );  其实calls里还能获得很多信息。

最后大家注意logOut方法,这里用到了DWR2.0新功能:DWR反向调用,就是DWR调用javascript,具体用法大家网上可以查到,需要配置的,我这里就不多说了。补充一下,addScript调用的是html里的function logOut().

这样的话,如果用户session超时,或被管理员踢掉,一旦他做任何dwr操作就会被强迫登出到首页了。
posted @ 2008-12-05 20:42 方佳玮 阅读(2872) | 评论 (3)编辑 收藏

很久以前看某本书整理的,忘了哪本了,现在贡献出来。

1)在select语句中使用条件逻辑

1select ename,sal,   
2       case when sal <= 2000 then 'UNDERPAID'  
3            when sal >= 4000 then 'OVERPAID'  
4            else 'OK'  
5       end as status   
6from emp   


ENAME SAL STATUS
---------- ---------- ---------
SMITH 800 UNDERPAID
ALLEN 1600 UNDERPAID
WARD 1250 UNDERPAID
JONES 2975 OK
MARTIN 1250 UNDERPAID
BLAKE 2850 OK
CLARK 2450 OK
SCOTT 3000 OK
KING 5000 OVERPAID
TURNER 1500 UNDERPAID
ADAMS 1100 UNDERPAID
JAMES 950 UNDERPAID

FORD 3000 OK
MILLER 1300 UNDERPAID

 

2)从表中随机返回n条记录

1select *   
2  from (   
3    select ename, job   
4    from emp   
5    order by dbms_random.value()   
6  )   
7  where rownum <= 5 

 

3)按照子串排序

比如要从EMP表中返回员工名字和职位,并且按照职位字段最后2个字符排序

1select ename,job   
2  from emp   
3order by substr(job,length(job)-2

ENAME JOB
---------- ---------
KING PRESIDENT
SMITH CLERK
ADAMS CLERK
JAMES CLERK
MILLER CLERK
JONES MANAGER
CLARK MANAGER
BLAKE MANAGER
ALLEN SALESMAN
MARTIN SALESMAN
WARD SALESMAN
TURNER SALESMAN
SCOTT ANALYST
FORD ANALYST

 

4)处理空值排序

当被排序的列存在空值,如果希望空值不影响现有排序

1select ename,sal,comm   
2   from emp   
3order by comm nulls last 

 

ENAME SAL COMM
------ ----- ---------
TURNER 1500 0
ALLEN 1600 300
WARD 1250 500
MARTIN 1250 1400
SMITH 800
JONES 2975
JAMES 950
MILLER 1300
FORD 3000
ADAMS 1100
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000

1select ename,sal,comm   
2  from emp   
3order by comm desc nulls first 


ENAME SAL COMM
------ ----- ----------
SMITH 800
JONES 2975
CLARK 2450
BLAKE 2850
SCOTT 3000
KING 5000
JAMES 950
MILLER 1300
FORD 3000
ADAMS 1100
MARTIN 1250 1400
WARD 1250 500
ALLEN 1600 300
TURNER 1500 0

5)根据数据项的键排序

比如如果job是“SALESMAN”,根据COMM排序,否则根据SAL排序

1select ename,sal,job,comm   
2  from emp   
3 order by case when job = 'SALESMAN' then comm else sal end  


ENAME SAL JOB COMM
---------- ---------- --------- ----------
TURNER 1500 SALESMAN 0
ALLEN 1600 SALESMAN 300
WARD 1250 SALESMAN 500
SMITH 800 CLERK
JAMES 950 CLERK
ADAMS 1100 CLERK
MARTIN 1250 SALESMAN 1300
MILLER 1300 CLERK
CLARK 2450 MANAGER
BLAKE 2850 MANAGER
JONES 2975 MANAGER
SCOTT 3000 ANALYST
FORD 3000 ANALYST


 

6)从一个表中查找另一个表中没有的值

比如要从DEPT中查找在表EMP中不存在数据的所有部门(数据中,DEPTNO值为40的记录在表EMP中不存在)

1select deptno from dept   
2minus   
3select deptno from emp 


 

7)在运算和比较时使用null值

null不会等于和不等于任何值,null和自己都不等于。以下例子是当comm有null的情况下列出比“WARD”提成低的员工。 (coalesce函数将null转换为其他值)

1select ename,comm,coalesce(comm,0)   
2  from emp   
3where coalesce(comm,0< ( select comm   
4                                     from emp   
5                                    where ename = 'WARD' )


ENAME COMM COALESCE(COMM,0)
---------- ---------- ----------------
SMITH 0
ALLEN 300 300
JONES 0
BLAKE 0
CLARK 0
SCOTT 0
KING 0
TURNER 0 0
ADAMS 0
JAMES 0
FORD 0
MILLER 0

 

8)删除重复记录

对于名字重复的记录,保留一个

1delete from dupes   
2 where id not in ( select min(id)   
3                      from dupes   
4                     group by name ) 

 

9)合并记录
比如如下需求:
如果表EMP_COMMISSION中的某员工也存在于EMP表,那么更新comm为1000
如果以上员工已经更新到1000的员工,如果他们SAL少于2000,删除他们
否则,从表中提取该员工插入表EMP_COMMISSION

1merge into emp_commission ec   
2using (select * from emp) emp   
3    on (ec.empno=emp.empno)   
4 when matched then  
5       update set ec.comm = 1000   
6       delete where (sal < 2000)   
7 when not matched then  
8        insert (ec.empno,ec.ename,ec.deptno,ec.comm)   
9       values (emp.empno,emp.ename,emp.deptno,emp.comm)  

 

10)用sql生成sql

1select 'select count(*) from '||table_name||';' cnts   
2  from user_tables;   


(user_tables是oracle的元数据表之一)

CNTS
----------------------------------------
select count(*) from ANT;
select count(*) from BONUS;
select count(*) from DEMO1;
select count(*) from DEMO2;
select count(*) from DEPT;
select count(*) from DUMMY;
select count(*) from EMP;
select count(*) from EMP_SALES;
select count(*) from EMP_SCORE;
select count(*) from PROFESSOR;
select count(*) from T;
select count(*) from T1;
select count(*) from T2;
select count(*) from T3;
select count(*) from TEACH;
select count(*) from TEST;
select count(*) from TRX_LOG;
select count(*) from X;

 

11)计算字符在字符串里的出现次数

判断字符串里有多少个‘ , ’

1select (length('10,CLARK,MANAGER')-   
2  length(replace('10,CLARK,MANAGER',',','')))/length(',')   
3  as cnt   
4from t1   


先计算原字符串长度,再减去去掉逗号的长度,这个差再除以‘,’的长度

 

12)将数字和字母分离


原数据是:

DATA
---------------
SMITH800
ALLEN1600
WARD1250
JONES2975
MARTIN1250
BLAKE2850
CLARK2450
SCOTT3000
KING5000
TURNER1500
ADAMS1100
JAMES950
FORD3000
MILLER1300
 1select replace(   
 2  translate(data,'0123456789','0000000000'),'0') ename,   
 3  to_number(   
 4    replace(   
 5    translate(lower(data),   
 6      'abcdefghijklmnopqrstuvwxyz',   
 7      rpad('z',26,'z')),'z')) sal   
 8  from (   
 9    select ename||sal data from emp   
10 )   

ENAME SAL
---------- ----------
SMITH 800
ALLEN 1600
WARD 1250
JONES 2975
MARTIN 1250
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500
ADAMS 1100
JAMES 950
FORD 3000
MILLER 1300

思路是很复杂的,比如先去除数字,是先把所有数字翻译为0,然后用replace去掉0.


 

13)根据表中的行创建分割列表


表中数据:
DEPTNO EMPS
------ ----------
10 CLARK
10 KING
10 MILLER
20 SMITH
20 ADAMS
20 FORD
20 SCOTT
20 JONES
30 ALLEN
30 BLAKE
30 MARTIN
30 JAMES
30 TURNER
30 WARD

 1select deptno,   
 2    ltrim(sys_connect_by_path(ename,','),',') emps   
 3  from (   
 4  select deptno,   
 5    ename,   
 6    row_number() over   
 7       (partition by deptno order by empno) rn,   
 8    count(*) over   
 9      (partition by deptno) cnt   
10  from emp   
11  )   
12  where level = cnt   
13  start with rn = 1   
14    connect by prior deptno = deptno and prior rn = rn-1 


查询结果
DEPTNO EMPS
------- ------------------------------------
10 CLARK,KING,MILLER
20 SMITH,JONES,SCOTT,ADAMS,FORD
30 ALLEN,WARD,MARTIN,BLAKE,TURNER,JAMES

 

14)按字母顺序排序

 1select old_name, new_name   
 2  from (select old_name, replace(sys_connect_by_path(c, ' '), ' ') new_name   
 3          from (select e.ename old_name,   
 4                       row_number() over(partition by e.ename order by substr(e.ename, iter.pos, 1)) rn,   
 5                       substr(e.ename, iter.pos, 1) c   
 6                  from emp e, (select rownum pos from emp) iter   
 7                 where iter.pos <= length(e.ename)   
 8                 order by 1) x   
 9         start with rn = 1   
10        connect by prior rn = rn - 1   
11               and prior old_name = old_name)   
12 where length(old_name) = length(new_name) 


You would like the result to be:

OLD_NAME NEW_NAME
---------- --------
ADAMS AADMS
ALLEN AELLN
BLAKE ABEKL
CLARK ACKLR
FORD DFOR
JAMES AEJMS
JONES EJNOS
KING GIKN
MARTIN AIMNRT
MILLER EILLMR
SCOTT COSTT
SMITH HIMST
TURNER ENRRTU
WARD ADRW

 

posted @ 2008-08-07 14:41 方佳玮 阅读(2708) | 评论 (6)编辑 收藏

答辩后,心理有很多话要说,真是很不爽,也为中国软件业的未来捏一把汗。如果此文让某些读者感觉不爽,就当没看过,在此先向你道歉。
 
本周5是我们计算机专业毕业设计答辩日,我提前4天来到学校,带着3月份早就完成的毕业设计。真是让我大吃一惊,很多同学竟然都下载或者花钱买了毕业设计或者找人帮忙做来交差,这个数量我估计至少有5成。我的一个好友,更是夸张,什么都没做,要我帮他在2天内搞定,我慌了,真把我当超人了,不过还好,由于她那个东西确实没什么内容,我赶了一下还是帮她搞定了,实在是没啥内容的毕业设计。最搞笑的是还有些同学。。。,由于不是自己做的东西,而且连代码也看不懂,运行出错都不知如何解决,只会找别人求助,还天真地说:奇怪,怎么不行呢?原来明明看到可以运行的。。。。 我要他自己去debug一下,结果,连开发工具也没用过,怎么在开发工具里跑一个工程debug也根本不会,我再次无话可说。
 
同学们啊,你们不是高中生,你们是重点大学计算机专业应届毕业生啊,怎么就像没读过大学一样,你们到底在4年里干了什么啊。
 
然后更让人心寒的是:答辩时,很多老师都自己什么也不会,或者只会皮毛,看着同学的毕业设计,除了问点需求问题,再也问不出任何技术问题了,最后就草草答辩完,给个分数就算过了。我在答辩时,也懒得把架构和技术应用来说了,实在是对牛弹琴。学生堕落,教师应付,学校乱搞扩招,公司高薪招不到人才,中国软件业的未来有何希望!
 
当然,还是有10%左右的学生很优秀,有些做了很不错的java ee程序,有些自己研究做了简易3D游戏引擎,还有些同学水平不怎么样,但通过自己努力独立完成了,虽然做得不怎么好,但学到很多东西,也是自己劳动汗水,但是这些同学太少太少。。。
posted @ 2007-06-18 15:43 方佳玮 阅读(1583) | 评论 (6)编辑 收藏

选自《Professional Javascript For Web Developers》

其它方式:对象冒充,call(),apply(),原型链都有不少缺点这里就不一一介绍了,想了解的可以去看一下这本著作的第4章节。

这种方法用对象冒充继承属性,用原型链继承方法,代码如下
function  ClassA(sColor){
    
this .color  =  sColor;
}

ClassA.prototype.sayColor 
=   function (){
    alert(
this .color);
}

function  ClassB(sColor, sName){
    ClassA.call(
this . sColor);
    
this .name  =  sName;
}

ClassB.prototype 
=   new  ClassA();

ClassB.prototype.sayName 
=   function (){
    alert(
this .name);
}

测试:
var  objA  =   new  ClassA( " red " );
var  objB  =   new  ClassB( " blue " " Nicholas " );
objA.sayColor(); 
// red
objB.sayColor();  // blue
objB.sayName();   // Nicholas

其它好方法,请参考zlnherit库和xbObjects
posted @ 2007-03-03 15:44 方佳玮 阅读(1350) | 评论 (0)编辑 收藏

1.有个大大提高性能的建议:

比如得到list 是5个班级,然后要得到5个班级的所有学生

垃圾办法:5次通过级联获得,等于执行5条sql语句

好办法:

this .getSession().createQuery(
        
" from User a,Clazz b where a.clazz=b and b in(:clazz) " )
 .setParameterList(
" clazz " , list)
 .list();

仅执行一条


2.还有个很实用的方法,如何通过hql语句返回多个po

List list  =   this .getSession().createQuery(
 
" from User a,Clazz b where a.clazz=b " ).list();

// 使用的时候:
Iterator it  =  list.iterator();
  
while (it.hasNext()){
 Object[] vo 
=  (Object[])it.next();
 User user 
=  (User)vo[ 0 ];
 Clazz clazz 
=  (Clazz)vo[ 1 ];
 System.out.println(user.getUserName() 
+   " , "   +  clazz.getClassName());



3.我们全部用一对一,多对一等。如果过滤有问题,有个办法

List students  =   this .getSession().createFilter(clazz.getStudents(), " where this.status='A' " ).list(); 
posted @ 2007-02-14 23:30 方佳玮 阅读(473) | 评论 (0)编辑 收藏

选自《Professional Javascript For Web Developers》

其它方式:工厂方式,构造函数方式,原型方式都各有各的大缺陷,这里就不一一介绍了,想了解的可以去看一下这本著作的第3章节。

1. 混合构造函数/原型方式

function  Car(sColor, iDoors, iMpg) {
  
this .color  =  sColor;
  
this .doors  =  iDoors;
  
this .mpg  =  iMpg;
  
this .drivers  =   new  Array(“Mike”, “Sue”);
}

Car.prototype.showColor 
=   function  () {
  alert(
this .color);
};

var  oCar1  =   new  Car(“red”,  4 23 );
var  oCar2  =   new  Car(“blue”,  3 25 );

oCar1.drivers.push(“Matt”);

alert(oCar1.drivers); 
// outputs “Mike,Sue,Matt”
alert(oCar2.drivers);  // outputs “Mike,Sue”

优点:具有其它方式的优点而没有其它方式的缺点
不足:封装性欠缺

2 . 动态原型方式

function  Car(sColor, iDoors, iMpg)  {
  
this .color  =  sColor;
  
this .doors  =  iDoors;
  
this .mpg  =  iMpg;
  
this .drivers  =   new  Array(“Mike”, “Sue”);

  
if  ( typeof  Car._initialized  ==  “undefined”)  {
    Car.prototype.showColor 
=   function  ()  {
      alert(
this .color);
    }
;

    Car._initialized 
=   true ;
  }

}


优点:封装性比上一个方式更好
不足:就是看上去奇怪一点,呵呵


总之,以上2种方式是目前最广泛使用的,尽量使用它们避免不必要的问题。

posted @ 2007-02-11 17:34 方佳玮 阅读(6146) | 评论 (1)编辑 收藏

v0.9 点击下载

有些错别字,我会在以后版本更正

花了几周把DWR中文文档.PDF给搞出来了

这是首次发布在网上

希望对大家有用

有任何意见请发我邮箱:jorwen.fang@gmail.com,或者在此留言

第一版目录预览:

第1章. DWR入门 8
1.1 简介 8
1.2 第一个DWR程序:Hello World 9
1.2.1 将DWR放入你的工程 9
1.2.2 编辑配置文件 9
1.2.3 编写service 10
1.2.4 测试DWR 10
1.2.5 编写一个jsp 11
1.3 本章总结 12

第2章. web.xml配置 13
2.1 主要配置 13
2.2 常用<init-param>参数列表 14
2.2.1 安全参数 14
2.2.2 Ajax服务器加载时保护参数 14
2.2.3 其他参数 15
2.3 日志配置 16
2.4 多个dwr.xml配置和J2EE角色定义 16
2.5 插件配置 18
2.6 测试模式配置 19

第3章. dwr.xml配置 20
3.1 纵览 20
3.2 <init>标签 20
3.3 <allow>标签 21
3.3.1 Creator 21
3.3.2 Converter 25
3.4 <signatures>标签 30

第4章. 整合 32
4.1 DWR与Servlet 32
4.1.1 使用webContext的方法: 32
4.1.2 方法选择 32
4.2 DWR与Spring 34
4.2.1 让DWR和Spring一起工作的检查列表 34
4.2.2 Spring Creator 34
4.2.3 找到Spring配置文件 34
4.2.4 使用Spring配置DWR 35
4.3 DWR与JSF 36
4.3.1 JSF Creator 36
4.3.2 Servlet Filter 36
4.4 DWR与Struts 37
4.4.1 Struts creator 37
4.4.2 开始顺序 37
4.5 DWR与Weblogic或PageFlow 38
4.6 DWR与Hibernate 39
4.6.1 让DWR和Hibernate一起工作的检查列表 39
4.6.2 HibernateBeanConverter 39
4.6.3 Session管理 39
4.7 DWR与WebWork 40
4.7.1 配置dwr.xml 40
4.7.2 在JSP中导入脚本 40
4.7.3 高级 41
4.8 DWR与Acegi 42
4.8.1 问题提出 42
4.8.2 解决方案 42

第5章. DWR中的JavaScript简介 44
5.1 简单的回调函数 44
5.2 调用元数据对象 45
5.3 查找回调函数 45
5.4 创造一个与Java对象匹配的Javascript对象 46

第6章. engine.js 功能 47
6.1 使用选项 47
6.2 选项索引 48
6.2.1 处理器(Handler) 48
6.2.2 调用处理器(Call Handler) 48
6.2.3 Hooks (一个batch中可以注册多个hook) 49
6.2.4 全局选项(在单次调用或者批量调用中不可用) 49
6.2.5 废弃的选项 49
6.2.6 未来版本的选项 49
6.3 选项说明 50
6.3.1 批量调用 50
6.3.2 顺序调用 50
6.3.3 错误警告和超时 50
6.3.4 远程调 Hooks 51
6.3.5 远程调用选项 51

第7章. util.js 功能 54
7.1 $() 54
7.2 addOptions and removeAllOptions 54
7.3 addRows and removeAllRows 55
7.4 getText 56
7.5 getValue 56
7.6 getValues 57
7.7 onReturn 57
7.8 selectRange 57
7.9 setValue 58
7.10 setValues 58
7.11 toDescriptiveString 58
7.12 useLoadingMessage 58
7.13 Submission box 61

第8章. DWR进阶 63
8.1 DWR  Annotations 63
8.1.1 初始配置 63
8.1.2 远程访问类 63
8.1.3 对象转换 64
8.2 错误和异常处理 64
8.2.1 错误处理 64
8.2.2 异常 65
8.2.3 找出更多的信息 65
8.3 传递额外的数据到callback函数 66
8.4 从其他的URL读取数据 67
8.5 安全 68

第9章. 范例精讲 71
9.1 购物车 71
9.1.1 介绍 71
9.1.2 实现目录 72
9.1.3 测试部署 74
9.1.4 调用远程对象 75
9.1.5 实现购物车 77
9.1.6 调用远程的 Cart 方法 79
9.1.7 演示结果 81
9.1.8 总结 81

第10章. 附录 83
10.1 常见问题 83
10.1.1 TransformerFactoryConfigurationError 83
10.1.2 XML解析错误 83
10.1.3 使用weblogic的类路径问题 83
10.1.4 没有cookies的情况下用DWR 84
10.2 JavaScript高级应用 85
10.2.1 用变量操纵函数 85
10.2.2 高阶函数 86
10.2.3 动态类型 87
10.2.4 灵活的对象模型 89
10.2.5 本节总结 91

posted @ 2007-02-08 20:18 方佳玮 阅读(7597) | 评论 (49)编辑 收藏

曾经看过一项统计,在大连有95%以上的软件公司都是软件外包的公司,准确的说:是面向外国开发的软件公司。这种现象不单单只出现在大连,现在北京,上海包括深圳也有很多对日开发的外包公司,只是数量上不象大连那么明显罢了。
    我看到很多程序员都在讨论外包的利弊,在这里我只谈谈自己的观点:
    1:曾经问过许多大连软件行业的朋友,大部分人都抱怨自己的工作时间长,工资待遇不高,而且工作技术含量不高,感觉学不到什么新东西。用一句网友的话来形容:“软件外包,丰富了老板的腰包,牺牲了程序员的青春”。工作将近三年,我的感受也是如此。外包就是这个样子:内部设计是外国人做的,我们需要做的只是按照人家的式样书,把伪代码经过枯燥无味的反复调试工作变成可以正常运行的程序。测试也是如此,我们只需要负责单体测试就足够了。大部分测试工作:连接测试,综合测试,压力测试统统移到外国去做。这就是大部分软件外包公司的现状。学过软件工程的人都应该深深的知道一点:在软件开发的过程主要由设计,代码,测试三部分组成。对应这三部分,合理的安排开发时间是非常必要的,往往我们项目是这样安排的,3:1:2,也就是说设计需要的时间是代码部分的三倍,测试部分是其2倍(单体测试应该和代码整合成一个部分)。按这个比例计算,如果整个项目的资金为60万,做程序员的最多能分到10万,而公司中人数最多的也是程序员。这样我们就可以理解为什么如此多的程序员在抱怨工资低了。至于技术含量的问题,我想应该这么理解:不是我们做的项目缺少技术含量,而是技术含量高的部分绝大多数都是由日本鬼子完成的,外国人看中了中国廉价的劳动力市场,才把这些技术含量低的部分拿到中国来做。而外国人也绝不会把技术精髓的部分拿到中国来做。

    2:上面说到外包的那么多缺点,我们不做总可以了吧?但为什么还有那么多的人乐此不彼呢?原因大概有这么两点:中国的软件产业从98年开始茁壮的开始成长,到2001已经发展的很火爆,仔细想想当时97届的计算机毕业生(2001年毕业),基本上没毕业就找好工作了,没找到工作的只是寥寥几人,可以想象当时的计算机行业相当红火。可2002年随着全球IT产业的不景气,中国的软件行业已经逐渐走下坡路,很多软件公司倒闭,破产。也就是说,现在的软件行业不好做了,最起码不如以前了。在这种情况下,合理的利用外来资产来发展壮大中国的软件行业也不失为一种对策。还有一个原因:我国的软件行业属于起步比较晚,经验和人才相对匮乏,和日本等发达国家合作,可以为我们培养出很多高水平的管理和开发人员。曾经问过一些在北京工作的软件开发人员,他们通常写代码不写注释,也用不写软件开发的相关文档。试想这样的软件产品的质量能放心的了么?而在外包公司,这种现象是根本不能发生的。即使,技术含量再低的工作,内部设计书,详细设计书,单体测试报告…这都是不可缺少的产品的一部分,而且国外公司对这些文档的要求都是比较严格的。做任何事情都要按着一定的规范来做,虽说有些繁琐,但对于没有太多经验的程序员来说,书写技术文档对其事业发展是很有好处的,也是非常有必要的。

      总体来说,软件外包有利有弊。我认为对我国目前软件产业不太成熟的现状来说,软件外包的利大于弊。做任何事业总要付出牺牲,而中国软件事业牺牲的确是我们这一代程序员。
posted @ 2006-10-03 12:42 方佳玮 阅读(1164) | 评论 (2)编辑 收藏

作者:崔启亮, 原始出处:软件质量研究网www.sqstudy.org 
目前已经进驻上海的知名全球服务外包企业包括埃森哲、优利、NCS、博朗、爱特优科等

目录:
[0] - 为什么要对大学生谈软件外包?
[1] - 什么是软件外包?
[2] - 软件为什么要外包?
[3] - 为什么要承接软件外包
[4] - 做软件外包有前途吗?
[5] - 外包公司是怎么工作的?
[6] - 有哪些好的外包公司?

[7] - 软件外包公司需要什么样的人?
[8] - 哪些人不适合做软件外包技术人员?
[9] - 如何通过软件外包公司的面试?


[0] - 为什么要对大学生谈软件外包?

中国软件外包行业这几年成为发展最为迅速的行业之一,无论你是在校的大学生,还是即将毕业的同学,都有必要了解这个行业。如果你是软件相关专业的同学,或者毕业后准备从事软件行业,那么更应该关注软件外包这个行业。

尽管网上已经有很多关于软件外包的信息,但是这些信息很多都是媒体记者的报道,他们只是从旁观者的角度看待软件外包,缺乏一定的深度和实践感受。还有一些来自非软件外包的人士,基于他们主观的理解和推测,认为软件外包是很低级的工作,为软件外包工作泼冷水,影响了对软件外包工作的正确认识,造成了软件外包的“中国式误会”。

大学生接受了系统的高等教育,具有牢固的知识基础,而且具有极强的可塑性和学习能力,是未来软件外包行业的主力军。但是,他们参加软件外包实际项目的机会和经验毕竟很少,对于软件外包有很多模糊的认识。由于教材的更新需要更长的周期,高校教师如果没有丰富的外包企业经验,很难把软件外包的实际知识传授给学生,因此,外包企业从业人员有必要向这些高校学生交流一些软件外包企业的实际情况。

那么什么是软件外包?软件为什么要外包?中国软件外包的现状如何?将来做软件外包是否有前途?这些问题可能很多同学不是很清楚,如果今后打算进入这个行业,则从现在开始就需要先了解这些问题的答案。

笔者具有多年的软件外包公司工作经验,对于软件外包行业一直积极关注,并且积极与国内外同行交流,对软件外包有些自己的体会,借此机会与个位同学进行交流。


 [1] - 什么是软件外包?

软件外包就是软件开发商(简称“发包方”)将软件开发的一部分或者全部,发给别的软件公司(简称“接包方”)去完成。

我们通常说的中国外包公司很多都是“接包方”,主要从日本和欧美等国承接软件外包项目的技术工作。现在软件行业比较发达的美国、欧洲和日本是最大的“发包方”市场。

由于软件外包是软件全球性生产方式,所以存在很多关于外包的英文术语。外包的英文单词是“Outsourcing”。站在“发包方”的角度,把“接包方”成为“Vendor(外包服务商)”。站在“接包方”角度,把“发包方”成为“Client(客户)”

软件外包与其他外包其实没有本质区别,就是双方合作把一个很复杂的、较大的软件项目分工合作,共同做好。其实在其他行业,外包已经实施了很长时间,例如汽车行业,生产汽车的公司(比如一汽集团)他们先设计好汽车的结构,完成主要部件的生产,把很多零件外包给很多厂家加工,然后采用完成整个车辆的安装和制造。

现在人们很关注软件外包,就是因为外包在软件行业应用的时间还很短,而且软件生产存在很多不可见因素,软件外包的优势和好处,还没有被普遍了解和感受。

总结一句话,软件外包就是软件生产的分工和合作,主要目标就是生产出好的软件。


[2] - 软件为什么要外包?

同学们可能都听说了,现在印度和中国做软件外包“火得不得了”,越来越多的欧美大型软件公司都把软件外包给印度和中国。为什么会出现这种现象呢?

要回答这个问题,不能简单的从发包方或者接包方一个方面寻找答案。因为“一个巴掌拍不响”,要实现软件外包,必须双方都有需求、有能力、愿合作才行。而且不能把目光只盯在中国一个国家,还需要从全球软件行业的整体来看待和理解。

为什么软件外包能发展的这么快呢?主要原因在于通过软件外包,发包方和接包方都获得了可观的利益,非常具有现实意义。说得更简单一点,就是双方都获得了好处,大家是互相合作的伙伴。

作为发包方,可以获得下列好处:

  • 降低软件项目成本
  • 提高软件质量
  • 缩短软件开发周期

怎么理解软件外包能较低软件项目成本呢?

大家可能听说过,美国的软件技术人员的工资比中国同等水平的人员要高5到10倍,所以不少美国的软件开发公司都把软件开发和测试的工作,发到中国的软件外包公司来作,可以大幅度的降低成本。对于中国的软件外包公司,他们从国外客户承接外包项目,可以获得很稳定也很好的项目价格,所以很乐意做软件外包服务商(Vendor)。

说到通过软件外包提高软件质量,可能很多人不理解。举个例子就明白了。

美国微软(Microsoft)公司是全球最大的软件公司,现在正在开发的Windows Vista新操作系统,需要同时发布多个语言的本地化软件,例如英语、简体中文、繁体中文、日语、韩语、德语、法语、阿拉伯语等。这些语言的本地化版本的翻译、编译、测试,如果全部在微软公司内部完成,那么微软需要招聘大量的精通每种语言和软件技术的工程师,否则语言质量肯定不能保证。如果把这些工作外包给专业的软件本地化外包公司,软件本地化是这些外包公司的强项,所以可以显著的提高软件质量。

软件外包能缩短软件开发周期的道理很容易理解,如果很复杂的软件开发工作都在一个公司内部完成,那么可能耗费1年甚至几年的时间。例如,如果Microsoft Windows Vista的软件需求分析、框架设计、详细设计、软件编码、软件测试、软件多语言本地化等工作都在Microsoft公司内部实现,那么微软可能需要招聘很多的内部员工,动用很多的项目经理管理这些人员,对这些人员进行技术、语言和流程培训,花费的时间肯定比外包更长。这样的软件即使开发出来了,等到能够发布这些技术可能过时了,其他竞争对手的相似产品肯定已经早已占领了市场。

现在是网络信息时代,时间就是金钱,速度就是效益,“快鱼吃慢鱼”,实现抢先推出新产品,谁就可能占领更多的市场份额。


[3] - 为什么要承接软件外包?

前面提到了软件开发商通过软件外包,可以达到降低软件成本、提高软件质量和缩短开发周期的好处,所以大型软件开发商很愿意把软件的一部分工作外包给专业的软件外包公司。

那么软件外包公司为什么愿意从事这种接包工作呢?

我们可以从以下几个方面分析这个问题。

  • 承接软件外包工作可以获得稳定的、较高的利润
  • 承接软件外包可以学习软件的先进技术和管理方法
  • 承接软件外包可以加速企业国际化步伐

下面对这几点进一步说明。

软件外包的接包方都是人力成本较低的国家和地区,例如中国和印度的软件开发和测试工程师的平均工资比欧美同等级别的人员要便宜很多。这样看来即使发包方发来的外包项目的价格不很高,但是对于这些国家的外包公司看来,还是价格很高的。

通过举个实际的例子来算算“经济帐”,假设美国软件公司发给中国软件外包公司做软件测试的项目,按照没个测试工程师每小时15美元计算,每天8小时公司可以获得120美元。每个月按照22天计算,外包公司可以从每个测试工程师获得120*22=2640美元。如果按照1美元=8人民币元计算,是21120人民币元。一般软件外包公司发给员工的工资大约4000到8000人民币元,另外除去运营成本和各种税费,外包公司获得的纯利润高于15%到20%。

15%到20%的纯利润是个什么程度?熟悉中国软件开发行业的同学可能知道,由于中国开发的通用软件受到盗版的影响,利润非常少,甚至无法收回投资。另外,中国软件行业竞争太激烈了,经常为了投一个“招标项目”,大家靠拉关系,拼价格,即使最后抢到这个项目,价格已经很低了,再加上内部开发成本逐年上升,经常是项目做完了,所赚无几,甚至赔钱。2005年中国软件开发行业的利润整体下滑,有媒体报道说降到了5%。一般企业正常发展的净利润应该高于11%,否则生存就有了问题,更别谈什么发展了。

承接软件外包可以学习软件的先进技术和管理方法。软件发包方都是较为成熟的大型国际化软件公司,他们在技术和管理上积累了成功的流程和方法。对于中国软件公司,很多还停留在100人以下的小规模,很少具有开发和管理大型国际化软件的经验,也没有这方面的整体实力。通过承接大型软件公司的外包项目,可以锻炼队伍,学习各种开发和测试技术、项目流程规划,项目管理等多方面的技术。其实印度规模较大的外包公司,塔塔咨询(TCS),InfoSys等最早也是从承接美国的软件外包测试开始的,现在都超过了5万人,现在可以承接大型软件的咨询和设计任务,在美国市场上直接和IBM、HP等大型公司正面竞争。

承接软件外包可以加速企业国际化步伐。企业国际化是现在中国企业喊的最多的口号,但是真正成功实现了国际化的中国企业还不多。多年来缺乏与国外的交流,中国人的头脑形成了很多僵化的意识。承担软件外包项目,可以与国外客户直接交流,学习行业国际规则,维持良好的国际客户关系,了解国外市场的现状,为将来企业进军国际化做好物质和市场准备。

正是基于承接软件外包的种种好处,国内很多的软件公司纷纷加入软件外包测试的大军,大家就像发现了新的金矿,乐词不彼,准备大干一场。甚至某些以开发产品或专业服务为主的公司,例如用友、东软和神州数码都加大了承接外包项目的力度。

有消息称,在未来2年内,中国的软件外包公司将到纳斯达克上市,成为新的中国外包概念股。


 [4] - 做软件外包有前途吗?

俗话说:“男怕入错行”,如果你进入了一个没有前途的行业,即使你的能力再高,你的发展空间也很有限。对于,刚刚毕业的大学生,第一份工作非常重要,甚至会影响一生的职业生涯。

软件外包是全球软件行业新兴的行业,是经济全球化和软件产业全球分工的产物。大家知道全球化已经深入到我们生活的每个方面,我国的改革开放就是顺应了时代潮流。

对于中国而言,软件外包的发展更是如火如荼,属于典型的IT“朝阳行业”。每年的增长速度都在50%以上,特别对于中国的软件外包公司,他们每年的业务都是100%的速度增长,发展势头不可阻挡。

从事软件外包工作的好处之一是可以在短期内获得职业提升的机会。现在中国软件外包行业如果具有5年以上的工作经验,就可以成为外包的有经验专才了。很多大学生进入软件外包公司工作2到3年,如果学习能力和交流能力好,可以成为项目经理或者部门经理。

从事软件外包工作的好处之二是可以学习和培养国际化思维方式和工作方式。前面已经谈到,软件外包是全球合作的工作方式。做软件外包工作,有机会学习先进的软件设计和测试方法,学会管理大型的、多个团队协作的软件项目,要和多个国家和地区的技术人员和管理人员进行英语或者日语交流。这样可以提高语言表达能力,团队交流能力,遵守科学的生产流程,成为熟悉国际市场和技术的职业人士,对于将来的职业发展大有帮助。

而如果毕业后到一个小的软件公司工作,由于中国的小软件公司很多都是10多个或者几十个人的手工作坊式公司,企业内部缺乏完善的流程,管理混乱,粗放式经营,依靠个别高手的能力,这样的环境很不容易学习到关键技术,而且还会养成随意的、不善交流的独立自我的工作习惯。这种习惯一旦养成对于今后的职业发展是大为不利的。

因此,大学毕业生投身做软件外包,就是进入了一个发展前途十分可观的“朝阳行业”,通过自身的不断努力,有希望在短期内,成为熟悉国际化行业规则的技术和管理人才,成为职场上非常有竞争力的软件专家。


[5] - 外包公司是怎么工作的?

进入软件外包企业后,为了尽快适应新环境,完成日常工作,需要了解软件外包公司是如何安排工作的。

从外包的内容看,现在大多数中国软件外包公司从事两种内容的工作,第一是软件设计和编码的外包(即开发外包),第二类是软件测试外包。

从工作的地点看,软件外包公司的员工的工作形式分为两种,第一是被派遣到发包方(客户)的公司进行工作,这种形式称为“On-site外包”。第二式在软件外包公司内部工作,称为“In-house外包”。

如果同学们到人才招聘网站看看外包公司的招聘广告,经常能看见赴微软,赴IBM从事软件开发或测试的招聘职位。这种形式就是“On-site外包”。举个例子,软件外包公司A招聘了从事软件外包测试的同学小李到微软亚洲工程院从事微软的软件测试,虽然小李在微软的公司工作,但是他隶属于A公司,工作上受到A公司和微软公司的领导,A公司每个月按照A公司的工资标准给小李发工资。一般来说,“On-site外包”的工程师的技术水平要求的更高些。

在笔者看来,“On-site外包”工作方式只是软件外包的初级形式,如果软件外包的服务模式成熟之后,越来越多的外包将以“In-house外包”的形式实现。下面介绍“In-house外包”的工作方式。

所有的软件外包公司都是以“项目”的形式,组建项目团队开展外包工作。一个“项目”就是一个有着明确的任务,明确的开始和结束时间,以及明确的质量要求的工作。项目团队就是为了完成一个项目组建的有不同角色的多个人的小组,一般安排一个项目经理,一个或几个组长,多个工程师。

项目经理主要制定项目计划、资源安排、内部交流和外包的客户交流。组长为每个工程师分结和安排具体的任务,跟踪项目进度,解决技术问题。工程师根据组长分配的任务按照进度和质量完成每天的工作,并且报告进展和遇到的问题。

项目经理负责周期性的向“客户”报告项目进展情况,同时把客户反应的问题和来自客户的最新文件和要求等传达给项目组。

通常项目经理和组长都是由具有管理和技术经验的员工担任,对于刚刚加入软件外包公司的大学生来说,绝大多数都是从工程师的职位做起的,先经过外包公司的内部培训,然后进入项目组实习,转正之后称为工程师,负责具体的开发或测试工作。

顺便说说,不少优秀的大学生,专业技术非常好,学习能力由特别强,善于思考和总结,也善于与其他人交流和合作,这样的学生很快就可以在项目团队中脱颖而出,经过一年或者两年可以从普通工程师晋升到测试组长甚至项目经理。我的不少同事就是这样过来的,这是因为软件外包发展得非常快,客户发来的软件外包项目越来越多,项目团队越来越多,每个项目都需要项目经理,所以从事软件外包具有很大的职业发展空间。

现在总结一下软件外包公司的工作方式:

  • “On-site外包”或者“In-house外包”方式
  • 按照项目团队的方式工作
  • 刚进入外包公司的大学生绝大多数要从工程师做起


 [6] - 有哪些好的外包公司?

对于正在找工作的同学来说,都希望到一个规模较大的公司工作,一般来说,大公司比较规范,待遇也较高,倒闭的风险小。对于软件外包公司来说也是这样子。

同学们可以猜猜看,全球著名的高端软件外包公司有哪些?据媒体报道,比较公认的全球高端外包公司分别是IBM,HP和EDS,前两家同学们肯定耳熟能详,有些同学可能怀疑IBM,HP能算是软件外包公司吗?它们算不算外包公司不是我说的,反正做软件外包多年的老外都这么人为,人家可是全球知名的外包专家,可不是信口胡说的呀。

有的同学经常问我,国内有哪些规模较大的外包公司?哪个外包公司最好?我一般都回答不好。为什么呢?因为每个人看问题的角度不同。比如,什么是“规模较大”?是按照正是员工的人数比较呢还是按照每年的总收入确定?什么样的外包公司是“好公司”?给员工发的工资搞就是好公司吗?给员工提供专业的技术培训,而且具有很大的职业发展空间的是否就是“好公司”呢?

因此,在你问这些问题前,先要搞清楚你心目的好公司应该具有什么样的特征。

我还是从国内外包公司的普遍特征来给出这个问题的一些参考信息。

前面已经提到,我国软件外包公司属于新兴的行业,真正从事软件外包的员工如果人数超过1000人在中国就可以算是比较大的外包公司了。据了解国内最大人数的外包公司现在不超过3000人(这里需要说明一点,有些公司一开始是做系统集成的,最近才开始做软件外包业务,虽然他们的全体员工超过5000人,但是真正做软件外包的还不超过3000人)。所以同印度的某些大的软件外包公司项目,我国的软件外包公司规模普遍弱小。印度的软件外包公司超过10000人的很多,有些超过了5万人。所以有些国内的软件外包的朋友,把中国软件外包公司比作“蚂蚁”,把印度外包公司比作“大象”。

如果同学们打算做软件外包,肯定要问哪个省市的软件外包公司最多?我要告诉大家的是,中国的软件外包在各个省市的发展很不平衡。大连、北京、上海、深圳、苏州、西安等发展的相对快些。其他各个地方今年开始从政府到企业都开始提出要发展软件外包了。

关于国内软件公司的规模,同学们可以参考我国政府权威部门发布的“中国软件欧美出口工程”试点企业名单。这些公司都具有一定的规模和实力,有些记者把这些公司比喻成“中国外包的国家队”,言外之意其他的外包公司只能算是“地方武装”了。

大连的软件外包发展的最为快速,特别是对日外包做的最为成功,因为大连的政府支持,地理位置靠日本很近,可以找到很多掌握日语的软件技术人员。北京和上海的软件外包发展的时间更长,这两个直辖市凭借经济和政治的影响,吸引了大量的国外客户,人才资源很丰富,所以外包做的很早,很多欧美的大型软件公司都在这两个城市成立的研发中心。

说到外包公司,很多人首先想到的是中国本土的外包公司,其实出了本土外包公司,国外外包公司在中国的分公司也不可忽视。这些国外外包公司有的进入中国较早,有的最近一两年才在中国落户。他们凭借国外市场的良好客户关系,全球的专业品牌,先进的外包管理技术,丰富的外包经验,加上国际化的工作环境,良好的薪资待遇,吸引着很多大学生前去应聘。

最后给同学们一点建议,大家在找工作的时候与要单纯追求规模大的外包公司,中小规模的外包公司有可能发展速度更快,有可能提供很大的职业发展空间。关键是通过各种方式综合了解软件外包公司的发展前景、工作环境和个人发展空间,可以通过打听在外包公司工作的同学、朋友、亲戚、老乡,也可以上网看看外界对这家公司的报道和评论。


[7] - 软件外包公司需要什么样的人?

刚毕业的同学如果没有考研或出国留学,都有过找工作应聘的经历,不少同学都感觉找到合适的工作单位不是一件容易的事情。有些同学虽然得到了软件外包公司的应聘机会,但是面试后就没有消息了。

而一些软件外包公司的招聘人员却为找不到合适的人员而苦恼,只好发动一切可以调动的因素,解决企业人才困乏的问题。所以有人把这种现象归纳为:“高校有人没事干,企业有事没人干”。

这种现象的本质是大部分高校毕业生的综合素质达不到软件外包企业的用人要求。那么软件外包公司需要什么样的人呢?为了能够进入软件外包企业,在校学生应该如何学习和学习什么呢?

说的简单一点,企业需要的是能马上融入外包项目团队,独立承担实际外包项目任务的人。所以很多企业在招聘启事中都有“x年软件外包相关工作经验”等的硬性指标,而这些都是在校学生欠缺的地方。

现在一些外包公司都提供兼职岗位(Freelancer),这是在校学生(尤其是即将毕业的学生)参与社会实践的好机会,应该抓住这些实习机会,积累工作经验。另外,如果在这些企业实习期间表现优秀,毕业后有机会成为公司的正式员工。

软件外包企业对待大学毕业生更看重学生的学习能力。刚毕业的大学生就像一块好的毛坯钢材,材质优良,如果这些学生有较好的主动学习能力,进入企业后经过几个外包项目的实践,积极思考,善于总结,成长很快。企业不欢迎凡事不经过大脑思考,大小问题都要向主管求助的“懒汉”员工。

企业需要具有职业精神的员工。职业精神包括很多方面的内容,包括对工作的热情投入,积极与团队成员交流,具有合作精神,以企业利益为重。而不欢迎喜欢与企业讨价还价,抱怨企业提供的发展空间不够大的学生。

由于软件外包服务行业是为客户提供服务的行业,很多外包项目的具体任务一般比较琐碎、枯燥,例如按照客户提供的软件框架进行编码,按照客户提供的测试用例执行软件测试。对于刚刚毕业的学生他们都需要从这些很基础的技术岗位做起,这是对他们职业精神和做事风格的考验。

软件外包服务的很多工作就像生产流水线上的公司在拧螺丝钉,需要遵守严格的生产流程和一丝不苟的严谨精神。把这些基本工作做好了,才能取得企业的管理人员的信任,才有机会承担更复杂更大责任的工作。

一些刚毕业的学生经常心高气傲,很鄙视这些繁琐枯燥的工作,感叹埋没他们的才华,这是没有摆正工作心态的表现。外包公司非常欢迎愿意做看似琐碎的工作同时有能力做好的同学。其实做好这些看似琐碎的工作,当好拧螺丝的工人,就是不简单,他的未来就会不平凡。道理很简单:基础打好了,万丈高楼平地起。

总结起来,外包企业需要具有一定的外包工作经验,主动学习能力强,团队合作精神好,愿意从琐碎的技术工作做起,而且有能力做好“小事”的人。

海尔公司总裁张瑞敏有句名言说得非常好,对于准备到软件外包公司工作的同学非常有启发,他说:“把一件简单的事做好就是不简单,把每一件平凡的事做好就是不平凡”。


 [8] - 哪些人不适合做软件外包技术人员?

大千世界,无限精彩。作为软件行业的新领域,软件外包吸引着越来越多的人投入这个行业。每个行业都有行业的行规和准则,并不是任何人都适合从事软件外包行业的。

哪些人不适合从事软件外包呢?由于本文的读者针对即将毕业的大学生,也适用于准备加入软件外包公司的新人,所以我们可以把问题缩小范围:哪些人不适合做软件外包服务的技术人员?

回答什么人不能做软件外包,也就是哪些人做不好软件外包,需要先了解软件外包服务行业的工作性质和对人的综合要求。软件外包是为客户提供专业技术服务的行业,而且现在的软件外包企业的客户大都来自国外,客户对外包公司人员要求比较严格。另外,外包公司的工作非常具体和琐碎,需要一丝不苟。

软件外包行业的这些特点,决定了以下三种类型的人不适合做软件外包的技术人员:

第一种人是外语不过关的人。

语言是交流工具。如果客户是欧美客户,英语交流是必不可少的。如果客户是日本公司,对日语要必须熟悉。作为初级的外包技术人员,需要阅读和写作大量的文档和邮件,这些都需要良好的英语能力。很多英语不过关的人员不容易通过外包公司的笔试。对英语的要求,需要达到熟练阅读英文文档,写作专业的测试缺陷报告和日常邮件写作的程度。

外包公司强调英语的重要性,这是做好工作的基础,因此,请在学校里、公司里利用一切条件自觉学习英语,养成习惯,从阅读理解学习。把英语阅读和写作养成一个习惯,终生受益。

第二种人是痴迷于钻研软件高深技术的人。

软件外包服务的很多工作都是非常琐碎的,看上去没有多少高深新技术的事务性工作。例如,对日软件外包的项目,客户已经编制好了程序框架,需要变成人员根据他们的规范编写代码和每天工作进度日志。不少外包编程人员抱怨客户限定的过于严格,没有足够的自我创造的空间。对于软件外包测试人员,最常见的工作就是执行客户编写好的测试用例,报告软件缺陷,很少有机会从软件项目的全局高度制定测试计划,确定测试方案和策略,安排资源和进度。

如果你对软件编程的各种新技术无限热爱,习惯于一个人无拘无束的从事软件产品的开发,最好不要去软件外包公司,否则很难发挥你的聪明才智。这样的人更适合自己创业开发独立的软件产品,或者到中国中小型软件公司当软件开发工程师。

第三种人是大事做不来,小事不愿做的人。

正如前面说过的,很多软件外包工作非常具体和琐碎,需要非常好的做事态度,满足客户各种合理的和不合理的要求。有些同学到软件外包公司工作不久就感到失望了,抱怨工作枯燥,看不到前途。这些都是刚参加不久的人容易产生的错误认识。

在任何软件外包公司,如果个人的工作能力非常突出,很容易被领导赏识和提升,因为软件外包发展太快了,对人才的需求非常强烈。但是如果不从具体的琐碎的小事做起,并且把小事做好,怎么能证明你可以把大事做好呢。

任何公司之所以能够生存、发展、壮大,必尤其成功之处,不要觉得你必老板高明很多。比较聪明的同学会放平心态,从学徒学起,把每一件工作都做好了,自己的长处得到发挥,对自己的前途发展大有帮助。

总结起来,不善于外与交流的,痴迷于钻研软件高新技术,不能踏踏实实工作的人,不适合到软件外包公司从事软件技术工作。


[9] - 如何通过软件外包公司的面试?

如何通过软件外包公司的面试?这是很多同学都很关注的问题。面试成功来自于应聘者自身的综合实力和运气。为了提高面试成功率,请按照以下几个方面进行准备。

(1)制作有吸引力的求职简历

外包公司的招聘专员每天都会收到几十封甚至上百封求职简历,如果你的简历很平淡,可能很快从招聘专员的眼下溜走,失去了面试的机会。

什么是有吸引力的简历? 简单地说就是让看到你简历的招聘专员相信你就是他们正在寻找的最合适的人。因此,你的简历要简明扼要,列举出符合他们要求的条件和相应的客观证据。要明白求职简历目的就是获得面试的机会,否则你的水平再高,也不可能进入招聘专员的“法眼”。

如何写出具有吸引力的简历,现在很多资料都比较详细,但是最重要的一点是实事求是,反对夸张和吹嘘。把你的技能和经验按照招聘职位的要求进行内容和形式的组织即可。

(2)准备面试

  • 了解要去面试的公司,可以浏览公司的网站,媒体报道,同学和朋友的介绍。
  • 了解公司的行业,规模,现状和发展概况。
  • 技术准备,准备应聘职位要求的技能
  • 模拟面试场景(包括英语自我介绍和书面答题)
  • 准备自我介绍、各种证书、笔试和面试解答问题
  • 计划乘车路线和穿着打扮等外表形象

(3)参加面试

  • 准时
  • 诚实
  • 积极
  • 友好
  • 不必不亢
  • 注意细节
  • 沉着冷静
  • 避免争论
  • 小心“陷阱”
  • 充分发扬长处
  • 展示个人综合能力
posted @ 2006-10-03 00:26 方佳玮 阅读(1349) | 评论 (0)编辑 收藏

初次写js,感觉很不错

需求:
1. session 传值初始化时钟,格式 hh:mm:ss
2. 时钟在页面上显示倒计时功能
3. 时间到触发点击按钮事件

<body MS_POSITIONING="GridLayout" onLoad="window.setInterval('Clock()', 1000);">
        
<script type="text/javascript">
        
        
function Clock(){                  
            
var init = clock.innerText;
            
var stop = new Number("0");

            
var hms = new String(init).split(":");
          
var s = new Number(hms[2]);
          
var m = new Number(hms[1]);
          
var h = new Number(hms[0]);
          
          
          
          
if(stop == 0){
              
if(s == 0){
                  
if(m == 0){
                      
if(h == 0){
                          stop 
= 1;
                          
var e = document.getElementById("finish").click();
                      }

                      
else{
                          h
--;
                      }

                      m 
= 59;
                  }

                  
else{
                      m
--;
                  }

                  s 
= 59;
              }

              
else{
                  s
--;
              }

          }

          
var ss = s < 10 ? ("0" + s) : s;
          
var sm = m < 10 ? ("0" + m) : m;
          
var sh = h < 10 ? ("0" + h) : h;
          init 
= sh + ":" + sm + ":" + ss;
          clock.innerText 
= init;         
        }

        
</script>

<form id="Form1" name="Form1" method="post" runat="server">
<SPAN id="clock"><STRONG>
<%=(string)Session["time"]%></STRONG></SPAN>
<asp:button id="finish" runat="server" Width="70px" Height="20px" Text="完成提交"></asp:button>
</form>
posted @ 2006-10-01 00:35 方佳玮 阅读(1091) | 评论 (1)编辑 收藏

我大二时是java初学者,很多用法不当,哈哈,现在看来确实有点幼稚。当时同时在学数据结构。把c改编成java。现在把自己的作业和大家分享。

地址:http://www.java-cn.com/bbs-jsp/show.jsp?forum=base&id=142767
posted @ 2006-09-15 11:34 方佳玮 阅读(685) | 评论 (0)编辑 收藏

在公司工作了1个多月了,最近突然领悟了,领悟了何为计算机专业。
 
迷恋Java不是错,因为这是应届毕业生轻松进入好公司的敲门砖,但是也可以说是错!
 
导师何立勇对我说:“是人使用工具,而不是工具使用人”,我现在完全领悟了,Java,vb,.net,任何开发语言,任何开发技术,所有计算机相关的技术知识都只是完成客户需求工具而已。有人喜欢java,喜欢struts,hibernate,spring,鄙视老的技术,鄙视.net,鄙视vb都是不正确的,也是一个初级程序员的思想。
 
我们作为计算机专业的,为了什么,其实为了有实力更好地使用工具满足客户需求。读研,读博也就是这个目的,英语流利精通也是这个目的。我以前放弃英语和计算机基础知识从长远看是错误。所以既然我已经有实力求职,我以后也没必要拣了芝麻丢了西瓜,在公司好好做个java程序员,同时学好英语学好计算机其他重要知识和工作相关的知识,有必要的话会考硕士,更好的成为优秀的工具使用者,以后才不会永远只是个java程序员。
 
但是,独立解决问题的能力,动手能力,开发经验,我在大学里已经做得非常不错了,确实成为我进入NCS的结识的敲门砖。(NCS是新加坡外企,新加坡人会说中文,否则我也进不去,因为美国外企英语口语面试,只能说我运气好而已)
所以告诫所有同学,包括考研的同学,理论知识,英语非常重要,但如果没有独立解决问题的能力,动手能力,开发经验,你也很难成功!
就像我认识的一个南京大学研究生,在读时排名前5,毕业后由于没有以上敲门砖最后找不到好工作,于是参加8个月的J2ee培训,多累啊,现在惠普工作月薪8000,以后会更高,这个是活生生的例子。但也只有名牌大学硕士同时有敲门砖才能拿那么高的,英语不好我是肯定进不了惠普的。
 
绕了个大圈回到起点,我要开始拣西瓜了。。。。。。


作为计算机专业的,实战经验,理论,英语,3者都要好,而不是选择其一钻牛角尖,
实战经验好的虽然找工作不难,但好的公司,高的职位是妄想。3者都平庸的话那就更没出路了,如今太多人3者平庸了。在今后的时间里,我要平衡3者,都要提高,我想我领悟地还不算晚!以前小错中有对的地方,但不能让其成为大错。

这点确实2班的个别同学,比如领导做得非常好,我班目前没有。这就是为何IT行业,有人拿数万月薪,有人拿8000月薪,有人拿2000,3000月薪,有人虽然计算机专业却压根进不了IT行业。

不同选择重视不一样,想本科毕业就业的,想在1,2年内拿4000~6000月薪的(上海),请重视实战经验,并且逐步提高理论和英语,以后跳槽到好公司也有资本。想考研的,重视后两者,在读研时千万重视实战经验。这个经验相当于受过至少半年以上培训的水平。毕竟时间有限,本科也就这么4年,3项全能都是高手,实在是难!

(自我介绍,上海华理计算机专业,今年9月大四,一直追求j2ee,扔掉专业扔掉英语,如今领悟)

posted @ 2006-09-02 23:52 方佳玮 阅读(917) | 评论 (4)编辑 收藏

1.Method_Add
/*
输出:
It is now 星期四 2006/08/17 at 05:55:57 下午 CST
Two years ago was 星期二 2004/08/17 at 05:55:57 下午 CST
*/

package  api.java.util.Calendar;

import  java.text.SimpleDateFormat;
import  java.util.Calendar;

public   class  Method_Add  {
    
public   static   void  main(String[] a)  throws  Exception  {

        Calendar now 
=  Calendar.getInstance();
        
        SimpleDateFormat formatter 
=   new  SimpleDateFormat(
                
" E yyyy/MM/dd 'at' hh:mm:ss a zzz " );
        System.out.println(
" It is now  "   +  formatter.format(now.getTime()));
        
/*
         * public abstract void add(int field, int
         * amount)根据日历的规则,为给定的日历字段添加或减去指定的时间量。
         
*/

        now.add(Calendar.YEAR, 
- 2 );
        System.out.println(
" Two years ago was  "
                
+  formatter.format(now.getTime()));
    }

}


主要经验值获得:
1. java.text.SimpleDateFormat 的用法
2. java.util.Calendar.add( ) 的用法,如何进行日期计算。

----------------------------------------------------------------------------------

2.Class_GregorianCalendar
/*
输出:
136 days remain in current year
*/

package api.java.util.Calendar;

import java.util.Calendar;
import java.util.GregorianCalendar;

public class Class_GregorianCalendar {
    
public static void main(String args[]) {

        Calendar calendar1 
= Calendar.getInstance();
        
int doy1 = calendar1.get(Calendar.DAY_OF_YEAR);

        
int year = calendar1.get(Calendar.YEAR);
        
        
//在具有默认语言环境的默认时区内构造一个带有给定日期设置的 GregorianCalendar
        Calendar calendar2 = new GregorianCalendar(year, 1131);
        
int doy2 = calendar2.get(Calendar.DAY_OF_YEAR);
        
        
//今年最后一天减去今天的剩余天数
        int days = doy2 - doy1;
        System.out.println(days 
+ " days remain in current year");
    }

}


主要经验值获得:
1. java.util.GregorianCalendar 的作用
2. 如何返回指定的日期的Calendar

次要经验值获得
1. 如何计算据今年结束的天数

----------------------------------------------------------------------------------

3.Class_Calendar
/*
输出:
ERA: 1
YEAR: 2006
MONTH: 7
WEEK_OF_YEAR: 33
WEEK_OF_MONTH: 3
DATE: 17
DAY_OF_MONTH: 17
DAY_OF_WEEK: 5
DAY_OF_WEEK_IN_MONTH: 3
AM_PM: 1
MILLISECOND: 92
ZONE_OFFSET: 8
DST_OFFSET: 0

*/

package api.java.util.Calendar;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class Class_Calendar {
    
public static void main(String[] a) {
        Calendar calendar 
= new GregorianCalendar();
        calendar.setTime(
new Date());

        System.out.println(
"ERA: " + calendar.get(Calendar.ERA));
        System.out.println(
"YEAR: " + calendar.get(Calendar.YEAR));
        System.out.println(
"MONTH: " + calendar.get(Calendar.MONTH));
        System.out.println(
"WEEK_OF_YEAR: "
                
+ calendar.get(Calendar.WEEK_OF_YEAR));
        System.out.println(
"WEEK_OF_MONTH: "
                
+ calendar.get(Calendar.WEEK_OF_MONTH));
        System.out.println(
"DATE: " + calendar.get(Calendar.DATE));
        System.out.println(
"DAY_OF_MONTH: "
                
+ calendar.get(Calendar.DAY_OF_MONTH));
        System.out
                .println(
"DAY_OF_WEEK: " + calendar.get(Calendar.DAY_OF_WEEK));
        System.out.println(
"DAY_OF_WEEK_IN_MONTH: "
                
+ calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH));
        System.out.println(
"AM_PM: " + calendar.get(Calendar.AM_PM));
        System.out
                .println(
"MILLISECOND: " + calendar.get(Calendar.MILLISECOND));
        System.out.println(
"ZONE_OFFSET: "
                
+ (calendar.get(Calendar.ZONE_OFFSET) / (60 * 60 * 1000)));
        System.out.println(
"DST_OFFSET: "
                
+ (calendar.get(Calendar.DST_OFFSET) / (60 * 60 * 1000)));
    }

}


主要经验值获得:
1. Calendar 的一些变量和方法用法

----------------------------------------------------------------------------------

4.
posted @ 2006-08-17 18:00 方佳玮 阅读(1843) | 评论 (1)编辑 收藏

     摘要: 1. Constructor /**/ /* 介绍:Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。输出:java.util.ArrayList: Collection java.util.ArrayList: int java.util.Ar...  阅读全文
posted @ 2006-08-15 14:09 方佳玮 阅读(2966) | 评论 (1)编辑 收藏

     摘要: GWT QQ 群号:28310588用过gwt的都知道,对一个按钮button做点击事件很简单,但要做鼠标事件,比如over,up,leave就没办法了,但extends Button就能做到,以下就是这个例子:我自己写的package mypack.client;import com.google.gwt.core.client.EntryPoint;import com.google.gwt....  阅读全文
posted @ 2006-08-02 10:15 方佳玮 阅读(1689) | 评论 (2)编辑 收藏

GWT QQ 群号:28310588

http://www.gwtpowered.org/


有超多的GWT组建,比如:

超好的日期输入[插图][演示]


可排序的table:[插图][
演示]



还有很多其他的,大家自己去寻找需要的组件。自己再修改,扩展,汉化变成自己的超级GWT组件吧!
posted @ 2006-08-01 11:17 方佳玮 阅读(2306) | 评论 (4)编辑 收藏