J2EE剑侠行

直觉我的J2EE应用生涯,打造我心中的一把利剑。

常用链接

统计

技术链接

最新评论

2005年12月21日 #

找到一个好用的UML建模工具-argouml

 很不错的一个UML建模工具-argouml
     argouml下载地址
     我一眼就看上他的原因是:生成的用例和包图可能直接生成JAVA代码,而且准备无误,这正是我要找的。
     我想:以后使用一些框架的话,可能由PD生成一些实体,然后Hibernate生成pojo等,加入到argouml,然后根据一个框架的特性生成一些包 和类.就等于详细设计了吧.应该来说是比详细设计还实用的东西.总比哪些WORD文档好吧.还有让人看不懂的概要设计.
    我想从技术出发,这个是一条比较适用的路子.下班了.我明天将会汇报一下我使用的情况和一些范例.
    反过来又想像.这好象是一个组合的脚手架.好象ROR的零星操作步骤.应该学习.ROR毕竟是一个新生事物,JAVAEYE的推广也需要一个时间.如果像我这样的打工,混口饭吃的人还是专心的研究J2EE好一点.否则明天就没有饭吃了.

    呵呵.我的文章可被JAVAEYE收回到水贴里了,可能自己的能力不如人吧,好好学习,天天向上,如果看客有什么好的工具和软件生产思路,可以共同交流。

posted @ 2007-06-20 13:29 @家军 阅读(1835) | 评论 (1)编辑 收藏

ROR:习惯约定优于配置(学习ROR的第一天)

今天学习了一下ROR,有一些学习经验东西要与大家分享。
给ROR加一个座右铭--------狭窄心肠的日本产物。
首先,不要一个一个的下载Ruby,Rails,建议使用一键安装,下载地址如下:
InstantRails-1.3-win
版本说明:ruby 1.8.4 (2005-12-24) [i386-mswin32]
其次,下载一个目前为止比较好的一个ROR的实践工具:RadRails
下载地址:radrails-0.7.1-win32
接下来,设置一下Radrails的环境
1)、Windows/perferences/Ruby/Installed Inteperters/ ->add ruby所在路径:比如D:\InstantRails\ruby\bin\ruby.exe
2)、Windows/perferences/Rails/Configuration ->Rails path:比如D:\InstantRails\ruby\bin\rails
->Rake path:比如D:\InstantRails\ruby\bin\rake 绝不是bat/cmd
->mogrel path:比如D:\InstantRails\ruby\bin\mongrel_rails绝不是bat/cmd

有了如上的配置后,就只需要和在JAVA当中ANT一样使用。(成功用过APPFUSE的人就不用害怕了)

看看日本人写的第一步:
1),在RadRails中创建一个Rails Project,怎么样会出来一堆的东东。
2),进入DOS命令吧,后面的工序都是这样的,好象买了海尔的洗衣机,第一次是送货、第二次是用户回访,第三次是.....
进入到你的项目处,运行ruby script\generate controller MyTest,
则得到的服务如下:
exists app/controllers/
exists app/helpers/
create app/views/my_test
exists test/functional/
create app/controllers/my_test_controller.rb
create test/functional/my_test_controller_test.rb
create app/helpers/my_test_helper.rb
修改一下my_test_controller.rb

代码
       class  MyTestController  <  ApplicationController
      def index
        render_text 
" Hello world!! "
      end 
      end

在浏览器里输入:http://127.0.0.1:3000/my_test/
会出现 Hello world!!字样,
不过有意思的是你可以输入:http://127.0.0.1:3000/My_test/
http://127.0.0.1:3000/My_Test/
http://127.0.0.1:3000/my_Test/
都可以得到这个值,可能没有JAVA哪样严格吧。
3)、还有对数据库的操作,要配置一个database.yml(好象Log4j的东东)
4)、创建数据库表的时候只能够使用复数起名,比如User就不行,只能够起Users
下面只要执行几个命令就可以使用增删改查了。
如下是我的操作,下班了,就不多写了,例子能够说明一切问题:
代码
 1 E:\RORProject\demo>ruby script/generate model user
 2 
 3       exists  app/models/
 4 
 5       exists  test/unit/
 6 
 7       exists  test/fixtures/
 8 
 9       create  app/models/user.rb
10 
11       create  test/unit/user_test.rb
12 
13       create  test/fixtures/users.yml
14 
15       exists  db/migrate
16 
17       create  db/migrate/001_create_users.rb
18 
19 E:\RORProject\demo>ruby script/generate controller user
20 exists app/controllers/
21 exists app/helpers/
22 create app/views/user
23 exists test/functional/
24 create app/controllers/user_controller.rb
25 create test/functional/user_controller_test.rb
26 create app/helpers/user_helper.rb
27 

修改user_controller.rb如下:
代码
1    class UserController < ApplicationController
2        scaffold:user
3    end

最后你的浏览器当中输入:http://127.0.0.1:3000/user/list,就包括了对数据库表的四个操作.当然你也可以自己定义四个操作的任意一种.
最后总结:
ROR可能是敏捷开发的一个好实践,但是我觉得他完成复杂应用进不会有大做为,而至于这一点还需要再做探究。不过现阶段最好的需求就是能够给用户快速的写出一个不完整的DEMO,这一点为以后打单取得主动。

posted @ 2006-09-29 11:47 @家军 阅读(1987) | 评论 (1)编辑 收藏

三个JAVA文件完成你的MVC应用

     摘要: 只需要你三个JAVA类和两个配置文件,就可以完成你的MVC应用,我们就做一个示例吧。本文以一个登录为例。第一个JAVA文件Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->/**======================================...  阅读全文

posted @ 2006-09-29 11:43 @家军 阅读(1890) | 评论 (3)编辑 收藏

struts标签,请你走开(系列一)

在项目开发的很多时候,用户需要更友好,更容易理解的操作界面,而为了能够达到这种表现界面,struts标签显得力不从心,本人经过几个项目的开发当中 逐渐的摈弃了struts标签,而由JSTL来做为JSP页面的表达者。
struts标签之死穴一 不支持嵌套
看看这种常见的需求吧。一个用户隶属于一个职能部门,比如
项目要求 职能部门有五个(乱写的)
1、企划部
2、网络集成部
3、行政部
4、营销部
5、产品部
项目要求 一共有二个员工
1、张三 隶属于行政部
2、李四 隶属于营销部
而你想把张三和李四都列表出来,显示为如下:
姓名 部门名称
张三 行政部
李四 营销部
而且还需要用户的列表链接到修改页面当中(假如只修改部门)应该如何做呢。
在使用struts标签是很难做到的,除非你非常不在意内存的使用(乱写技术性代码)
看看JSTL是如何做的吧。
从STRUTS的ACTION当中加载两个对象

List GetAllDept  =  UserDAO.GetAllDept(); // 取得所有部门

List GetALLUser 
=  UserDAO.GetAllUser(); // 取得所有用户

request.setAttribute(
" View_Dept " , GetAllDept);

request.setAttribute(
" View_User " , GetALLUser);
在页面当中加入对JSTL的引用
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

然后写代码如下:
<table>

<tr>

<td align="center">

<href="User.do?method=EditUser&UserId=<c:out value='${View_User.UserId}'/>">

<c:out value="${View_User.UserName}" /> </a>

</td>

<td align="center">

<c:forEach items="${View_Dept}" var="View_Dept">

<c:if test="${View_User.Dept.DeptId==View_Dept.DeptId}">

<c:out value="${View_Dept.DeptName}" />

</c:if>                            

</c:forEach>

</td>

</tr>

</table>

其中View_User.Dept.DeptId表示USER表与DEPT表的一个关系(外键)
你就可以看到所显示的列表了。

还有如果在修改用户时,则也与上面的差不多,首先在ACTION当中加入:

String ModifyUserId = request.getParameter("GroupUserId");

if (ModifyUserId == null && ModifyUserId.equals("")) {

//这是出错处理

request.setAttribute(
"UserMsg""User.ValidateUser");

return mapping.findForward("Fail");

}

DynaValidatorForm UserActionForm 
= (DynaValidatorForm) form;

User user 
= UserDAO.GetUser(ModifyUserId);        

List GetAllDept 
= UserDAO.GetAllDept();//取得所有部门

request.setAttribute(
"View_Dept", GetAllDept);

UserActionForm.set(
"User", User);
然后页面当中显示如下(部门为LISTBOX),例子当中只显示部门
<html:select property="DeptAsString">            

<c:forEach items="${View_Dept}" var="View_Dept">        

<c:choose>                        

<c:when test="${User.Dept.DeptId==View_Dept.DeptId}">

<option    value="<c:out value='${View_Dept.DeptId}' />"selected>    

<c:out value="${View_Dept.DeptName}" />            

</option>                            

</c:when>                            

<c:otherwise>                        

<option value="<c:out value='${View_Dept.DeptId}' />">        

<c:out value="${View_Dept.DeptName}" /></option>        

</c:otherwise>                        

</c:choose>

</c:forEach>

</html:select>

可以看到HTML的SELECT有一个DeptAsString,你可以在FORM当中指定一个STRING的FORM属性。
这样用户的要求就可以完成了。
本次只说明方法,而代码没有经过测试。希望大家多多观注我的BLOG,下一次将臭骂ACTIONFROM不支持的DATE类型及解决方法。

posted @ 2006-09-25 16:36 @家军 阅读(443) | 评论 (0)编辑 收藏

用二维数组管理好你零乱的状态、分类和其它常用选项

     摘要: 在大家的编码过程当中,有没有遇到过这么一种情况,很多零乱的状态、分类和其它常用选项常常是定义死了。但是没有一个完整的东东来约束他,在每个模块当中使用相关的信息时,往往重新COPY一次,或者COPY过来修改一次。如果多人协作的话,务必会让代码变的零乱、不好管理等。
本次主要是把一些静态的分类、状态或者其它常用选项使用二维数组管理起来。如果你是一个使用JSTL或者STRUTS做前台表现的话,你就更应该好好关注了.......  阅读全文

posted @ 2006-09-05 13:31 @家军 阅读(1267) | 评论 (0)编辑 收藏

如果失去工作会怎么办?

    在工作当中,遇到了一个不明智的上级,我是刘罗锅,但是领导不一定是乾隆。设计当中的争执成为私下做对的理由,从此,我感觉到今年的财运不佳。
    因为工作当中的争执,而让领导失去了面子??我在郁闷当中,为什么呀!好事反而成了坏事。
    领导的报复心理,让我失去了绩效,所以我感觉到财运不佳。我很想跳出这个魔鬼圈,是不是能够改善一下自己的经济收入呢?正在想离开这个公司......
    发现自己的软肋:UML整体设计(最好有代码生成)和XP敏捷开发。近期需要加强这两方面的学习,可以以权限设计为UML做为训练(生成代码??),以CRM->VtigerCRM为业务主线,做一个XP开发,不过VtigerCRM的表设计真是很糟糕,Indiea人呀。
    今年的公司很乱,是一个很糟糕的管理层,可能我以后离开这个公司后才感觉到领导者的“聪明才智”吧!完全在内耗当中生存。我已经被领导国边缘化,我会在灰色的区域彷徨很长的时间,或许公司另有高人吧,我已经被领导逐渐忽视,自己发光的时间也只有一年,好象知了一样。
    “人贵有自知之明”,如果领导没有重视,只是为了发挥自己的最低性能的话,我完全有很多的时间来学习知识,我很庆幸自己和开源代码有很大的信心,我将在以后的时间里,为开源界展示自己的能力。
    首先要把自己学习到的知识透明化,其次我会在开源中小型的CRM软件当中做出自己应有的贡献。

posted @ 2006-07-24 11:37 @家军 阅读(459) | 评论 (1)编辑 收藏

struts表单 vs JSTL表现之多条件查询示例

    struts表单主要是利用actionform来取得JSP页面所有的request的,所有的Struts标签无非在取得request当中的所有INPUT,并赋值回标签值的,同理,JSTL能够在JSP表单当中轻易的表现要输出的结果。
    如果你是高手,你就知道这个标题有误,是的,struts表单与JSTL表现没有可比性,但是如果我们要在实现一个多条件的查询页面时,这个比较就比较有效了。
    我不妨比较一下利用struts表单的查询实现 和 利用JSTL做为表现而实现的查询功能有什么不同,让读者寻其方便。
    示例说明:
    用户表-USER
    username  用户名称
    loginid   登录ID
    sex       性别
    一、利用struts表单的查询实现
        实现步骤:
        创建多条件的序列化对象(java)->在struts.config当中申明actionform->Action当中实现->输出结果
       
    /** The value of the simple userName property. */
    
