个人首个C项目上线 @ 11/4/2009

随笔
庆祝一下个人首个C++项目上线,其实10月20号就上线了,这里补上记录一下。

一个多月的加班,是进这个公司以来加班最多的一次,估计也就刚毕业那会有这么加过班吧,一来跟项目比较大有关系,二来也是跟本人新手学习有关系。

这里要感谢导师ivan,C++高手,耐心长辈般(其实年纪相仿)的指导。

这个项目也用到了之前学习和积累的知识:shell,存储过程(统计相关)。

这个系统是卖家客户管理及消息群发,卖家可以管理自己的买家,以及营销自己的商品。很实用的一个功能。
发布于 11/4/2009 18:22:04 | 评论:1

统计sql小结 @ 10/19/2009

分享
1 批量思想,尽量一次表IO,计算尽量多的数据,多使用case when,减少表IO
    实践证明统计的瓶颈不在计算上,而是在IO上,所以要尽量减少表的读取。

2 能用insert不用update,大数据量表避免使用update,用delete和insert来规避
  有这种情况A表包含10个字段,其中第一步可以准备其中4个字段的数据,新增到中间表B,然后第二步可以得到另外6个字段的数据,新增到中间表C
  然后B,C表的数据新增到A表,这里需要联合B,C表一次insert入A表中,而不能先insert B到A表,然后再update C表到A表
 
2 引入中间表 联合查询多张大表时,要引入中间表,两两联合,一步步算出来;

3 要注意加入提示:
  INSERT INTO /*+ append */    去掉不必要的日志
 
  /*+ full(a) */  全表扫描,不走索引(有index的情况下一定要加这个)
 
  /*+ parallel(a 4) */ 并行处理(4个线程同时处理),读取大表的时候要加
 
  /*+ use_hash(a, b) */ hash关联,提高联合查询效率(会先把小表hash存储)
发布于 10/19/2009 11:52:48 | 评论:1

慢慢恢复中 @ 10/15/2009

随笔
那个天杀的篮球赛,那个天杀的贼,我的包丢了。。。能丢的都丢了。

我自认为是很小心的人,但是那天大家的包堆在一起,确实没想到我的包会被偷。

事情过去几个月了,丢的东西也慢慢新置回来了,工卡、token卡、钱包,手机,眼镜,还有小强在帮忙办的身份证。。。

感谢gai,感谢小强。。。

得到一个教训:身份证千万不要随身带!!!!!
发布于 10/15/2009 12:30:18 | 评论:5

梦见初中同学 @ 3/8/2008

随笔
今天是妇女节,祝广大女性们节日快乐!

很奇怪,早上从梦里醒来,梦见的是初中同学!

初中时代是我的一段不愉快的时期。我并不想用“灰暗”这种词,因为我知道自己不应该再抱怨什么。

那时候为了有个好成绩,每天想的事情就是怎么让自己的学习成绩更高。每天除了啃书本做题目,不会再有更重要的事情。别的事情都能放下,唯独学习成绩不能放下。当然当时也是有原因的,或许是身边的亲人对自己寄予很高的期望吧,具体是谁,我也不想再提了,因为确实觉得不想再去为这个事情去抱怨什么了。

在有人管束的日子是很难受的。当时的心态也是复杂的,我觉得我不用别人来说我,所以有逆反情绪,但是我又没有以罢学来发泄这种情绪,依然做着为了成绩而努力的事情。

在这种背景下,我失去了太多同学情谊,也就没有从中得到太多的乐趣。当然用功学习和同学情谊并不是矛盾的。只是我当时心胸实在是狭窄,不会想着和同学去玩,不会想着和同学分享自己的东西。

在初中我伤害过一个女生。当然是仅用言语伤害,大家不要想多了。我当时对她说:“反正你也帮不了我”。虽然后来她说正是因为我这话让他变得振作起来,但是我到现在想起这个事来心里还是会有疼的感觉。

