Author: Bochun Bai

  • 读书笔记 2010.03.15

    第二部分,执行的要素
    我理解这一步分讲的是一些基础组件,有了这些基础组件就可以搭建起执行的大楼。
    首先第三章讲的是自己,首先要严格要求自己:
    自己要了解人
    自己要了解事
    自己要明确方向
    自己要跟进
    自己要赏罚分明
    自己要培养下属
    自己要了解自己
    书上是用例子解释的上面这些基本素质的,但是要都做到,真得不容易。

    第四章讲的是文化,一个人可以严格要求自己,一群人一起,就会形成文化。
    如何建立执行的文化,首先要统一价值观,其次是建立奖惩制度并贯彻。
    在这章里面,多次提到“情感强度”。比较低的情感强度是执行的阻力。

  • 更新笔记 2010.03.08

    今天更新,在过程中有很多的想法,记录几句话:

    首先进度计划的太紧了,这是后续各种困难的来源。

    比较复杂的问题,一般都是人和人的问题。
    沟通大概要花一半的时间,而灵感只需要5分钟。
    代码,画时间最多的,不是最复杂的部分,是最枯燥的部分。
    遵守约定很重要,可以极大的提高效率。

  • 读书笔记 2010.03.06

    今天听管理培训课程,收获颇多。

    第一个收获是,能力和意愿的循环关系。
    第二个收获是,智力工作者掌握生产工具,与传统工人不同。
    第三个收获是,要因人因事而异的做出判断,管理没有对错。

    讲课的王老师好像住的离我家很近。

  • 读书笔记 2010.03.05

    今天回家比较晚,只有20分钟时间读书。

    第三章开始,讲的是执行的要素,只看了1/3的1/7:了解。了解真的很难,了解事,了解人,还要了解人和事之间的关系。
    增进了解的各个例子,讲的都是沟通。不同的情景采用了不同的沟通方式。

    2/7是“事实”,这7个基本行为,很困难。读起来比较慢。
    争取周末都看完,下周可以尝试改变,提高生产力。

  • 读书笔记 2010.03.04

    今天读书50分钟,读完了第一部分,共两章。

    读《执行》的第一章,有一个让我印象很深刻的比喻,执行是Missing Link。从猿到人的进化过程中,缺少关键的化石证据。在从计划到完成的过程中,同样缺少一个关键的步骤,就是执行。两者都是公认的存在,也都同样难以量化。
    这一章有一段话,说关于实施微观化管理,我理解就是亲力亲为。我联想到了今天在更新时候遇到的推进问题,明天开始要想个办法,让每个人的劲往一处使,心往一处想。

    第二章,执行文化带来的区别,全都是事例。每一个事例阐述了“执行”的一方面作用。执行,可以及早的发现问题;执行,可以知道计划很难执行;执行,可以知道自己的实力;执行,要将力量整合在一起。

    想想以前的团队,每次讨论都在努力达成一个效率最高的方案,并且可以迅速的开展,在进度中还经常会调整具体方案。最终的结果,总是与最初的目标相同。是什么赋予了每个人这样的力量呢?

  • 读书笔记 2010.03.03

    读书20分钟,遇到很多问题。记录以备将来参考。
    读的是《执行》,Larry Bossidy+Ram Charan著,上周项目组述职时候拿到的。

    之前自己对“执行”的关注局限在如何提高执行的效率。今天的20分钟,看过目录和导言,我认为这是一本写给高级管理者(即领导)的书,而我现在还是在做具体事情的角色。对日常工作的直接指导意义不会很显著。

    第一章开端的第一个例子,是个失败的例子。标准、制度、战略、市场、人员、目标、激励、信心,以上这些都没有让目标达成。
    这引起了我的兴趣,因为我们正在做“激励”,做“制度”,做“标准”。

    我想前两章在阐述“执行的重要性”的同时,会有很多具体的例子。明天继续读。

  • Mail乱码解决方案

    使用Mail回复Rich Format格式的邮件时,经常会变成是乱码。打开Terminal输入下面这个命令,可以解决。
    defaults write com.apple.mail NSPreferredMailCharset "gbk"
    写个日志保存,免得重装了以后忘记怎么改。

  • 人人网中间层:实践篇

    之前的问题篇和求解篇描述了人人网在发展过程中遇到的问题,并且介绍了我们采用中间层来提高性能的解决方案。今天的实践篇将通过一个例子来实现一个中间层服务。
    这个服务要达到的目的是快速的查询用户是否有效,数据将要使用bitset保存在内存中,每个用户一位,仅保存正整数约21亿,占用内存256M。

    开始编码

    下面的代码都在这个位置保存:http://gitorious.org/renren/bitserver

    接口定义

    定义接口如下:
    [code lang=”c++”]#include
    module renren {
         struct BitSegment {
             int begin;
             int end;
             Ice::ByteSeq data;
         };
        interface BitServer {
             bool get(int offset);
             Ice::BoolSeq gets(Ice::IntSeq offsets);
             BitSegment getSegment(int begin, int end);
         };
    };[/code]
    这个BitServer.ice文件,通过slice2cpp命令编译成为服务端的Skeleton文件:
    [code lang=”bash”]slice2cpp -I/opt/Ice-3.3/slice BitServer.ice[/code]

    服务端

    有了上面生成的服务端文件后,就可以实现我们自己的业务功能了。
    BitServerI.h和BitServerI.cpp,暂时只是实现了单个get的接口。
    [code lang=”c++”]#ifndef __BitServerI_h__
    #define __BitServerI_h__

    #include

    #define SIZE_OF_BIT 2147483647
    #include

    namespace renren
    {

    class BitServerI : virtual public BitServer
    {
    public:
    void initialize();

    virtual bool get(::Ice::Int,
    const Ice::Current&);

    virtual ::Ice::BoolSeq gets(const ::Ice::IntSeq&,
    const Ice::Current&);

    virtual ::renren::BitSegment getSegment(::Ice::Int,
    ::Ice::Int,
    const Ice::Current&);
    private:
    std::bitset bits_;
    };

    }

    #endif[/code]
    [code lang=”c++”]
    #include
    #include

    int main(int argc, char** argv) {
    int status = 0;
    Ice::CommunicatorPtr ic;
    try{
    ic = Ice::initialize(argc, argv);
    Ice::ObjectAdapterPtr adapter = ic->createObjectAdapter(“BitServer”);
    renren::BitServerI* obj = new renren::BitServerI;
    obj->initialize();
    adapter->add(obj, ic->stringToIdentity(“BitServer”));
    adapter->activate();
    ic->waitForShutdown();
    } catch (const Ice::Exception& e) {
    std::cerr << e << std::endl; status = 1; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; status = 1; } catch (...) { std::cerr << "unknown exception" << std::endl; status = 1; } if (ic) { try { ic->destroy();
    } catch (const Ice::Exception& e) {
    std::cerr << e << std::endl; status = 1; } catch (const std::exception& e) { std::cerr << e.what() << std::endl; status = 1; } catch (...) { std::cerr << "unknown exception" << std::endl; status = 1; } } return status; } void renren::BitServerI::initialize() { for (int i=0; i<0xFFFFF;i=i+2) { bits_[i]=true; } } bool renren::BitServerI::get(::Ice::Int offset, const Ice::Current& current) { if(offset < 0) return false; return bits_[offset]; } ::Ice::BoolSeq renren::BitServerI::gets(const ::Ice::IntSeq& offsets, const Ice::Current& current) { return ::Ice::BoolSeq(); } ::renren::BitSegment renren::BitServerI::getSegment(::Ice::Int begin, ::Ice::Int end, const Ice::Current& current) { return ::renren::BitSegment(); }[/code]

    客户端

    我们使用Java作为客户端,首先用slice2java工具生成Java的Proxy类。
    [code lang=”bash”]slice2java -I/opt/Ice-3.3/slice BitServer.ice[/code]
    然后自己实现客户端代码:
    [code lang=”java”]package renren;

    class BitServerAdapter {
    private final String endpoints_;
    private Ice.Communicator ic_;
    private renren.BitServerPrx prx_;

    public BitServerAdapter(String endpoints) {
    this.endpoints_ = endpoints;
    }

    public void initialize() {
    ic_ = Ice.Util.initialize();
    prx_ = renren.BitServerPrxHelper.uncheckedCast(ic_.stringToProxy(endpoints_));
    }

    public boolean get(int id) {
    return prx_.get(id);
    }

    public static void main(String[] args) {
    BitServerAdapter adapter = new BitServerAdapter(args[0]);
    adapter.initialize();
    boolean ret = adapter.get(Integer.valueOf(args[1]));
    System.out.println(ret);
    System.exit(0);
    }
    }[/code]

    性能测试

    完成了代码,来测试一下性能吧。
    首先启动服务器
    [code lang=”bash”]target/bitserver –Ice.Config=config[/code]
    再启动客户端
    [code lang=”bash”]java -cp /opt/Ice-3.3/lib/Ice.jar:target/bitclient.jar \
    renren.BitServerAdapter “BitServer:default -p 10000” 1022[/code]
    在客户端调用增加循环50000次,单线程平均每秒处理一万次。

    在多线程的环境下,单个服务器每秒可处理的请求8万次左右,已经超过了目前的需要。

  • 2009年的最后一刻钟 我很感动

    在2009年的最后一天,最后15分钟。我在人人网上被铺天盖地的“诺基亚跨年演唱会”带进了一首一首老歌。

    感动的时间,感动的人,感动的歌曲,和大家一起实况讨论。

    这个功能太让我感动了,感谢开放平台为用户做出的一切!

  • 人人网中间层:求解篇

    书接上文,为了提高性能,在人人网的技术结构中,在数据库和页面之间,有中间层。中间层高性能的基础是用内存代替磁盘。

    用内存代替磁盘

    数据库系统的最大瓶颈在磁盘IO,大量的小数据请求不是磁盘的强项。人人网中间层服务就是利用了内存代替硬盘的方法来提高整体性能。有了这层服务以后,以前的数据库关联查询被提前计算并缓存,需要访问时直接获取。
    通用的Memcached缓存方案也有些不足,数据不能自己变化,也不能部分变化。于是人人网选择了自己实现缓存的方式。
    在自己实现缓存的过程中,管理内存相对容易,通信协议是比较复杂的部分,我们在这方面选择了开源的Ice通信框架(http://www.zeroc.com)来完成繁琐的工作,至今它都工作的很好。
    Ice通信框架在人人网完成了两件事,通信和定位。客户端通过IceGrid组件定位到需要的服务地址,将请求发送到中间层服务,中间层服务将结果返回。客户端只需要知道一个地址就可以找到所有的服务;同时,众多服务也可以在不同的服务器之间随意迁移。在现在的人人网有超过500个Ice写成的中间层服务在运行。

    定制的内存数据

    用Ice解决了通信和部署的问题后,中间层服务就是核心的数据结构管理。概括的说,就是灵活变化,保证速度。下面列举若干使用了中间层服务的情况

    一份数据 多种排序

    在人人网的好友页,有很多排序方式可以显示好友列表。每种列表都是从一个按ID排序的服务中获取的,再经过排序,缓存在各个顺序的列表中。

    随时间变化的数据

    在很多列表页面,都会显示“在线标志”,这个标志是冗余在各个列表的缓存当中,定期刷新的。这些需要和cache一起实现的业务逻辑,在人人网中间层当中非常普遍。

    特殊类型

    我们用了一个bit保存用户的激活状态。200M内存可以保存全部int范围的状态。并且查询和更新速度飞快。
    接下来的实践篇将会用这个为例子展示中间层的实现。