private java.lang.String userName;
    
/** The value of the simple loginId property. */
    
private java.lang.String loginId;
    
/** The value of the simple sex property. */
    
private java.lang.String sex;
    
/**
     * Return the value of the USER_NAME column.
     * 
@return java.lang.String
     
*/
    
public java.lang.String getUserName()
    {
        
return this.userName;
    }

    
/**
     * Set the value of the USER_NAME column.
     * 
@param userName
     
*/
    
public void setUserName(java.lang.String userName)
    {
        
this.userName = userName;
    
/**
     * Return the value of the LOGIN_ID column.
     * 
@return java.lang.String
     
*/
    
public java.lang.String getLoginId()
    {
        
return this.loginId;
    }

    
/**
     * Set the value of the LOGIN_ID column.
     * 
@param loginId
     
*/
    
public void setLoginId(java.lang.String loginId)
    {
        
this.loginId = loginId;
    }
    
/**
     * Return the value of the sex column.
     * 
@return java.lang.String
     
*/
    
public java.lang.String getSex()
    {
        
return this.sex;
    }

    
/**
     * Set the value of the sex column.
     * 
@param loginId
     
*/
    
public void setSex(java.lang.String sex)
    {
        
this.sex = sex;
    }
<!-- struts_fonfig -->
       
<form-bean name="UserActionForm" type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="userCondition" type="com.antbee.searchCondition.UserFindCondition" />        
        
</form-bean>
Action当中
DynaValidatorForm UserForm = (DynaValidatorForm) form;
        UserFindCondition Condition 
= (UserFindCondition) UserActionForm
                .get(
"userCondition");// 取得查询条件
List user = userManager.find(Condition,
                (iCurPageNo 
- 1* pageCon.PAGE_SIZE, pageCon.PAGE_SIZE);//呵呵,加入了hibernate的分页
具体实现:
    public List find(UserFindCondition Condition, int begin,
            
int count) {
        StringBuffer sql 
= new StringBuffer("from User as a where 1=1");              
       
if (Condition != null) {
            makeSql(sql, shipmentFindCondition);
        }
        String fsql 
= sql.toString();
        Query query 
= this.getSession().createQuery(fsql);
        
if (Condition != null) {
            setParameter(query, Condition);
        }
        query.setFirstResult(begin);
        query.setMaxResults(count);
        List tt 
= query.list();
        
return tt;
    }

--
    /**
     * 根据条件生成一个sql语句
     *
     * @author 和
     * @param sql
     *            初始的sql语句(一般为select a from A as a where 1=1)
     * @param condition
     *            查询的条件
     * @return
     * @version 1.0
     */
private
 void makeSql(StringBuffer sql, UserFindCondition condition) {
        
if (condition.getUsername() != null
                
&& !condition.getUsername().toString().equals("")) {
            sql
                    .append(
" and a.username like :username");
        }

        
if (condition.getLoginid() != null
                
&& !condition.getLoginid(().equals("")) {
            sql
                    .append(
" and a.loginid( = :loginid(");
        }

        
if (condition.getSex() != null
                
&& !condition.getSex().equals("")) {
            sql.append(
" and a.sex = :sex");
        }


    }

    
/**
     * 根据条件设置query的值
     * 
     * 
@author 和
     * 
@param query
     *            一个hibernate的Query对象
     * 
@param condition
     *            查询的条件
     * 
@return
     * 
@version 1.0
     
*/
    
private void setParameter(Query query, UserFindCondition condition) {

        
if (condition.getUsername() != null
                
&& !condition.getUsername().equals("")) {
            query.setString(
"username""%" + condition.getUsername()
                    
+ "%");
        }

        
if (condition.getLoginid() != null
                
&& !condition.getLoginid().equals("")) {
            query.setString(
"loginid", condition.getLoginid());
        }

        
if (condition.getSex() != null
                
&& !condition.getSex().equals("")) {
            query.setString(
"sex", condition.getSex());
        }     

    }

呵呵,笑死人了,这个方法很通用,我才在我的第二个项目当中才用到,真是可惜,当然了,使用Actionform有一个毛病就是对date类型要转换成STRING类型来处理,这是actionform的一个死穴。还有对Actionform不能够重置,只能够回来从前。不知道这群设计者怎么想的,真是由于这一点,所以我们有必要使用最原始的方法来解决问题了。使用页面当中的input,我们来拼request如何?
   二、利用JSTL做为表现而实现的查询功能
     步骤:在JSP页面布置很多的input,当然,你可以加入value了。(省略了...)
           创建查询条件的序列化对象(同样user.java)
           在action当中拼个condition了,做为查询条件,后面的处理类同第一种方式。
     UserSearchCondition userSearchCondition = null;
     userSearchCondition 
= makeUserSearchCondition(request);

private UserSearchCondition makeUserSearchCondition(HttpServletRequest request) throws Exception{
       
UserSearchCondition userSearchCondition = new OrderSearchCondition();
        String username
= request.getParameter("Username");
        String loginid
= request.getParameter("Loginid");
        String sex
= request.getParameter("Sex");  
       

                
        
if(username!= null && !username.trim().equals("")){
           
usernameSearchCondition.setUsername(username);
        }
        
        
if(loginid  != null && !loginid.trim().equals("")){
            userSearchCondition.set
Loginid (loginid );
        }
        
        
if(sex != null && !sex.trim().equals("")){        
            userSearchCondition.setSex(
sex);
        }      

        
        
return userSearchCondition;
    }

     以后的方法,我就不用再做举例了吧,可以参考如上第一种方法的实现.
     第二种方法的好处就是:在页面上比较好控制,比如重置,又比如日期性数据等。
     (所有过程当中的代码没有经过测试,只是说明这种方法而已)

posted @ 2006-07-21 11:20 @家军 阅读(2698) | 评论 (1)编辑 收藏

hibernate的延迟加载通用方法

呵呵,在忙一个项目,潜水很久,现在冒个泡:
(本文适用在struts+spring+hibernate3上做开发的虫虫们)
类名:HibernateUtil

package com.antbee.j2eemodel.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class HibernateUtil extends HibernateDaoSupport {

/**
* 初始化POJO类
@author @家军
@param object POJO对象
@param methodName 方法名称
@return
@version 1.0
*/
public void initialize(Object object, String methodName) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {

String[] methodArray 
= methodName.split("\\.");
Method method 
= null;
Object initializeObject 
= object;

if(methodArray.length == 1){
this.getHibernateTemplate().lock(initializeObject, org.hibernate.LockMode.NONE);
method 
= object.getClass().getMethod(methodArray[0], new Class[] {});
initializeObject 
= method.invoke(initializeObject, new Object[] {});
this.getHibernateTemplate().initialize(initializeObject);
}
else{
for(int i=0;i<methodArray.length;i++){
method 
= initializeObject.getClass().getMethod(methodArray[i], new Class[] {});
initializeObject 
= method.invoke(initializeObject, new Object[] {});
}
this.getHibernateTemplate().lock(initializeObject, org.hibernate.LockMode.NONE);
this.getHibernateTemplate().initialize(initializeObject);
}
}

/**
* 初始化POJO类
@author @家军
@param object POJO对象
@param methodName 方法名称数组
@return
@version 1.0
*/
public void initialize(Object object, String methodName[])
throws SecurityException, NoSuchMethodException,
IllegalArgumentException, IllegalAccessException, InvocationTargetException {

for (int i = 0; i < methodName.length; i++) {
String[] methodArray 
= methodName[i].split("\\.");
Method method 
= null;
Object initializeObject 
= object;

if(methodArray.length == 1){
this.getHibernateTemplate().lock(initializeObject, org.hibernate.LockMode.NONE);
method 
= object.getClass().getMethod(methodArray[0], new Class[] {});
initializeObject 
= method.invoke(initializeObject, new Object[] {});
this.getHibernateTemplate().initialize(initializeObject);
}
else{
for(int j=0;j<methodArray.length;j++){
method 
= initializeObject.getClass().getMethod(methodArray[j], new Class[] {});
initializeObject 
= method.invoke(initializeObject, new Object[] {});
}
this.getHibernateTemplate().lock(initializeObject, org.hibernate.LockMode.NONE);
this.getHibernateTemplate().initialize(initializeObject);
}
}

}

/**
* 初始化POJO类
@author @家军
@param object POJO对象
@return
@version 1.0
*/
public void initialize(Object object) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
this.getHibernateTemplate().lock(object, org.hibernate.LockMode.NONE);
this.getHibernateTemplate().initialize(object);
}

/**
* 初始化POJO类
@author @家军
@param collection POJO对象集合
@param methodName 方法名称数组
@return
@version 1.0
*/
public void initialize(Collection collection, String methodName[])
throws SecurityException, NoSuchMethodException,
IllegalArgumentException, IllegalAccessException, InvocationTargetException {

for(Iterator i=collection.iterator();i.hasNext()Wink{
Object object 
= i.next();
this.initialize(object,methodName);
}
}

/**
* 初始化POJO类
@author @家军
@param collection POJO对象集合
@param methodName 方法名称
@return
@version 1.0
*/
public void initialize(Collection collection, String methodName)
throws SecurityException, NoSuchMethodException,
IllegalArgumentException, IllegalAccessException, InvocationTargetException {

for(Iterator i=collection.iterator();i.hasNext()Wink{
Object object 
= i.next();
this.initialize(object,methodName);
}
}

这个方法的好外是:可以不在hbm.xml的文件当中,指定为lazy=true这个模式,可以直接使用。使用方法如下:
如果你使用SPRING,则需要把hibernateUtil注入其中:
 <bean id="hibernateUtilTarget" class="com.antbee.j2eemodel.util.HibernateUtil">
<property name="sessionFactory">
<ref local="mssqlSessionFactory" />
</property>
</bean>

<bean id="hibernateUtil" parent="BaseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="target">
<ref local="hibernateUtilTarget" />
</property>
</bean>
<!--配置基础事务-->
<bean id="BaseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager">
<ref bean="mssqltransactionManager" />
</property>
<property name="proxyTargetClass">
<value>true</value>
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean> 

使用示例:
如果你使用STRUTS,则需要这样:
List what_ur_view = XXXManager.find(.);//取得你要展示的对象
//如果这个对象当中有延迟加载的对象(SET)时,则需要如下加载就行
this.hibernateUtil.initialize(what_ur_view, "getTbShipmentSale");
//其中getTbShipmentSale是其对象(SET也可以操作) 

在页面显示的时候,你就可以使用JSTL如下表述:
<c:out value="${what_ur_view.tbShipmentSale.goodsReceivePersonPhone}" />//呵呵,是不是很爽呀。 

同样的方法,我们也可以对一个SET在页面进行显示,方法如下:
<c:forEach items="${what_ur_view.tbShipmentProductMappingSet}" var="ProductMapping" varStatus="status">
<c:out value="${ProductMapping.productNum}" />
<c:out value="${ProductMapping.tbOutOfWarehouse.outOfWarehouseNum}" />
</c:forEach>
//呵呵,支持多级嵌套, 

在ACTION当中则需要加入
hibernateUtil.initialize(what_ur_view.getTbShipmentProductMappingSet(),
new String[] { "getTbProduct""getTbOutOfWarehouse",
"getTbProductConfigure" }); 
呵,如果你要是在HIBERNATE当中使用,这个就太简单了吧。

怎么样?呵呵呵,
从此,我对STRUTS的标签深恶痛绝,而对JSTL情有独钟了。

posted @ 2006-07-21 10:09 @家军 阅读(5586) | 评论 (2)编辑 收藏

成功是一种病态的坚持!

   很长的时间陷入到与同事上级的斗争当中,无聊死了,今天回来看看自己书签当中的网站,感觉到自己是小人了。我不应该留恋明争暗斗,我应该自立自强,永不停息。
   在年前的时候我曾经非常看好compiere的应用,想不到今天再看看国内使用的形势,长三角和珠三角的广泛应用,还有ORACLE免费数据库的推出,更加印证了我错误的做法。
   一个人最重要的事情就是三个字:做决定。
   一个人想要成功,尤其像我这样不甘愿给别人打工又有很多想法的人,除非是一种病态的坚持才能够取得成功。
   我很讨厌公司现行的CRM系统,简单的说一句就是:简直就是一个糊人的、丑陋的MIS系统,一点设计思想都没有,一点产品理念都没有。最重要的设计者在拼命的逃脱自己的责任,开发者在忍受莫大的痛苦,业务在每一个开发者思想里扭曲......唉,想抽出一点时间来都难。
   我要在以后的时候里,一则增加自己的业务能力,以compiere的应用为主;二则要增强我的技术能力,以 vTigerCRM为蓝本,做一个J2EE的产品移植。
   在今年年底以前,自己必须要做到对compiere的应用熟练,能够完成 vTigerCRM的J2EE实现。所以自己最重要要做的事是:时间安排,

posted @ 2006-07-19 16:35 @家军 阅读(385) | 评论 (0)编辑 收藏

转摘:从一个笑话看软件开发管理

来自于:http://blog.csdn.net/Raptor/archive/2006/05/13/727299.aspx

关于软件开发的笑话有很多,下面这个是我刚在QQ群里的看到的:

1. 程序员写出自认为没有Bug的代码。
2. 软件测试,发现了20个Bug。
3. 程序员修改了10个Bug,并告诉测试组另外10个不是Bug。
4. 测试组发现其中5个改动根本无法工作,同时又发现了15个新Bug。
5. 重复3次步骤3和步骤4。
6. 鉴于市场方面的压力,为了配合当初制定的过分乐观的发布时间表,产品终于上市了。
7. 用户发现了137个新Bug。
8. 已经领了项目奖金的程序员不知跑到哪里去了。
9. 新组建的项目组修正了差不多全部137个Bug,但又发现了456个新Bug。
10. 最初那个程序员从斐济给饱受拖欠工资之苦的测试组寄来了一张明信片。整个测试组集体辞职。
11. 公司被竞争对手恶意收购。收购时,软件的最终版本包含783个Bug。
12. 新CEO走马上任。公司雇了一名新程序员重写该软件。
13. 程序员写出自认为没有Bug的代码。

要我说,如果真有这样的公司,不倒闭对不起人民。

这个笑话从程序员开始,到程序员结束,从头到尾都在说程序员的不是。但是我要说的是,这完全是管理者的失败,从整个过程中,看不到任何管理工作。这种管理者不但无知无能,还很无耻——将自己的失败责任推给程序员。

1、程序员凭什么证明他的代码没有BUG?有Test case吗?有Code review吗?这个环节管理缺失。

2、测试发现BUG有进行BUG管理吗?有跟踪吗?这个环节管理缺失。

3、凭什么证明程序员已经把那10个BUG修改好了?另10个又为什么不是BUG?BUG的评价标准难道是程序员说了算?这个环节管理缺失。

4、5个不能工作的BUG修改问题有没有追究责任?增加新BUG是修改过程中不可避免的事情,但是如果有有效的单元测试机制,可以大大减少这种情况。这个环节管理缺失。

5、迭代是正常的,但是问题处理于发散而不是收敛发展,可见没有有效的管理调控。这个环节管理缺失。

6、过于乐观的时间表和不可能达到的最后期限,都表现出管理者的无知和无能。而在这样的情况下强行推出产品,那就是无知者无畏了。

7、这是对用户的不负责任,管理者要负最大的责任。

8、这样的情况还能发项目奖金,只能说管理者不是一般的愚蠢。

9、管理工作没有任何的改进,问题仍然处于发散迭代状态。管理工作依然没有到位。

10、拖欠测试部门工资体现出管理者对质量管理工作的忽视以及对人力资源管理方面一无所知。

11、送被收购者两个字:活该。送收购者两个字:瞎眼。

12、可见新管理者与原管理者半斤八两,都没有认识到问题的根本所在。不过也只有这样的管理者才会作出收购这种公司的决策。

13、历史的重演是必然的。

一个正常的企业或是项目,其运作必须应该是循环向上进行的。而保障这种运行的工作就是管理。而管理工作的主要内容就是控制,包括控制循环的节奏——不能太快也不能太慢,控制发展的方向——只能向上不能向下,控制运作的稳定——不能大起大落或时聚时散等。

而这一切,在这个例子中都看不到。

在 这个笑话的例子中,一切都是以开发工作在驱动,这首先就是一个方向性错误,产品是为用户服务的,当然应该是以用户和市场作为驱动,并且结合自身的能力最终 确定工作的重点。这一错误折射出管理者对被管理的内容很不了解,只好任由比较了解的程序员摆布——事实上他们除了技术,并不会了解更多。

一个管理者如果对自己所管理的内容不了解,他就不可能管理得好

这是一件毫无疑问的事,可是国内的软件业似乎总是不相信这一点。中国软件业中流毒最深的谎言之一就是:

管理者只要懂管理就可以,不需要懂技术。

其实这不过是那些无知无能无耻的管理者为了骗钱而编出来的,相信这句话的人必将付出金钱的代价。

其 次是质量管理。基本的质量管理常识告诉我们,每次循环结束前,最重的工作就是总结改进。只有这样才能保证循环运作是向上发展,而不是失去控制地向下发展。 也只有有效的质量管理,才能保证迭代过程是收敛发展,并最终达到目标。但在这个例子中,这个部分显然是缺失的——其中虽然有测试部门,但是他们的作用仅仅 是质量管理中的质量检测环节,管理部分还是缺失的。

然后是人力资源管理。软件开发是一项劳动密集型的工作,虽然这是脑力劳动,但同样意味着人在因素在其中占有决定性的地位。而例子中未改完BUG的程 序员拿到项目奖金,而同样辛苦工作的测试人员却被拖欠薪资,除了表现出管理者对他们的工作内容的不了解,以及对质量管理工作的不重视以外,还表现出管理者 完全不会管人,这是一种谋杀团队的行为——谋杀一个团队远比建设要容易得多。

最后,这个失败的管理者把他的经历编成这个笑话,让大家看到他被程序员们害得多惨,把程序员妖魔化为一群骗子。但只要稍懂管理的人简单分析一下就可以看出来,只不过是这个人的无知和无能造成了他现在的结果,而把责任推给别人的行为更是表现出他的无耻。

作为身居高位的管理者,如果连应该承担的责任都要推卸,他们还能胜任什么事情呢?

posted @ 2006-05-15 15:53 @家军 阅读(346) | 评论 (0)编辑 收藏

我向百度公司进军!

     百度公司今天搬到我们这幢楼内,更加刺激了我去百度的念头,因为我喜欢创新的工作,所以我将为这一点而去努力奋斗。
     不是说百度公司有多好,主要是想稳定上几年,有一点积蓄了,就可以自己出来自谋生路。呵呵。看见百度技术的职位只有无线搜索技术用到了JAVA,呵呵,不会灰心,其实,PYTHON或者RUR都将是以后的方向,至于PHP,我感觉百度会在不远的将来抛弃掉的。在服务器的性能和安全争端上我只相信JAVA,百度只不过把这一种技术很快转化成了资本,如果百度想要和GOOGLE一争高下,实质性的工作--技术上必须上要胜出GOOGLE一筹才行。而这一点只有行家才知道。

     我在北京的这几年都是为代码,或者就是为纯粹的技术而奋斗,其实做为软件公司,其起步主要是靠技术,但是他成名或者有所富裕后,就觉得人情是一个比技术还好玩的东西时,这个公司就开始有了差距,不过,这个公司就开始危险了,或者是穷途末路,只能钻到钱眼里去了。如果管理层(其实就是和有权的腐败工厂DANG有关系的人)没有动静的话,这个公司必死。这就是中国的国情。
   
     工厂DANG叫嚷的中国国情就是要隐含有权层的灰色收入,况且五千年的封建文化完全可以掩盖这一点。否则,会把老祖宗也搬出来。孔子曰:孟子说:还有什么孙子谈兵什么的。
    
     从程序员的角度思索一下,如上是IF.....ELSE....的语句后,final,工厂DANG治理的天下乱七八糟。

posted @ 2006-05-08 15:50 @家军 阅读(377) | 评论 (0)编辑 收藏

我将成为一个快乐的房奴

    呵呵,我在北京买到房子了,贷款了40万元,在签订了很多的不平等条约后,我成为了一个正式的房奴了,但是我很高兴。
    我来自于农村,我最原始的生活憧憬就是改变农村这种生活方式,我在很小的时候就不喜欢农村的黄昏,因为夕阳照着我疲背一天身体时,我感觉到生命的绝望。于是我要改变自己,改变整个家庭的命运。
    父亲很努力,在我懂事的时候就进入了县城,我的心理比较的蹋实了,好象有了可以骄傲的资本,虽然家庭的收入很拮据,但是我认为自己要改变的不只是这一点。
    于是我只身来到北京,举目无亲的可怜像和在火车站睡觉的经历更加激励了我,我要生活下去,我从上大学的时候就有一个始终不愈的信念:打不死的精神活到老。
    我对生命很是无所谓,因为我知道自己已经在阶级社会的最低层,我不害怕自己的失败,我也不在乎钱,钱对于我来说只是肯定我的成绩,肯定我的所有为是有效的。
    呵呵,我成为了北京的一员了,我的想法很简单,当我20年后,如果我的儿子不在北京发展了,我将买掉我的房子,回家后,我也应该成为自由的生活者了,我已经能够让我的晚年有所事事了。
    这一段时间主要在忙一个紧急的项目和公积金贷款,我将撰写一个比较权威详细的的贷款程序、
    博客将给我一个表现自己全新的舞台,我将为生命之花绽放。

posted @ 2006-05-08 15:29 @家军 阅读(659) | 评论 (5)编辑 收藏

危险的中国经济

   说起来危险吧,就是对纳税人的不满,如果纳税人有追求自由的念头,那么你就知道中国的经济有多危险。
   呵呵,危险的中国楼市
         危险的就业大军
         危险的新农村政策
  新农村的建设就是废除个人承包制,恢复现代地主制。看小X忙的不亦乐乎,他在干着财富分裂的现代社会主义建设。好象农民脱离了土地,浮萍会被枯叶败枝聚集,壮观的让人压抑。
  程序员不谈政治了。否则,后果不好。

posted @ 2006-04-28 20:01 @家军 阅读(253) | 评论 (0)编辑 收藏

快被尖刻的客户托垮了!

  最近没有时间写BLOG,虽然心理有很多想法想写,想努力的推进开源代码的实施,但是被尖刻的客户托垮了。
   可能是我目前见到最尖刻的客户吧,用户在使用软件当中,遇到任何一点可疑的问题就打电话“责令”修改,否则没有快速响应,最高的领导就出面给我施加压力。我CALL,我真是对这群滥人生气。所以我不得不打断所有的工作而快速响应,于是晚上自愿加班到9-10点,已经有三周没有休息了。最要命的这个项目的设计者、编码者、测试者和实施者就我一个人,而我上面有项目经理、销售、部门经理、副总,一有问题,四个经理就在一旁看结果,呵呵,压的人喘不过气来。
   我也很气愤这个鬼公司,老板小气的要死,实施时连个笔记本都没有,而且前一段时间说为了实施方便才刚刚搞了一个移动硬盘,这才把我的老式的MP3(U盘)才换下来。所有给客户的演示的第一步骤就是搬机器,最后一个步骤也是搬机器。唉,这么诡异的公司!!!!!!!!!!!!!!!
   现在客户系统要上线,说不允许出现BUG,我没有敢承诺,所以我也不说话,所有上面的领导都告诉我,不允许出现错误,你说我应该怎么说,我也没有说,只是和最小的头说:我尽量吧,错应该不是错,以后就是布丁了。
  果然,正式上线的系统出现错误了,果然领导生气了,果然领导给我委派了一个测试人员(普通员工临时调配),果然我想离开这个诡异的公司。果然开源代码的推广又一步的延迟.........
  不过,我觉得我还是很自信,因为我已经尽了自己的最大努力,还有积累了很多的软件工程的经验,还有快速开发的经验。
  呵呵,出去混又何妨,方正我已经有了项目经理证,方正也实施了这个近百万的项目了。还是一个人执政,呵呵,和尚养大了,又觉得庙门小了。
 
 

posted @ 2006-04-28 11:03 @家军 阅读(285) | 评论 (0)编辑 收藏

开源代码的盈利模式是什么?

 已经有很长时间没有写日记了,公司的活太累了,所以没有清闲的时间和清静的心情来写BLOG。
 我现在还深学陷入到开源代码的实现当中,我感觉不到开源代码将对以后的生活带来什么实质的影响,可能就是能够加快软件生产的效率而已,在IT界,开源代码的商业模式有过很多的探讨,这也证明了开源代码的魅力所在。因为她很深,所以以传统的专业精神是很难很快的了解开源代码。因为研究所化费的代价很大,所以她的存在价值就越来越高。
 从很多的资料和个人的体验当中,我深深感觉到开源代码的盈利就是服务,而这个服务应该是多元化、多层面的服务体系,这个就好象是一个宗教一样,像是道教,人之初,性本善,开源代码的开源之初总是最好的,以后可能会鱼龙混杂,现在已经有这种迹象了。
 从理论上进行分析,以后对开源代码进行管理的企业将是一个可以盈利的企业,对开源代码提供规则的将也是商家,在一定实践基础上对开源代码进行分级,将是另外一个视角看开源代码的方式,这个对开源代码的成长起辅助作用。
 开源代码对软件的生产将提供最大的技术支持,这只是给有心人的。
 开源代码也将指导企业应用的先进化生产,风险和效率将同时存在。将来对开源代码这种生产力的风险减低和效率提高的服务型企业将是开源代码的最大受益者。
 我现在在拼命的研究AJAX技术,感觉用户体验是有了,但是又增加了写程序的能力,页面和实际业务不能够完全分离,不知道这个东东能生存多久。AJAX的出生和用户对“点击->返回”的上网体验都是不久的事,哪个将取得领导地位,还拭目以待。

posted @ 2006-03-30 13:43 @家军 阅读(791) | 评论 (0)编辑 收藏

我的信仰地图[引用 zbw25]

{只为学习,并无其它目的}
一、概念界定
  前一段时间在和李杜韩兄讨论儒家是否宗教的问题,当时我答应他,要好好想一想,给出一个自己的关于宗教的定义。在这段时间里,我 始终在思考这个问题。终于我决定将问题放在一个更加广阔的范围内来进行思考,这就是,什么是宗教?什么是科学?这个问题似乎反而简单了。在不进行更加深入 地思考的情况下,我可以先给出科学的定义:科学是用理性的、逻辑的方式看待世界的观点,以及方法论。也可以这样说:科学就是以理性和逻辑的方法为特征的世 界观和方法论。这样的定义还可以进一步解释为,以理性和逻辑的态度,来探索世界,形成结论,并以此指导自己的生活。那么宗教呢,宗教同样对世界进行探索, 形成结论,并以此指导自己的生活。马克思主义的说法是:宗教的颠倒了的世界观,我并不如此认为,这是完全站在以我为中心的立场来对宗教信仰的评价。这个问 题,我下面还要详细分析。因此,我对宗教的定义是:以一种崇拜的、神秘主义的心态,来探索世界,形成结论,并以此来指导自己的生活。这样就称之为宗教。 
   这里要解释一下理性的、逻辑的心态与崇拜的、神秘主义的心态的区别,前者相信,人类对世界的探索,将不断的接近真理,也就是说,世界是可知的,我们所生 存的世界,对于科学来说,就是各种各样可以研究的对象,可以看成一个整体,也可以分别研究,从科学研究的可行性角度来看,对世界的研究首先意味着对问题的 分解,也可以说是对世界的分解。因此,科学很容易的就导向无神论(无神论与科学并不等同,这一点下面再详细分析)。而崇拜的、神秘主义的心态,首先就认为 这个世界是一个整体,而且是一个人类永远无法彻底把握的整体。面对浩淼苍穹,无尽时空,人类唯有赞叹造化的神奇,并越发深切的意识到自己的渺小。但是这样 的态度并非不可知论,因为,以宗教的态度看待世界的人,同样在探索世界,而且从未停止。 
  在这样一个框架下,我们同样可以定义哲学,哲学是另 一种态度,面对世界万物,哲学家是思辨的。他们以一种思辨的心态来探索世界,形成结论,并以此来指导生活。思辨与逻辑不同,对于逻辑来说,对就是对,错就 是错。而对于思辨来说,对也可能是错,错也可能是对。在我看来,一切哲学都是思辨的,这与马克思哲学中的形而上学/辩证法的概念,并不一致。思辨、狡辩、 诡辩等等都只有一线之隔,而真正的哲人,因为一定可以继续思辨而否定自己,所以最终的结果要么是发疯;要么是停止思辨,开始建立自己的理论体系。而后来的 哲学家,就可以在他的思考、思辨停止的地方,开始对他的反驳。也正是由于哲学的思辨的本质,因此哲学体系的种类最多,最为千差万别,有的像科学,有的像宗 教,有的什么都不像,而自成一家。 
  再界定两个概念,知道与信仰。我可以知道自己有左右两只手,而无需信仰自己有两只手。所谓信仰,可以定义 为对于无法证明的命题的确信。我们知道,宗教中的绝大多数命题都是无法证明的,因此我们同样都将宗教和信仰连起来表达。而对于科学,我们往往会认为这不是 信仰,因为科学结论都是可以证明的,但是问题并没有这么简单,因为科学体系是建立在公理体系的基础上的,而公理体系是无法证明的,因此对科学的信心,也可 以称之为信仰,当然这样的信仰需要“糊弄过去”的地方只有少数的一些公理和常数。相对来说比宗教要“好”很多。但是无神论并不是这样,我们可以马马虎虎不 将科学算成信仰的一种,但是无神论,却一定是一种信仰,因为这同样是对无法证明的命题的确信。 

二、儒家的定位 
  现在,基于 已经明确的定义,我们可以继续回到对儒家问题的讨论上来了。儒家肯定不是科学,也不是单纯的宗教,我们可以很清楚地界定,儒家同样是以一种崇拜的、神秘主 义的心态,来探索世界,形成结论,并以此来指导自己的生活。儒家对天的崇拜,以及对天道、天命的近乎神秘主义的信仰,可以说是一种很典型的宗教的心态。 
   但是,问题到这里并没有结束,因为我们还需要区分儒家这样的宗教,与其他的宗教有什么区别,为什么对于儒家是否宗教的问题,有着如此多的争论,而在其他 的宗教上几乎没有这样的疑问。按照李杜韩兄的理解,认为儒家是一种“准宗教”,但是什么是“准”呢?为什么会“准”呢?为什么就不能明确的分析出,儒家与 其他的宗教的真正的区别所在呢? 
  在我看来,绝大多数的宗教,都是起源于人类对于“生死”问题的思考,个人问题,是宗教探讨的当然的出发点。 但是,这正是儒家与其他宗教的区别所在。在基督教的论述中,“永生”是一个重要的命题,进天国,得永生,是基督徒所能得到的最大的恩典;而在佛教的论述 中,“出六道轮回”是每个佛教徒的追求—即使不是最高追求;而在道教的论述中,“长生不老”是值得追求,也是可能达到的目标。这些宗教—我对其他的宗教不 太熟悉—所共有的特征是面向个人的,是“我”的追求目标,或是“我”能得到的恩典。这些宗教对人的教导中都有“向善”的成分,但是都是达到目标的手段—甚 至在基督教不承认任何手段的有效性,只要求绝对的信仰—或方法。因此通常的表述是:“如果你如何如何,你就能怎样怎样”。 
  但是在儒家,个人 问题几乎是完全不被考虑的,社会、他人、国家、天下才是真正重要的。正心、诚意是为了修身,而修身是为了齐家、治国、平天下。对自己下功夫,并不是为了自 己,而是为了比自己更加广大的,更加重要的事情。天理是重要的,人欲是可以忽略的。这样的区别非常明显,其他的宗教,一切的追求、行为,无论是对他人、社 会还是对自己,最终的目的都是为了“自己”。所有的努力,甚至“熄灭自己欲望”的努力,也是为了实现自己最大的欲望。但是,儒家从来就不告诉你:“信了我 的教,你能如何如何”。也可以这样说,儒家从来都不会“利用一个人的私人欲望,来引人入教”。这也就是为什么历史上有这么多的邪教,而这些邪教的理论根 源,或借鉴者,可能是基督教、佛教、道教或者其他的什么宗教,但从来没有借鉴过儒教,因为在儒家的理论中,不提供“满足个人欲望的可能性”。儒家从来只告 诉他的信徒:“你要成为君子,你要忧国忧民,你要……”,却从来没有告诉他的信徒:“成为君子后,你有什么样的好处……”。 

三、三种宗教的区别 
  在论证了儒家与其他宗教的重大区别之后,我们可以来讨论一下道教、佛教与基督教之间的区别所在。 
  他们之间的相似之处是很明显的,这三种宗教都非常的关注“生死”问题,但是如何解决这个问题呢?三种宗教却给出了不同的答案。 
   为了解答“生死”问题,这三种宗教都非常的关注“时间”、“始终”等等命题,但是对于道教来说:“道生一、一生二、二生三、三生万物”,可以说是一个无 穷无尽的过程,因此在道教看来,“时间是有始无终的”。而对于佛教来说,时间即没有开始,也没有结束,因此“时间是无始无终的”。对于基督教来说,上帝是 一切的创造者,当然也包括时间,一直到最终的审判,“时间是有始有终的”。 
  因为“时间是有始无终的”,所以对于道教来说,向前看是没有意义 的,回去是唯一有意义的事,在老子的“小国寡民”的理想确定无法实现之后,作为个人回到过去,回到道,成为唯一的出路。因此,在道家看来,不断的修炼自 己,最终成仙,并不是向前的进步,而是回到了本源,回到了自己的出发点。 
  因为“时间是无始无终的”,所以对于佛教来说,这世间的一切都没有意义,因为如果有无限的时间,那么世界一定会不断的重复,人就在六道中轮回,承受着永远的痛苦。唯一的出路,是跳出来,不但要跳出这个世界,甚至要跳出所有的“时间和空间”。 
  因为“时间是有始有终的”,所以对于基督教来说,一切都是掌握在上帝的手中,没有人能夸耀自己的努力,没有人能凭借自己的奋斗而找到出路,唯一的道路就是“信”,其他的一切作为,都只具备世间的意义,而没有永恒的价值。 
  三种宗教的理论基础,已经如上所分析,而作为世界上的真实存在的宗教,一定会面临具体的“实践”问题,或者说如何判断一个实践是否符合理论的问题。 
   判断的困难在道教基本上不存在,因为这是一个明确的以目的为导向的宗教,是否正确,只看你是否有效果,这样的“实用主义”,避免了很多理论上的争论,乃 至人格上的判断。只要成了仙,就一定得了道。甚至炼丹都可以由别人来进行,自己只要吃了就可以。因此道教的基本发展历程,就是一个不断探索的过程,如何才 能更有效地成仙,不妨百家争鸣,不妨百花齐放,只要有效,一切都是值得的。这也就是为什么道教的历史最少争论,也最少理论派别的原因。而这样的弊端就是什 么歪门邪道都有可能混入道教,使得道教成为一个名副其实的大杂烩。 
  佛教对于判断的问题,存在两面性,既有很多外在的判断标准,又相信“如人 饮水,冷暖自知”的最高境界。佛陀的“相貌、神通、舍利子”乃至“智慧”,成为常用的外部标准。而在佛教中又有很多关于“次第”的论述,似乎成佛是可以循 序渐进,有迹可查的。然而事情并非如此简单,因为,外在的标准并不符合佛教的基本教义,因为一切表象,皆是因缘合和而成,并非根本,所以是否成佛,还需要 某种“未知的”方法的验证。这种方法没有人知道如何描述,但是已经公认的大师,则有权通过这样的方法来作出判断。所以在佛教会出现比道教多得多的派别,特 别是到了禅宗以后,佛教的派别、分化就会越来越多,因为判断没有公认的标准,只以权威的意见为转移。 
  基督教对于判断的问题,最为头疼,因为 根据基督教的基本教义,人的一切行为,表象,都不能成为判断的依据,这一点基督教比佛教执行的严格得多。而这样导致的后果就是无休止的争论与不断的分化。 基督教对于教会的纯洁性是最为注重的,这样导致的结果,并不是教会的纯洁,而是不同教派之间的“水火不容”,甚至“你死我活”。因为我无法从理论上驳倒 你,又无法实际的证明给你看,只能杀了你,才能证明上帝是站在我这一边的。但是这样不能解决任何问题,所以现在基督教的派别是世界上最多的,而这些派别之 间的矛盾,也是最为尖锐的。 

四、无用的哲学 
  之所以说“无用的哲学”,其实并没有什么贬义,而是我认为,从哲学的本质来说,他就应该是“无用的”。如果哲学变得很有用,就会十分危险,非人类之福。 
   根据我前面的定义,哲学是一种以思辨的心态,来探索世界,形成结论,并以此来指导自己的生活的方式。出于这样的一种心态,哲学成为人类智力的终极乐园, 古往今来,无数的人思考哲学问题,并沉醉其中,而哲学的问题没有一个得到解决—在科学意义上的得到最终答案—或者获得公认。我们甚至可以断言,一切的哲学 问题,都永远不可能有最终的确定的答案,这也正是哲学的魅力所在。 
  为什么哲学不能得出公认的结果呢?这有两个方面的原因,一方面是由于哲学的本质,另一方面是由于人的本性。 
   从哲学的本质来说,这是一种心态,一种永远试图再换一种方式思考的心态,或者我们可以褒义的称之为:“不断思考得更加深入。”而哲学的思考对象又是全世 界,如此的复杂,如此的难以概括,如此的千差万别。而哲学又试图从整体上来把握整个世界,因此一定会有无数个答案,而且一定无法确定哪一种答案是最优解 答。 
  对于人的本性来说,哲学思考是一种最好的智力游戏。因为不需要站在巨人的肩膀上,不需要继承已有的哲学,最值得赞赏的努力是开创全新的 体系,如果做不到,也可以创造全新的表述方式。前人的努力,与其说是继承的财富,到不如说是批判的目标。能够批判前人,提出自己的观点,能够使人得到最大 的满足,因为哲学是回答最重要的问题的学问。 
  似乎我这样讲,将哲学过于贬低了,其实并不是这样,因为这正是哲学的伟大所在。只有了解的哲学 的本质,才会相信,人人都能进行自己的思考,得出自己的结论,有这样的心态人,我们称之为有哲学精神的人,如果将这样的精神贯穿整个人生,我们就称之为 “哲人”,例如我们所尊敬的伟大的苏格拉底。哲学的最大的用处是作为“解毒剂”,但是哲学不能变成有用的结论,哲学会变质,有可能变成宗教,有可能变成政 治,有可能冒充科学,这样的有用,非常危险。 

五、有限的科学 
  说科学是有限的,同样没有贬低的意思。因为根据科学的本质,他就一定是有限的。 
   科学作为一种以理性和逻辑的态度,来探索世界,形成结论,并以此指导自己的生活的学问,他的本质就是不断的怀疑与验证,如果有人为了怀疑而怀疑,毫无意 义,而为了验证而验证,只能说是迷信或者说是伪科学。既然科学是一个不断怀疑与验证的过程,而且出于理性与统一的逻辑,科学必然是一个整体。打个简单的比 方,当年亚里斯多德在地上画的那个关于知识的圈,是一个而且只能是一个圈。如果在这个知识的圆圈之外另有一个“飞地”,那只能称之为科学猜想,只有在将来 的某个时刻,这个猜想得到了验证,这块“飞地”才能和大圈连在一起,成为科学知识的一部分。 
  附带说一句,我并不认为社会科学是科学的一种,在我看来,所有的社会科学,只是哲学思考扩大化之后对科学的模仿。这也就是为什么自然科学基本上没有什么派别,而社会科学却流派纷呈的原因。 
   科学是有限的,而世界是无限的—也正是由于科学,我们才能像今天这样深切的认识到世界的无限性—这就意味着科学永远也无法穷尽整个世界,科学的有限性不 但是必然的,而且是绝对的。真正的科学家,或者具有科学精神的人,永远都遵循着怀疑、验证的规律,而不会混淆知识与假想的界线。 
  说到这里, 我倒是想起了一件很有趣的事情,当年特异功能流行的时候,钱学森与**之间有一场激烈的争论,我们知道,钱学森是一个科学家,而**是一个—怎么说呢,就 算是—社会科学家吧。他们的态度截然不同,钱学森认为这种现象值得研究,而**则大力反对,或者说科学立场比钱学森还要坚定。这就是科学家与信仰科学者的 区别。 
  现在我们开始大力提倡尊重科学,学习科学知识。但是真正要学习的是什么呢?是科学精神,一种伟大的,永远不自以为是的精神。而不是为了维护某种“科学结论”却丧失了进一步探索的勇气。 

六、我的信仰选择 
   对于我来说,选择一种信仰其实分为两个阶段,在写这篇文章之前,我处在一种漫无目的的摸索阶段,就好像一个丛林中的迷路者,找不到方向,更不要说出路。 但是通过前面的思考,我为自己的画出了地图—一幅关于信仰的地图。于是在我来说,选择信仰的问题变得简单,并且有效。 
  当然,这个问题也可以 反过来看,就是我首先是确定了自己的信仰,然后开始寻找理论上的支撑,通过论证自己的信仰选择的合理性,使我可以更加有把握的走下去。不管怎么说,这是一 个良性循环的开始,信仰坚定了理论,而理论又更加坚定了信仰。也可以说,这样的方式才是信仰式、而非思辨式的。 
  首先要做的第一个选择题是, 是否需要信仰,也可以说,这个世界存在着两种人,有信仰的人和没有信仰的人,我要选择做什么样的人,我要选择一种什么样的生活。有两种人可以没有信仰,一 种是混混僵僵的人,这种状态可以简单的称之为“快乐的猪”,如果一个没有开始思考信仰的问题,他可以停留在这个状态,但是一旦他开始思考,就再也没有可能 回到混混僵僵的状态,对于我来说,这是一个不可能的选择。 
  另一种没有信仰的人,是有着各式各样 “现实追求”的人,这样的可以一辈子的不考 虑信仰问题,而生活得很充足,很忙碌。但是这样的人,他的目标是否达到,并不取决于自己,而是取决于别人的评价,所有的“成功、金钱、地位、名誉”,如果 不被别人承认,就什么都不是。我并不虚伪的反对这样的追求,但是如果只有这样的追求,人生是不完整的,可以说这样的人完全是为了别人的评价而活着,却没有 为自己而活着。这样的人,尼采称之为“骆驼”。我不愿意做这样的“骆驼”,因此需要继续作下面的选择题。 
  在我的“信仰地图”中,有三个大的 方向,科学、哲学与宗教。有人选择科学作为信仰,也有人选择哲学作为信仰,但是在我看来,无论是科学还是哲学,其基本的精神,都与信仰格格不入。当你成为 科学的信徒,你就违背了科学的精神;当你成为哲学的信徒,你就违背了哲学的精神。这样的人,在世界上的确不少,而且也的确在为害着这个世界。从历史上来 看,科学的信徒与哲学的信徒,为害世界的事情还真不少。也许有人要问,宗教的信徒不也一样为害世界吗?但是区别在于,宗教的信徒只是“可能”为害世界,而 科学与哲学的信徒,则一定会为害世界。 
  有人也许还要问,我是科学的信徒,但是我信仰的是科学的精神,难道也会为害世界吗?科学的精神,当然不会为害世界,但是这样的精神只是探索世界的一种方法,他只需要遵循,而不需要信仰。只存在是否严格遵循的问题,而不存在是否相信的问题。 
   同样的问题,也会有人问出来而为哲学辩护,在我看来,最好的哲学与最好的科学一样,一个使人奋进,一个使人冷静。科学的生命力在于始终遵循科学的精神, 而哲学的生命力在于不断的反思自身,甚至于整个哲学的基础。科学如果被人信仰,最多是科学的发展受阻,哲学如果被人信仰,整个社会的发展都有可能受阻。 
  既然科学和哲学都不可能成为我的选择,那么选择题就要继续进行,在我的“信仰地图”中,宗教又分为两个大类,一种是以个人为中心,另一种则是以社会为中心。前者包括了佛教、道教以及基督教等等众多宗教,后者则主要以儒家为代表。 
   以个人为中心的宗教很容易吸引人,因为这样的宗教讨论的问题是以“我”为中心的,解决的也是“我”的问题。当一个发现自己不应该为了别人的评价而活着的 时候,首先会想到的选择就是为了自己而活。当一个人发现对于外在的追求不再有吸引力的时候,走向自己的内心就成为唯一的方向。 
  在中国古代, 儒家遭受了普遍的误解,就是因为儒家的追求很像是向外的追求,读四书五经是为了做官,参加科举是为了功名利禄,所有的这些追求都可以说是外在的,世间的, 无常的。但是儒家信仰,与功名利禄追求,存在着重大的区别,一种是为了别人的评价而活,另一种却只是纯粹的为了别人而活,别人的评价是指向自己的,说到底 是为了满足自己的欲望,只不过这样的欲望需要通过别人的评价而得到满足。而儒家的信仰不是这样的一种个人欲望,这样的追求中没有一个“我”的存在。 
   无论是对世间功名利禄的追求,还是对于宗教的、出世间的追求,核心的理由都是为了“我”,只不过追求的目标一则现实,一则缥缈而已。因此,到了现在这个 社会,当儒家学说失去了科举做官的现实用途之后,要想使人信仰他,就变得非常的困难,因为他从不满足“我”的欲望,也从不许诺各种个人的好处。他的吸引力 就几乎不存在了,而现在的儒家信徒也就几乎不存在了,除了一些大专院校的儒家学说研究者,几乎没有人还会再接触儒家的思想,更不要说产生信仰了。 
  但是,我的选择,最终还是儒家信仰,有很多可以说的理由,而最大的理由,就是因为这种信仰不是为了自己。有很多名人名言深深地打动了我,例如:“先天下之忧而忧,后天下之乐而乐”、“为国为民,侠之大者”、“为天地立心、为生民立命、为往圣继绝学、为万世开太平”。 
  说到这里,我的这篇文章也就算结束了,但是关于儒家的话题,这却只是一个开始,毕竟可以讨论的东西,真的很多。

posted @ 2006-03-24 11:22 @家军 阅读(473) | 评论 (1)编辑 收藏

世界不在意你的自尊

(考虑再三,还是要转贴一些有用的话)
比尔盖茨十条职场箴言曝光:世界不在意你的自尊
1.生活是不公平的,要去适应它;
2.这世界并不会在意你的自尊,这世界指望你在自我感觉良好之前先要有所成就;
3.高中刚毕业你不会成为一个公司的副总裁,直到你将此职位挣到手;
4.如果你认为你的老师严厉,等你当了老板再这样想;
5.如果你陷入困境,不要尖声抱怨错误,要从中吸取教训;
6.在你出生之前,你的父母并非像现在这样乏味。他们变成今天这个样子是因为这些年来他们一直在为你付账单,给你洗衣服,听你大谈你是如何的酷;
7.你的学校也许已经不再分优等生和劣等生,但生活却仍在作出类似区分;
8.生活不分学期,你并没有暑假可以休息,也没有几个人乐于帮你发现自我;
9.电视并不是真实的生活,在现实生活中,人们实际上得离开咖啡屋去干自己的工作;
10.善待乏味的人,有可能到头来会为一个乏味的人工作。

posted @ 2006-03-21 11:06 @家军 阅读(328) | 评论 (0)编辑 收藏

TOMCAT内存溢出之解决方法

问题表现:

当用户执行一个大数据的应用时(净字节码量约为5M)时,系统会提示出错:

前台错误为:HTTP Status 500-Dispatch[EAITool] to method listCurTree retrun an exception

(以下省略)

………………………………………………………

………………………………………………………

后台错误为:java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start(Native Method)
        at org.apache.catalina.loader.WebappLoader.notifyContext(WebappLoader.ja
va:847)

(以下省略)

………………………………………………………

………………………………………………………

问题分析:

   由于TOMCAT内存溢出而引发的问题,主要原因是JVM的虚拟内存默认为128M,当超过这个值时就把先前占用的内存释放,而导致好象TCP/IP丢包的假象,出现HTTP500的错误。  
     
解决方法主要是加大TOMCAT可利用内存,并在程序当中加大内存使用。

解决方法:

方法:加大TOMCAT可利用内存:
  在TOMCAT的目录下,也就是在TOMCAT41/bin/catalina.bat文件最前面加入
  set JAVA_OPTS=-Xms800m -Xmx800m
  表现效果是当你启动TOMCAT时,系统内存会增加近800M使用

操作方法:
  1)、先关掉WINDOWS服务当中的TOMCAT4服务。
  2)、再找到TOMCAT/BIN目录下startup.bat,双击打开它,你会发现现WINDOWS内存占用会增加近800M
  3)、执行程序,因为是TOMCAT重新编译程序,所以第一次会比较慢。

结论:

经过测试,我们得出如下数据:

系统传输约2000条数据时,大约近12M的净数据(不压缩时),系统辅助运行的内存大约占用150M左右的空间,也就是近200M的内存占用,而我们扩大了近800MJAVA内存使用,这对于业务本身来说是足够了。所以你们不用担心大数据量的传递问题。

基于JAVA虚拟机的原理,JAVA自动有垃圾回收机制,也就是在你对一些内存长时间不使用时(近2分钟,取决于使用频度和优先级等),就会自动垃圾回收,从而释放不用的内存占用。

posted @ 2006-03-10 14:15 @家军 阅读(9097) | 评论 (2)编辑 收藏

MYSQL BUG #5020及解决方法

MYSQL BUG #5020
描述:
   MYSQL网站BUG公示
错误MESSAGE:
    
Connection was closed due to the following exception:

** BEGIN NESTED EXCEPTION ** 

java.sql.SQLException
MESSAGE: Communication link failure: java.net.SocketException, underlying cause: Software caused connection abort: recv failed

** BEGIN NESTED EXCEPTION ** 

java.net.SocketException
MESSAGE: Software caused connection abort: recv failed

STACKTRACE:

java.net.SocketException: Software caused connection abort: recv failed
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.
read(SocketInputStream.java:129)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:
183)
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:
222)
    at java.io.BufferedInputStream.