在初中,有一次化学老师叫我收集一次考试里成绩较高的同学,因为他没登记,而这个考试是有排名的,姑且叫这个为“排名赛”吧。我当时就由于不太相信有一位同学能考那么高分而没有登记他(当然并不比我的高了)。后来他表示过他的不满,但是再后来他也没再跟我计较这个事了。

是不是很残忍。

梦见了他们,醒来觉得自己真的想他们。梦里出现了lfx,lcm,ljp,kwc,zzl,包括之前说的那个女同学和那个男同学。梦见在初中那座学校见到他们,他们回学校上50天的补习班,说可以拿到什么硕士的文凭,哈哈。见到他们,我是极其夸张和兴奋的,或许把我现在的风格融进去了吧。

对不起的话不想再说了,“再给我一次”的话也实在是无聊。只是我觉得每个人都真不容易,可以的话,尽量为别人多做点事,尽量去善待别人。

一会就给初中同学ljp打电话!
发布于 3/8/2008 10:23:57 | 评论:9

湖南冷江一行 @ 2/18/2008

随笔
      通过同学,买到了到湖南冷水江的票了,初二出发。这样也就可以按最初的计划进行了:先在我家里过年然后再去她家。

    由于除夕那天她还要上班,所以我二十九那天就提前回家了。然后年夜饭她在深圳和亲戚一起吃,初一那天再来我家。然后初二我们再从家里出发,去深圳坐火车。这一趟的折腾多亏了有车人士阿Ted,他把gai从惠州接到我家,第二天再叫他老弟一起送我们到深圳。

    初三那天来到了湖南冷水江。

    好一座煤灰城!下了火车出了车站,打车过去,看到的房子是灰黑灰黑的,路也是灰黑灰黑的。往后一些天里更能领略到冷江的这个特色,以致一见到她的同学就说是冷江的survivor。

    下了车,往她家里走,我的心情还是有些紧张的。

    来开门的是她妈妈,可以看到她妈妈手上还缠着绷带。大家笑脸以对。然后就看到了他爸爸,他爸爸并没有多少笑容,给人有威严的感觉。然后还见到了她外婆、舅舅、三姨、小姨等人(她二姨去深圳过年了)-------可谓一个大家族啊!

    饭桌上我被分配了一小瓶52度邵阳老酒(似乎是叫这个)。好像长那么大人了还没喝过这么高度数的酒。开始喝了几口,感觉还没事,但过了会就感觉到头晕了。不过还好,听说我头开始晕了,她家里人并没有勉强我再喝。那天她老爸也陪我一起喝酒了,听她说她老爸现在是已经戒酒了,只是我来了所以就高兴也喝起酒了。

    往后几天的主要内容是去她爷爷家、去她小姨家吃饭、去波月洞、见她的同学、给她爸妈买电脑,还有一帮人陪着她妹妹买衣服。

    在冷江的这些天里感觉还是很好的。吃到往年吃不到的菜,其中基本每餐都有的是糯米丸子,也是我吃最多的一个菜了;她老爸老妈都很热情,很体贴细心。他老爸乍一看是一个很严肃的人,但是接触多了会发现他是一个很有趣的人,能开别人的玩笑,也能被别人开玩笑;在她亲戚家转了一圈,红包也收到不少,哈哈。 
 
    初十这天又要离开冷江回来上班了,这天她同城的亲戚也都过来吃饭送行了。易宝问我在这好不好玩,我说我来这是面试的不是来旅游的。然后她问那面试结果如何,我说应该可以拿到offer了,哈哈。



长假回来,还未能马上进去上班状态,所以写下该blog。
发布于 2/18/2008 11:13:03 | 评论:5

AOP的应用 @ 10/17/2007

分享
1 关于AOP
   
AOP(Aspect Oriented Programing),面向切面编程,是一个编程思想。简单地说就是在做一件事情之前、之中或之后插入别的要做的事情。
   