read(BufferedInputStream.java:277)
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:
1385)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:
1532)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:
1923)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:
1163)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:
1272)
    at com.mysql.jdbc.Connection.execSQL(Connection.java:
2236)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:
1555)
    at net.sf.hibernate.impl.BatcherImpl.getResultSet(BatcherImpl.java:
89)
    at net.sf.hibernate.loader.Loader.getResultSet(Loader.java:
880)
    at net.sf.hibernate.loader.Loader.doQuery(Loader.java:
273)
    at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:
138)
    at net.sf.hibernate.loader.Loader.doList(Loader.java:
1063)
    at net.sf.hibernate.loader.Loader.list(Loader.java:
1054)
    at net.sf.hibernate.hql.QueryTranslator.list(QueryTranslator.java:
854)
    at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:
1554)
    at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:
1531)
    at net.sf.hibernate.impl.SessionImpl.
delete(SessionImpl.java:1678)
    at net.sf.hibernate.impl.SessionImpl.
delete(SessionImpl.java:1664)
出错原因:
   我们的系统一天24小时运行,但在夜晚的时候是没有人连接的,因此Socket连接就超时了。早上尝试做任何事情(比如:登录)都将以失败告终,除非我们关闭连接或者重新建立连接。3.0.11后才会发生这种情况。
   现在我们使用的MYSQL版本号为4.016,问题一样。
专家建议:
   [Mark Matthews],翻译如下:
   注意:我不赞成Autoreconnect功能,在以后的发行版本中,它最终会被移除。在这种特殊情况下, 它不起作用的原因是:在3.0.11以后,autoreconnect的方法变得更加安全了并且和阿utoCommit状态有关联,这样的话就能使当前‘in-flight’事务失败(如果你在失败后,再次试图连接事务,就会重新被连接)。请查看相关解释文档,文档的修复故障中包括如何正确实用这个属性。无论在哪种情况下,   如果TCP/IP在没有连接的情况下并且还不会冒着数据库被瘫痪的危险,是没有百分之百的方式使得JDBC驱动器被自动重连接的,这也是为何要移除Autoreconnect功能的原因。不管网络发生什么情况,    JDBC 都不会说明这个连接是否处于连接状态。JDBC driver 客户端负责处理网络故障,只有应用程序本身(实际上是应用程序的开发者)知道如何正确应对事务失败的情况。在服务器上过期的‘Waittimeout’基本上是服务器给与的强制性网络故障。你通过把‘Waittimeout’设置的高点儿就可以改正它,尽管如此,作为一个开发者,你的代码应该包含相关的异常处理并采取适当的恢复措施,不要都把它们传到调用堆中。
   连接错误总是有一个SQL状态‘08’。如果你发现它的话,你可以再连接一次并重试事务(如果是适当的话)
   不管什么原因,如果这样不起作用的话,配置你的连接池来测试是否处于连接状态并且那些长时间闲置连接(所有的连接池都能这样做,但是它们的配置取决于池子)。