具体地,可以定义一个方法执行之前要做什么事情,执行完成后要做什么事情,有必要的话还能定义在这个方法执行之中要做什么事情。

AOP需要有技术来支持。目前用于支持AOP思想的技术主要有三种:AspectJ、CGLib和java动态代理。其中,

AspectJ是一种语言,可以说AspectJ是最贴近AOP思想的。AspectJ有自己的一套关键字来定义AOP的相关元素,比如一个Aspect切面。AspectJ是对一些类和方法定义切面,编译的时候是先把“被定义”的类(目标类)编译成class文件,然后再结合定义好的切面信息对之前的这些class文件再次编译,生成新的class文件。那些定义的切面信息其实已经被直接写入到最后编译出来的class文件里。个人认为这个过程要对在目标类的class文件进行再次编译解析成新的class,具体使用起来有些不太方便。
   
AspectJ是直接修改目标类的class文件来达到AOP的效果的,而CGLib和java动态代理都是通过代理目标类来实现的。
   
CGLib(Code Generation Library),字节码生成库,是第三方写的开源包。原理是使用字节码技术动态创建目标类的子类,运行时的类型已经不是目标类,而是目标类的子类。然后,CGLib允许定制子类的执行方法,在执行父类(目标类)的方法之前和之后切入(插入)要做的工作。所以CGLib是对类进行代理,通过动态创建该类的子类来达到代理的效果。下面说到的java动态代理则是对接口进行代理。
   
Java动态代理是java jdk自带的,就在reflect包里。Java动态代理是对接口进行代理,根据传入的接口类型动态生成一个实现类,然后可以定制这个实现类的一个回调接口。在定制这个回调接口时,就可以在调用目标类方法时,在目标类方法之前和之后加入一些要做的工作。
   
目前用的比较多是CGLib和java动态代理,spring和hibernate都有用到。
   
2 具体应用

2.1 数据库连接和事务管理
   
利用AOP的相关实现技术,获取和释放数据库连接、申请事务、提交事务或撤销事务这种工作可以放在一个集中的地方来做。把这些工作放在主流程之外去定义。然后在主流程的代码里再也看不到connection这种东西,当然也不用去关心跟connection有关的工作了。

具体做法上,首先对业务方法进行配置,定义该方法是否需要事务。配置内容如下:
<class>
<name>com.xx.xx.BankBizlogic</name>
    <method>
    <name>add</name>
    <transaction>true</transaction>
     ……
   
上面配置的意思是定义BankBizlogic类的add方法是需要事务的。
   
这样如果add方法正常执行完成则提交事务,如果中间抛出异常未能正常执行完则会撤销事务。
   
这个具体是采用CGLib对业务类进行代理,即目标类是业务类。下面的代码是CGLib回调接口的定制实现,先来看看:
   
/**
    * CGLib回调函数
*/
public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable
{
    //目标类方法执行前要做的工作
    //比如获取连接,是否要申请事务等
    MethodConfigInfo methodConfigInfo =
              ResourceManager.beforeBizMethod(superClass,obj,method,args);

     Object result = null;
     try
     {
        //通过代理类调用父类即目标类中的方法
         result = proxy.invokeSuper(obj, args);

         //目标类方法正常执行完后要做的工作
       //比如提交事务,关闭连接                
              ResourceManager.afterBizMethodForNormal(methodConfigInfo);
     }catch(Exception e)
     {   
        //目标类方法出现异常,则做撤销事务等工作
         ResourceManager.afterBizMethodForException(methodConfigInfo,
     e);
           throw e;
     }           
     return result;
}
   
上面的方法是定制的CGLib回调接口。可见其中beforeBizMethod、afterBizMethodForNormal和afterBizMethodForException分别在调用目标类方法proxy.invokerSuper之前和之后执行。
   
beforeBizMethod会根据配置文件信息,决定该目标类的业务方法是否需要事务,如果需要则获取连接,启动事务(把连接的自动提交属性设为false)。来看看beforeBizMethod的部分代码:
   