作者说明:在MYSQL4.1以后的版本当中,没有“wait_timeout”变量,由
interactiveClient代替
参考资料:http://dev.mysql.com/doc/connector/j/en/cj-configuration-properties.html
     [
Kirk Wylie]:翻译如下:
   
如果有一个事务在运行的话,就能得到一个特别简单的例子:
    
---如果连接在autoCommit模式下,autoReconnect是安全的。
    
---如果连接不在autoCommit模式下,但是没有打开的事务,autoReconnect是安全的。(因为连接可能在池在里面)
    ---如果连接不在autoCommit模式下,有打开的事务,这样就会抛出异常。
   
这样会解决你不在autoRecom\nnect模式下的忧虑并且会保留应用程序的功能性。
   尽管如此,在它改变的时候,在改变日志中没有任何记录说明发生了改变,这点令我很烦。由于这种改变很可能破坏我的应用程序,这种变化因该添加到CHANGE文件中。

  如下是我个人的做法:
  (STRUTS+SPRING+HIBERNATE)
  1、把mysql的变量
interactiveClient由 默认的28800(8个小时)延长。并告知用户多长时间后,重新启动TOMCAT服务器。不过,MYSQL5.0.12版本以前的所有版本,只要你设置成 了默认语言为GBK,所有对interactive_timeout(wait_timeout)的时候如何设置,重新连接或者重新启动MYSQL后,都 是28800,现在我使用的5.0.18后,使用GBK,没有问题。
  2、在HIBERNATE当中加入:
   
..
<property name="hibernate.connection.url">jdbc:mysql://192.168.100.111/eai?autoReconnect=true</property>
<property name="enableDeprecatedAutoreconnect">true</property>
<!--  如下的语句是使用第三方的DBCP来建立连接池 -->
<property name="dbcp.maxActive">100</property>
<property name="dbcp.whenExhaustedAction">1</property>
<!--  看到了没有,这个maxWait一定要大于MYSQL默认的28800(秒) -->
<property name="dbcp.maxWait">30000</property>
<property name="dbcp.maxIdle">10</property>

<property name="dbcp.ps.maxActive">100</property>
<property name="dbcp.ps.whenExhaustedAction">1</property>
<property name="dbcp.ps.maxWait">30000</property>
<property name="dbcp.ps.maxIdle">10</property>
..
    
 如上两种方法均可,推荐大家使用第二种方法,来遮挡一下MYSQL的BUG。
如果有不对之处,请大家提出自己的见解。

posted @ 2006-01-18 14:48 @家军 阅读(5661) | 评论 (0)编辑 收藏

2006年之创业狂想

  风风雨雨几年IT生涯,从刚刚开头不敢说一句话,到现在在企业工厂与客户指点江山,答疑解惑,好不胜哉。
  ERP的实施和开发将影响我一生的IT生涯,我也致力探索其技术,交流发布其管理思想,不过2005年让我在技术的领域里磨砺着这把剑,呵呵,梦寐以求的J2EE技术有所长进,不过还需要再接再厉,更上一层楼。
  这一年来,我看好开源代码给人们的生活带来的实惠和方便,我也曾经预言开源代码将为我淘得第一桶金。可能是时机未到或者自己修炼还未果吧,至今还要努力学习。
  所以,我的最大快乐就是技术转化成生产力,让企业的应用上一个新的台阶,让管理的先进思想长驻企业内部。
  我想,2006年,有必要创业:
     创立一个利用开源代码引导应用为主的论坛。
     初步的分类可以使用现在www.open-open.com的分类来做。
     与www.open-open.com网站建立联盟关系。
     我的工作表现在对网站的管理上,发表原创及使用感受。提倡开源代码当中的管理思想。
     还要加入PHP、PYTHON等新一代解释性语言带来的开源思想等。
     最终目标要扶植几家软件企业应用开源代码来做应用,或者利用开源代码二次开发等。
     理想目标是一到两家公司使用开源代码,我们做服务和二次开发工作。
  另外,从GOOGLE上,感觉到国内对艺术、字画和古玩有热衷的倾向,所以我想做一个交流平台。
  这个平台可以简单描述为:
     艺术家或者收藏家可以通过一定的流程,发布自己的作品和藏品,以照片为例。
     所有的艺术家或者收藏家都可以通过本网站的诚信通道由网站代理出售其作品或者收藏品。
     所有的网站注册用户可以选择自己喜爱的作品进行交易。
     交易通道有两个,一个与作品本人联系,一个与网站代理联系。(考虑中....)
          所有的网站注册用户可以提出自己的个性化需求与艺术家或者收藏家给出答复。(赢利点)
     个性化的需求由本网站代理完成,从中得到应有的费用。做为网站发展的基金。
  艺术和学问是一个知识分子追求的东西,还需要和艺术家和大学问家建立联盟关系,扩大影响力。
        

    加上两幅图片
  我和儿子