if(methodConfigInfo != null)
{
    //判断当前线程是否需要启动事务,如果需要:   
    if(Boolean.valueOf(methodConfigInfo.getTransaction()).booleanValue())
    {               
         //如果还没初始化过,则通知DBConnManager启动一个事务
         if(resourceInfo.getConnection() == null)
         {
               DBConnManager.startTransaction();
         }
     }
    }

afterBizMethodForNormal/ForException则做一些数据库连接的收尾工作,比如提交/撤销事务,释放连接。这里不再细述。
   
这里会有一个问题,就是怎么可以使目标类里的方法使用的数据库连接就是之前beforeBizMethod方法获取的连接,而afterBizMethod方法释放的也是同一个连接呢? 
   
这里其实还用到了java jdk提供的一个类ThreadLocal,这个类的作用是保存线程的资源。在对一个线程执行过程中,之前在某个地方往ThreadLocal实例里存放了资源对象,之后在别的地方仍然可以通过ThreadLocal拿回之前存放的资源。
   
其实ThreadLocal的基本原理也就是一个Map,然后key值是Thread.currentThread。所以每个线程都能随时随地访问和设置各自的资源,而不会搞串。只是这个Map其实是存放在current thread中的,是当前Thread对象的一个包可见属性,所以当current thread执行完毕要被回收时,这个Map也会被回收。

2.2 日志功能
   
跟传统的日志不一样,这里说的日志是可以根据请求处理类型分类产生不同的日志文件。

具体的做法和上面的数据库连接管理类似。也是根据配置文件的信息,决定日志文件的输出位置。
   
和上面数据库连接的管理一样,日志文件的建立和关闭这些工作在一般编程时也不用关心,只需要调用日志工具类提供的info或error方法进行日志输出。
   
配置文件内容如下:
<class>
<name>com.xx.xx.BankBizlogic</name>
      <method>
    <name>add</name>
    <transaction>true</transaction>
    <logdir>addbank</logdir>
    <newfile>true</newfile>
    </method>
    <method>
    <name>findByID</name>
    <transaction>false</transaction>
    <logdir>querybank</logdir>
    <newfile>false</newfile>
    </method>
</class>

这个配置文件和上面提到的配置文件是同一个配置文件。其中配置项logdir是方法的日志输出目录,配置项newfile意思为是否该方法每次执行时都需要新建日志文件,因为有些请求处理类型是没有必要每次处理请求都需要新建日志文件的。
   
日志文件的文件名格式是:HHMMSS_NO,其中NO是请求序号,为了防止文件重名。另外同一天产生的日志会被放在同一个文件夹下,比如在2007-10-6 12:47:30发生第一次add方法的请求,日志会输出在serverlog/20071006/addbank/124730_1.txt文件里。
   
这样上面的配置指明add方法日志将被输出到addbank目录下,而且每次add被执行时都会新建一个日志文件,findByID方法的日志会被输出到querybank目录下,所有该方法的日志会被输出到同一个文件(因为配置项newfile为false)。
   
而编程时,在日志的使用上则非常简单,只需要像使用传统的日志一样。目前的日志只提供了两个方法:
   
LogTracker.info(Class exeClass, String content)
LogTracker.error(Class exeClass, String content, Exception exception)

这两个方法都是静态方法,可以直接调用。
   
另外,对于没有配置的方法,它们的日志会被输出到当天的一个公共文件里。下图是一个日志输出示例:



serverlog是日志的根目录,这个目录下面是按日期产生的每天的日志,然后日期文件夹下是各类请求的日志。

3 小结

虽然上面说的一些功能效果比较好,但是还是有条件的。就是要遵循本身框架的一些约定来进行,比如要实现对Bizlogic层(业务层) 的代理就得调用Bizlogic层的代理类,所以层间调用会有严格的要求。

另外,上面日志有一个地方是可以改进的,目前的做法是所有日志文件的文件名格式都是HHMMSS_NO,而有些频繁发生的业务可能要求用到别的信息来命名日志文件,比如业务编号等。所以还是可以对日志文件名进行定制和配置。
发布于 10/17/2007 18:30:21 | 评论:8

又聚会 @ 7/22/2007

随笔
由于要离开北京了,所以跟大学同学打个招呼,叫大家一起随便聚聚,一起吃个饭。正好班里也有一段时间没有聚会了,趁这个机会呼吁大家一起聚聚,也是一件很好的事。

很高兴也到了有10来人,虽然有一部分人有事未能参加。

大家一起吃饭,依然是那么随意,说话随意,喝酒也随意。呵呵,跟这帮人在一起感觉真好!


跟大家一起,又想起00242这个班,尤其这个班的男生。00242有很多我值得怀念的东西,其中踢球为甚。

00242的男生几乎没有不踢球的,当时每周都会定期举行几次踢球活动,不管是白天还是黑夜。那个非典时期,对我们来说却是一个值得回味的时期。那时候不用担心场地问题,整个足球场都是我们的。那时踢得真叫一个痛快,一个爽!


毕业后的一两年里,我们仍然经常组织一些足球活动。虽然多数情况下用的是北信那个真草地的两端小半圆的煤渣地,虽然踢完球后大家吃的是学校后面的大红,但是大家依然开心!真的开心!

如今要离开这个生活了7年的地方了,很想说:
00242的男人们,我会想你们的,哈哈~~~~~~~~~~~~

ps:本人其实是主张低调的,并不是一个随便煽情的人。
发布于 7/22/2007 23:39:20 | 评论:15

台球心得 @ 7/13/2007

休闲
    学习台球有半年了,以下总结了三点,拿出来给大家参考参考,以供交流。
    总结起来有“三好”:看好、站好、握好
1 看好
    所谓看好,就是看好瞄准点,如果还没有看好瞄准点,请不要着急趴下击球。
    目标球的瞄准点就是球袋和目标球的连线,该线和目标球的交点就是瞄准点。
    如何确定这个瞄准点?刚打的时候我是走到球袋和目标球连线的延长线方向去看这个瞄准点,看好这个点后再击球。但打多了就没必要这样了,其实你就站在击球的位置去观察就能看出这个瞄准点。从球袋到目标球,自然就找到了那个交点,即瞄准点。
2 站好
    站好在这里就是站稳。只有下半身站稳了,上半身才能更自如地击球。
    如果你是右手握杆,那么右腿伸直,基本上是垂直地面;左腿稍微向前,然后稍微弯曲。所以基本是右腿支撑身体,左腿配合平衡。做得什么程度可以因人而异,但基本原则就是这个。




3 握好
    就是握杆了。握杆也很重要,握杆是否正确直接关系到准度问题。
    用食指和拇指形成的虎口握紧球杆,食指稍微前移(在握紧的情况下前移)。就是虎口握紧球杆,然后虎口稍微前移。手的其他部分就是配合了。中指还会使些力,然后无名指和小指基本就是放松配合了。运杆时,虎口就要握紧球杆,当然不要太紧,导致动作生硬影响出杆。
    这种握杆方法可以让球杆击球的时候抖动最小,就是可以出杆稳。当你出杆稳的时候,有些杆法就能看出效果来,比如低杆,你会看到白球强烈的回旋!提到了低杆,随便补充一下。其实要打出强烈的回旋球很容易!就是要如何保证你出杆稳。而采用封闭式手架(即环形支架)可以帮助你出杆稳,所以打低杆的时候不妨试试用封闭式手架。

发布于 7/13/2007 16:06:55 | 评论:9

开张了 @ 7/12/2007

随笔
    开张了,兴奋!
    早就喜欢上了这里的风格,简单大方!按耐不住跟天魔大哥要了个账号,实在是感谢!欢迎各位来视察!
发布于 7/12/2007 23:15:57 | 评论:18
Tag 云图