259895602.jpg
 爷爷和孙子
259895994.jpg

posted @ 2006-01-12 15:57 @家军 阅读(485) | 评论 (2)编辑 收藏

州牧下的羊叫

古代的地方官员叫州牧,而牧民放牧的是羊和牛。
我是一只小羊,等到黑夜来临的时候,我在羊圈里看见在美丽的星空。一眨一眨的星星和皎洁的月亮。
天空是美丽的,也是完美的,因为我永远都触及不到她,所以她是神圣的。
草原是美丽的,绿色和黄色深深的循环着我的生活。
草原是险恶的,因为哪里有狼,因为哪里有虎豹。
不过我不用害怕,因为牧羊人会帮助我把它们赶走,我不害怕。
我最害怕的是没有草和水喝,因为这里有牛和其它的动物在和我分食。
我没有了草吃,牧羊人会把我赶到一个丰盛的草场去。
我没有了水喝,牧羊人会把我赶到一个小河流去。

呵呵,我没有了忧郁。
呵呵,这只是一个梦。就象美丽的天空一样。

我没有了草吃,牧羊人不知道哪里有丰盛的草场,但是他发现了牛棚里还有草,所以他就去牛棚里背些草过来。可能我还没有吃到,草已经没有了。

我没有了水喝,牧羊人不知道哪里有小河流,但是他发现了牛棚里还有水,所以他就去牛棚里背些水过来。可能我还没有喝到,水已经没有了。

于是我在彷徨,但是发现很多的牛已经在侵占着我们的领域,仅有的草被他们吃光了,仅有的水被他们抢去了。

我们只能向牛屈服,谁让我们是羊呢?

我在想,如果牧羊人:
    如果牧羊人能够了解草场的规律的话,是不是可以让牛和羊分别在不同的季节和不同的草场进食呢?
    如果牧羊人能够深暗天理地势的话,他能够不辛苦的背水背草呢?
    如果牧羊人能够按照天道地道来办事的话,他是不是会得人道呢?
    人道才是真正的平民力量,也是大海里的海浪和波动。

posted @ 2006-01-12 11:33 @家军 阅读(389) | 评论 (1)编辑 收藏

2006年之梦境杀手

  我来到思奥特公司已经有一年多了,应该是老员工了吧。
  但是我近段时间以来感觉到自己的一种无奈,冲不破的霸权管理和无聊可笑的管理者。
  于是我想变了。
  “穷则思变”,-毛泽东
  我想自己是一个超级深水潜水员,因为我喜欢大海,喜欢到大海的最深处,用自己的生物电照亮大海。
  我想写一些文章,在谈谈今年的感受,也是IT的人生感受吧。
  我想写:软件工业化生产之梦境管理
      软件工业化生产之梦境开发
      软件工业化生产之JIT生产
      软件工业化生产之超级服务者
  我很想用WIKI来写这些东西,SPRING的诞生是由一个梦想开始的,软件企业的管理和生产也应该有一些理论的指导吧。我很想写出自己的感受,当然我也需要大家的力量,所以我要加入鹰之队,我要WIKI。
  利用现在的空闲时间我要努力学习。我要开创一种利用开源软件做载体来极限学习的方法。
  我还有一个伟大的想法,我想开办一个利用开源软件尝试使用到实际应用当中的论坛,我想康比尔,我想OPEN OFFFICE VS M$,我想OPENCMS。。。。。。
  可能2006年将给我带来一个应用技术年吧,我想发挥我的一点热量,想重新营造IT界在中国的管理和生产。
  请大家关注我的贴子。

posted @ 2006-01-11 10:15 @家军 阅读(355) | 评论 (4)编辑 收藏

多数据库实现数据交换的可行性技术研究

2005年在给领导买关子时写的一篇文章。现在读起来也有意思,
大家可以看一看,多拓展一些思路。
多数据库实现数据交换的可行性技术研究

posted @ 2006-01-09 16:44 @家军 阅读(417) | 评论 (0)编辑 收藏

我快速实施的遭遇

我实施A公司的EAI项目以来,边需求调研和代码开发及最近的正式上线,只用了两个月的时间。项目很快就实施完成了。
今天开会,表示我的EAI项目完成。本来很高兴的事,让领导肯定一下我的成绩,谁知道领导毫不犹豫的把我调到另外一个项目组做CRM分析了,我操(本年度最难听的话),我是万精油呀,到处抹。项目经理一下子变成一个小职员。
CRM是一个烂摊了,即使我做过ERP也知道公司负责CRM调研和分析哪几个人是什么水准。我绝对反对领导这样做,太霸道了,看来这个小公司的弱点已经让我看透了。
埋炸弹。引爆所有程序。

posted @ 2006-01-09 15:32 @家军 阅读(312) | 评论 (1)编辑 收藏

EAI项目实施心得

  这一段时间,忙于在代码和A公司之间奔波,所以日志也没有时间来写。
  今天谈谈我近段时间在客户实施的心得。
  到现场实施情况是比较复杂的,所以从刚刚开头我就没有像专家一样的到处都问(调研时可以像专家一样告诉客户一些大道理)。我们的程序是基于合同技术附件签订的,实施也就跟着签字的需求和目标走。
  由于前一段时间让一群学生写了一些代码,虽然在质量上我有所“查阅”,但是问题最大的也就是在这里,在实施前只是把大致的错误进行了修改,就匆匆到现场实施。
  核心代码由于是自己的思想,也让放心的手下写了,但是还必须得测试和验证其准确性。这是一个重要的工作,也可能会涉及到一些改变。
  第一天,到了客户现场,先是对其环境要求,确定完主机和数据库后,就开始安装布置,1个小时后全部搞定,基本上给客户讲了一遍怎么使用(很粗略,因为 以后我们有培训)。接着就联合PDM系统和ERP系统进行测试,还幸运(不相信迷信也这么写),没有出事,用户的输出结果也正确,呵呵,收工回家。
  其实,里面的问题很多。只是用户对这个陌生的事物还有好奇的心理,没有深入去学习它。
  第二天,接着实施,在不断的测试过程当中,问题就出现了,很小的问题让客户对我的软件产生了怀疑,比如供应商编码和供应商PN号为什么输出是一样的? 员工ID为什么传递不过来?假如PDM发布同一个树但有不同的组成结构时,做的处理不符合我们的实际业务?为什么不同层次的装配件再次发布时,数量不相 加?假如我这一次发布错了,能不能删除?
  客户提出了很多问题,我知道我的程序开始让用户认可了,所以我的态度比较友好,(说实在的,哪时候真想找个替身),我把问题罗列出来后,做了归类,并给客户承诺完成时间,并态度友好、热情、友善、和气。。。。的给用户出错原因。当然心态必须是诚实。
  一般客户会提出这几类问题。
  一、软件本身的BUG,是自己的责任,勇敢的承认自己的错误,合同都签定了,还不让修改一个BUG。
  二、在实际需求时,考虑的不充分,或者是技术实现上有制约的地方
  三、实际业务和输出结果不符合。
  这三类问题,前两类我们很积极并承诺尽快得给用户解决,就是不在合同之内的事也加入代码实现,我们的目的就是先让用户使用起来。
  第三类问题,不管用户多么着急,我们也对之的实现优先级降低,同样必须让用户书面提出需求我们再做。
  后来的三两天就是修改程序,不过这个时候我手下已经没有人了,所以我自己这两天很辛苦。同样,也发现了很多错误,尤其是表现层,我真是恨这帮学生呀。害的我不得不对之进行修改。
  再以后就是实施,就算是我的第二个阶段吧。
  这个阶段里,我就象一只狗似的,看见客户负责人就赶紧用舌头去舔人家的脚,(想起了发廊的小M辛苦的为我按摩),晚上人家都下班了,为了赶进度只得自愿加班,晚上经常9点后回家。
  这个阶段里,是比较富有成果的,首先把客户前一段时间的BUG和考虑不充分的地方进行了弥补,而且用户对我修改的速度也很佩服。呵呵。(高兴的我自己好象是一个伟大的。。嗯,实施家)
  等到用户测试结果正确,不,应该是准确(我的认为),而且从长期的测试来说,我心理比较塌实了,我进行第三个阶段。修改需求并加入新的程序。
  这个过程比一个阶段好一些。我可以坐回公司来,上上网,聊聊天,喝口茶,再写写程序了,一两的活两天干,还能混吃两顿饭。呵呵,目前就实施在这里。

  对EAI产品本身我给用户提供了一个规则,因为我的软件当中有版本管理和BUG提交模块,所以我每一次的修改就对版本有所影响,小的改动加小版本,大 的改动加大版本,说来也巧,等正式上线刚才从0.8上升到1版本。呵呵。同样用户的BUG管理只开放给系统管理员,我可以每天收集一下BUG,并及时进行 修改。

  对TOMCAT中间件服务器和程序本身的性能优化是一个大问题,现在正在解决当中。
  程序的稳定性和并发控制也准备在下一期进行修改。

  请关注我的贴子。

posted @ 2006-01-05 17:57 @家军 阅读(1212) | 评论 (2)编辑 收藏

我对快速编程的设想

我没有什么敏捷、什么XP编程的概念,所以我这次的格斗没有套路。
从去年开始我担任了项目经理一职,已经负责公司的三个项目的开发和实施了。
我可以籍以此发表我的看法。
本主题内容是极限开发
首先说说我概念当中的极限开发。
项目特点:面向应用、面向服务的中小企业应用。
先哆嗦一下业务需求
我们在实际调研企业现状后,最大限度的了解与我们应用范围相关的实际业务。随后进入业务需求分析,其实就是抽象实际业务到软件功能设计。同时考虑到我们应用 范围外的业务,用户可以不太关心这一块,但是我们必须得做。最终的业务需求分析由公司内部评审,(尽管我们的管理不完善,但是我有权力让什么也不懂的领 导参与),再与客户去交涉。直到取得最终评审。
极限开发之前:
我们首先要做概要设计,其实是对前业务需求分析的细化,当然这文档是面向业务的,这个文档是修改最多的,所以在你开始写这个文档以前一定要做好版本管理(包括有效版本的管理)。
概要设计长话短说吧,就是对企业实际业务管理的理想模型,是尽可能的去理想(理智的想象,而不是单纯的想象),同时不能够把软件的功能划分在合同的需求功能之外(这个一定要把握一个度的问题)。
概要设计是一个相对漫长的过程,这个过程马虎不得,一定要有耐心说服用户和有权力的领导,说什么能做,什么不能做,我们为什么这么做,以及变通的业务实现等等。
极限开发之数据库设计篇
大家可能不理解,为什么我首先要对数据库进行设计呀,这个完全和我的习惯有关。(我的地盘我做主)
在对以上概要设计完以后,我的心理就对实际的软件功能有具体的描述了,当然这个是我最清楚了,我在写概要设计的时候会把这些映射成软件的具体实现,并且使 用一些工具比如VISIO在写完概要设计的实际业务时,我会把软件的实现图、逻辑图同时画出来,害怕以后没有时间来想这些,呵呵。
所以在其后的工作当中,我对软件的具体实现就胸有成竹了,所以我直接进行数据库设计。
数据库设计我使用DB Design,这个工具很好用,我在数据库设计时有两个准原则:
原则一:数据库表对应程序功能模块,一个模块一个前缀,并且如果无太多关系的业务模块对应一张表,并且这些表没有关联关系,都是独立的。
原则二:所有的表如果无复杂关系都使用统一的UUID做为主键,同样,如果处理同样的事务,字段名能够统一的话就统一命名,或者有统一规则生成等。
根据以上原则,我的数据库表没有想象当中的复杂,所以在程序实现时就不用考虑数据库间的关系。
极限开发之程序实现-统一增加、删除、修改数据库
数据库设计完以后,就建立映射成实体,并根据现行的软件架构实现统一的对数据库的增加、删除、和修改的操作,比如现在的STRUTS+SRPING+ HIBERNATE的架构,我根据数据库表,生成对本数据库表的增加、删除和修改的类接口,剩下的工作由下面的员工完成,(很想自动生成,但没有时间来写 这些东西。以后这个东东肯定会有人发明)
极限开发之程序实现-封装业务逻辑层
我一般使用VISIO或者现在的WEB FLOW给手下的员工画出程序实现方式,让他们来完成,我的工作是检查他们的代码是不是符合规范,是不是能够符合 业务需求,所以这个时间我的主要工作是质检和修改程序实现的业务逻辑,(有些刚刚毕业的大学生,你要给他讲明实现的业务关系呀,还不如告诉他你应该往哪个 表插入什么数据来得快,这是一个怪圈)
极限开发之程序实现-关键业务实现
关键业务的实现是至关重要的,这个我一个可能是不行,而且可能当时用户的需求在改变或者改进等,所以我就要找一个比较实在、能力比较强的员工来担任这个职务,要尽可能的给他讲明实际的业务和用户需要的效果和目的,说不定他还能帮助你的思维呢。
这个是个重要的环节,所以生产的重点就是这里,在最复杂的业务逻辑时,对程序的处理,一定要画个VISIO或者什么图告诉员工每一步的实现如何做,包括很 多的错误处理等。如果你在这里偷懒了,说明你这个项目的有很多的隐患在其中,这个工作比较艰巨,变数也多,需要多多鼓励员工。
极限开发之程序实现-单元测试
单元测试不是很严格,由公司相关人员测试,不过经过我质检过的代码,一般没有太多问题。
极限开发之程序实现-业务测试
根据项目的实际业务来测试,由我和能力很强和人来测试,最后由测试人员来测试,
极限开发之用户试运行及上线
这个就不用说了,要用服务的意识来帮助客户来认知这个东东,就好象到理发店让小妹妹给你按摩一样,不要害羞。也好象很累了到冼足浴室一样,无微不至引导消费。
我的这三个项目分别是库存管理+财务管理、EAI项目和CRM+服务。
用人最多的时候不超过6人,开发周期没有超过2个月的。
库存管理+财务管理  6人  1.5个月
EAI项目       3人  20个工作日
CRM+服务      5-6人 不到两个月
所有项目均是新写。


posted @ 2005-12-27 16:11 @家军 阅读(1826) | 评论 (8)编辑 收藏

无聊工作当中的寻财梦

今天东看看,西看看,一天全浪费在网上乱逛了。
先是看看淘宝网,想开小店,发现自己的帐号内空空荡荡。修改了一下密码后,就不知道做什么了,
又看看软件项目交易网,东看看、西看看,没有适合自己的软件外包项目,可能自己的能力还不够吧,应该多接受一些实际的应用。尤其是WEB应用这一块,不过通过软件项目交易网也可以看到现在市场的一些需求。
到最后浪费了一天的时间,没有看看OPEN-OPEN,没有学习康比尔,没有看看VITEGER CRM,啊,自己的心太野,就什么也学不会,
君子爱财,取之有道,君子固穷。没有办法。
还好振奋起精神吧。好好学习J2EE技术,为自己以后能够像油条一样积累很多的东东。
左右逢源,左右开弓,多好呀。

posted @ 2005-12-23 15:49 @家军 阅读(394) | 评论 (1)编辑 收藏

开源代码学习:Plone CMS系统

Plone
Plone是一种开源的内容管理系统(CMS)。基于Zope,用Python写成。
最早由 Alan Runyan, Alexander Limi, and Vidar Andersen在1999年开始,之后迅速成为流行而又强大的内容管理系统。
Plone 基于 GNU General Public License 发布。它建立在应用服务器Zope和Zope Content Management Framework(Zope 内容管理框架)之上。Plone的名字来源于一个来自英国伯明汉,叫做Plone的电声乐队
官方网站链接:http://plone.org/


很厉害,仅仅14M左右的东东,就有服务器和国际化的所有东东。佩服。CMS市场是不是做烂了,这么多的开源代码。不过操作方面比OPENCMS容易理解,权限管理不像OPENCMS那么复杂。

posted @ 2005-12-21 16:06 @家军 阅读(2126) | 评论 (1)编辑 收藏

Compiere ERP&CRM使用手册

 北京安特比软件技术公司倾情奉献。
所有资源均来自于网上,本人收集整理,只供学习用途。
如果你要转换其它阅读格式,请保留版本信息。
 
  Compiere ERP使用手册.part1.rar 1423KB
 Compiere ERP使用手册.part2.rar 1393KB  

posted @ 2005-12-21 14:54 @家军 阅读(3411) | 评论 (16)编辑 收藏