安装apache不说了,用apache做django容器的时候(详见参考文献1)遇到如下几个问题,记录一下:

  1. apxs找不到。centos上直接装的httpd-2.2.3-83.el5_10,默认没有apxs。想源码编译一个apache,结果发现源里面有。

    yum install -y httpd-devel

  2. /usr/local/lib/libpython2.7.a: could not read symbols: Bad value

    错误提示里面已经说了,libpython2.7.a没有动态编译。下了一个python2.7的源码,重新编译安装一下。 ./configure —prefix=/usr/local/ –enable-shared CFLAGS=-fPIC make make install

  3. ImportError: libpython2.7.so.1.0: cannot open shared object file: No such file or directory

    库路径问题,要么配置LD_LIBRARY_PATH,要么修改ld.so.conf然后ldconfig

  4. / not found.

    httpd.conf配置: WSGIScriptAlias / /var/www/html/mysite/mysite/django.wsgi Order allow,deny Allow from all

  5. log/errro_log中 No module named mysite.settings。

    wsgi配置: import sys sys.path.append(“/var/www/html/mysite/”)

  6. Cannot load /etc/httpd/modules/mod_ldap.rso into server: /etc/httpd/modules/mod_ldap.so: undefined symbol: apr_ldap_ssl_init

    大概是说httpd编译的apr版本和系统的版本不一致,查看httpd -V 显示:

    Server loaded:  APR 1.4.6, APR-Util 1.5.2
    Compiled using: APR 1.2.7, APR-Util 1.2.7
    

    尝试降级apr:

    yum downgrade apr-util
    

    或者指到别的apr版本上去,修改环境变量:

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64 
    

    我不知道httpd是否会去加载当前环境变量,所以顺便删了/etc/ld.so.conf里面的两行

    /usr/local/apr/lib
    /usr/local/apr-util/lib
    然后ldconfig   
    

    让apr走系统的版本。

Bibliography:

[1] Linux下安装Apache并以mod_wsgi方式部署django站点, http://www.cnblogs.com/fengzheng/p/3619406.html

gtest鉴于google自己的风格,不提供make install,直接make完之后配置路径链接就行,在linux上这样是ok的:

g++  -I$GTEST_DIR/include -I$GTEST_DIR -c $GTEST_DIR/src/gtest-all.cc
g++ -I$GTEST_DIR/include -I$GTEST_DIR -c $GTEST_DIR/src/gtest_main.cc

ar -rv libgtest.a gtest-all.o
ar -rv libgtest_main.a gtest_main.o

c++ -g -Wall -Wextra -pthread  -isystem $GTEST_DIR/include  -c -o RemoveElement.o RemoveElement.cpp
c++ -g -Wall -Wextra -pthread  -isystem -isystem $GTEST_DIR/include/include -c -o SameTree.o SameTree.cpp

在mac下这里会报错:architecture x86_64。关键我一直理解gest_main是包含main函数的gtest,gtest-all是不包含的,知道发现官方的makefile执行的时候是这样的

ar rv gtest_main.a gtest-all.o gtest_main.o   

用这里的gtest_main.a做libgtest_main.a就行了。不理解为什么在mac上单独打包一个gtest_main.o为什么不行。论坛貌似有人贴了一个patch,不看了,回家,碎觉。

主要是在Makefile中看到了这种字符($@),不理解含义,查阅了一下,跟shell中意义不一样:

$@     -is the name of the target currently being processed.
$<     -is the name of the first dependency.

顺便提下shell下的

$#    Stores the number of command-line arguments that were passed to the shell program.
$?    Stores the exit value of the last command that was executed.
$0    Stores the first word of the entered command (the name of the shell program).
$*    Stores all the arguments that were entered on thecommand line ($1 $2 ...).
"$@"  Stores all the arguments that were entered on the command line, individually quoted ("$1" "$2" ...).

总结一下混乱的GCC命令行参数,帮助写Makefile:

  1. 编译阶段

    1. 预编译E->生成汇编S(ccl)–>生成机器码c(as)–>链接生成目标程序(ld)
  2. 输出类型:

    1. -E 只执行到预编译
    2. -S 只执行到汇编阶段。生成汇编代码。
    3. -c 只执行到编译。输出目标文件。
    4. 空。生成链接目标代码。
    5. -o 指定输出文件名。
  3. 输入类型:

    1. 每个阶段可以接受之前阶段的中间结果(可跨越)。比如:

       gcc -E hello.c -o hello.i
       gcc -S hello.i -o hello.s
       顺序可以换:
       gcc -c -o hello.o hello.c
      
  4. 优化调试相关

    1. -g 生成调试信息
    2. -s 去掉调试和符号信息
    3. -O[1|2|3..] 编译优化
    4. -W[all] 开启额外警告
  5. 链接相关:

    1. -l, 指定所使用到的函数库
    2. -L, 指定函数库所在的文件夹。
    3. -I, 指定头文件所在的文件夹

Bibliography:

[1] Linux平台gcc和动态共享库的基础知识, http://robbinfan.com/blog/9/gcc-linker-basic-usage

While refactoring a project, I met with a situation that one configuration extends another configuration, like this:

ConfigA = {"a":xx, "b":xx}
ConfigB extends ConfigA + {"a":yy, c:"yy"}

Code before refactor treats configA and configB separately. So after a few code iterations you will find configA has something same with configB. So I change it to this:

configA = {"a":xx, "b":xx}
configB = dict(configA.items() + {"a":yy, c:"yy"}}

While this treats configA and configB evenly, meanwhile, it costs extra replication. A better way is like this:

configA = {"a":xx, "b":xx}
configB = dict(configA, **{"a":yy, c:"yy"}})

The order of configA and configB’s own elements is immutable, which means if configA and configB has a same element, use configB as result.

Actually I just want to memorize the usage of STL function random_shuffle. It takes two or threes arguments, the begin iterator, end iterator and a generator. What makes it interesting is the optional third parameter. Random_shuffle will pass the index to generator and takes the output as index to place current element while shuffling. Here is an example:

#include <iostream>
#include <algorithm>
#include <vector>
#include <ctime>
#include <cstdlib>

using namespace std;
const int POKER_NUM = 52; //52 pocker cards
void print_poker(int PokerNum)
{
    cout << PokerNum << " ";
}

class MyRand
{
public:
    int operator()(int index)
    {
        return rand() % PockerNum;
    }
};

int main()
{
    srand( (unsigned)time(NULL) ); //rand seed
    vector<int> poker;
    //initialize
    for (int num = 0; num < POKER_NUM; ++num)
    {
        poker.push_back(num+1);
    }

    //with default random_shuffle
    random_shuffle(poker.begin(), poker.end());
    for_each(poker.begin(), poker.end(), print_poker);
    cout << endl;

    //use custom random_shuffle
    random_shuffle(poker.begin(), poker.end(), MyRand());
    copy(poker.begin(), poker.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
}

I copy it from here. While I found a mistake in it. The result isn’t really random. The pseudo-code of above is :

for i in 0..n
    exchange a[i] and a[random(0..n)]

We assume a method can generate a sequence(a[0]..[n]) randomly, which means each sequence appears with the probability 1/n!. Take certain sequence a[0’]…a[n’] as an example: a[0’] appears with the probability 1/n, so a[1’] should appear with the probability 1/(n-1), etc. The algorithm above find a[1’] in the whole candidates, makes the probability 1/n actually. The right algorithm is like this:

for i in 0..n
    exchange a[i] and a[random(i..n)]

With a little change in the code:

class MyRand
{
public:
    int operator()(int index)
    {
        return rand() % (PockerNum - index) + index;
    }
};

Bibliography:

[1] random_shuffle算法小例子, http://blog.csdn.net/aheroofeast/article/details/3907192

[2] “Algorithms, http://www.amazon.cn/%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA-Thomas-H-Cormen/dp/B00AK7BYJY

2015.1.12,生日,去做了第一轮刮治的第一次治疗。痛不欲生啊。

11月的时候查出来牙周有问题,其实很早就觉得不好了,洗牙之前没去看。洗牙的时候拍了牙片,槽骨吸收的很厉害了。中间又拖了两个月,一个是忙,一个是没挂上号,终于上周去北大口腔挂了号。医生说很严重,侵袭性牙周炎,牙周袋太深,可能还是得手术。

今天第一次刮治。感慨牙这个东西,不意识到的时候不会觉得他的重要,上周探完牙周袋深度就疼了一个周,这次更是痛不欲生的感觉,打了麻药还是这样。而且奇怪的是手刮并不怎么疼,疼的还是超声洗牙石的部分。唯一的安慰是大夫态度都不错。牙科的大夫mm居多,虽然带着口罩都看不清楚长相…

以前还是不重视啊。家庭上也整体不重视。中国还是有很多落后的地方,理念上这么多年都没有更新过来。联想到公务员热和中国父母普遍的求稳定,觉得理念真是落后太多了。至于过年各种嘘寒问暖的亲戚…哎,你们没有隐私这个观念么…还好我家人父母不太执着这些事情,就是说说算了…或者我压根没当真过..

总的来说。长大了,要慢慢消除家庭的影响。有独立的思考了,就要慢慢消除教育的影响。离开了熟悉的环境,就要慢慢消除文化的影响。保持一个open的心态,不断质疑以前形成的思维定势,才能走出去,走的远。


此贴持续更新,毕竟还有四到五轮的刮治,每轮又要分多次,之后如果做牙周手术,又有得受了。立贴为记录吧。

今天才注意到北大口腔的字还是老江题的。联想到今天疼爽了的经历,真是excited啊


第二次刮治,右上右下。倒是比第一次疼痛减轻多了,不过上次刮治之后都是臼齿吃饭,这下吃饭比较成问题。另外麻药的持久感好强,感觉右半边脸好像不存在一样。

下周继续。第一轮三次完成。大夫比较辛苦。


第一轮第三次结束,医生说好多了,至少肿退下去了。买了牙缝刷每天饭后刷,还是能刷出一些刷牙刷不到的东西。下次检查年后了,抽空去拔个智齿。


今天想去拔智齿。经历了这样的流程:感冒不能拔->周日好的差不多了->早晨没起来->7点半出发去北大口腔第三门诊->被告知外科不现场挂号只能预约->北医三院,屏幕直接显示没号->海淀医院,被告知没号->中关村医院,成功挂号,拔牙医生只有周一到周六在->回,over。

拜GFW所赐,连tm boot2docker都连接不上了。好在有shadowsocks的服务,可以转成http proxy给命令行使用。

首先安装privoxy。Linux下直接apt-get install privoxy,然后编辑配置文件(etc/privoxy/config):

forward-socks5   /               127.0.0.1:1080 .
listen-address  localhost:8118
#local network do not use proxy
forward         192.168.*.*/     .
forward            10.*.*.*/     .
forward           127.*.*.*/     .

基本上上这两项就可以了。之后在shell配置下代理,详见参考文献2

export http_proxy='http://127.0.0.1:8118'
export https_proxy='http://127.0.0.1:8118'

最后chkconfig设置下开机启动。Mac下略微麻烦一些。主要是配置开机启动。详见参考文献3。至于Mac下的Shadowsocks,还是ShadowsocksX比较方便,跟Linux下一样,都是会在1080启动监听。

Bibliography:

[1] Privoxy, http://www.privoxy.org/

[2] 通过搭建代理来共享网络, http://cxh.me/2015/01/11/linux-proxy-setup/

[3] 使用Privoxy做智能代理切换, http://blog.devtang.com/blog/2012/12/08/use-privoxy/

遇到如下一个问题,java中使用复杂类型做Hashkey的时候,构造另一个值相同的对象作为key无法获取map的value。原因其实是java的==判断的依据是两个引用是否指向了同一个对象。实际调用了hashCode函数。内置对象的逻辑相等比较需要使用equals,比如String。而对于非内置对象,equals也同样调用了hashCode来判断相等。

所以对于需要逻辑相等判断的对象,需要override两个函数,比如如下一个getkey的类定义了如何从Map中根据path和type得到一个唯一的对象:

class ZkEventKey {
    EventType type = null;
    String path = null;

    ZkEventKey(EventType type, String path) {
        super();
        this.type = type;
        this.path = path;
    }

    EventType getType() {
        return type;
    }

    String getPath() {
        return path;
    }

    @Override
    public String toString() {
        return "ZkEventKey [type=" + type + ", path=" + path + "]";
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj){
            return true;
        }else if (obj == null){
            return false;
        }
        if (getClass() != obj.getClass()){
            return false;
        }
        ZkEventKey other = (ZkEventKey)obj;
        if(type == other.type && path.equals(other.path)){
            return true;
        }
        return false;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + type.hashCode(); 
        result = prime * result + path.hashCode(); 
        return result;
    }
}

hashCode取31是一个统计的结论,在接近2x的质数下,散列冲突最小。没有看到过证明。

有时候需要在eclipse中同时运行客户端程序和服务器程序,开始都是一个在eclipse里面运行,另一个在命令行单独启动,未免不方便。后来发现,其实可以直接在eclipse中运行两次。调试视图会有两个显示,同时新建一个console窗口,关联另一个实例的显示就可以同时监视两个程序的输出了。

协变返回类型(Convariant Return Type)是指override的函数,返回值有继承关系(子类函数返回类型是父类返回类型的子类)。例子如下:

之前没注意过这里:

java继承的时候只会隐藏父类同名同类型的函数。C++直接隐藏了同名的所有函数,如下:

public class BaseClass {
    public void Print(String str){
        System.out.println("String" + str);
    }
    public void Print(int num){
        System.out.println(num);
    }
}
public class TestDerived extends BaseClass {
    public void Print(String str) {
        System.out.println("String" + str);
    }
    public static void main(String[] args) {
        new TestDerived().Print(121);
    }
}

输出结果是121

而同样的实现C++中直接会找不到父类的函数。

拜GFW所赐,连tm boot2docker都连接不上了。而且最近红杏抽风,遂决定买shadowsocks服务翻墙。服务直接在官网购买,90一年,比红杏略便宜一点,主要还是可控性比较大,因为是socks5的代理。

这里购买服务,一年99,这个优惠码可以再打一点折imouto985。之后进入后台可以看到分配给自己的密码,服务器主要是日本,美国和新加坡的,实测貌似日本的响应更快一点。

mac下下载了客户端直接打开配置好地址就能用,linux下需要自己配置代理。

首先下载安装node.js

wget http://nodejs.org/dist/v0.10.35/node-v0.10.35.tar.gz
tar zxvf node-v0.10.35.tar.gz 
cd node-v0.10.35
./configure && make 
sudo make install

然后安装npm和shadowsocks

sudo apt-get install npm
sudo apt-get install shadowsocks

apt-get安装的nodejs好像有问题,所以用源码安装。编辑配置文件,默认是/usr/local/lib/node_modules/shadowsocks/config.json,启动之后就可以连上服务器了。

之后需要配置proxy。以chrome为例,如果之前配置过goagent的话,基本配置一样。不过proxy switch sharp终于升级到了proxy switch omega了。需要注意的是shadowsocks是socks代理,选择的时候不要选择http。gfwlist 可用如下:

https://autoproxy-gfwlist.googlecode.com/svn/trunk/gfwlist.txt

之后就可以翻墙了。最后说一句:Fxxk GFW,祝病魔早日战胜方校长,所有参与GFW的人都将钉在历史的耻辱柱上

首先这不是java编译器的问题,就是写代码的时候大意了。

有这样一个函数

int parse(String msg, Message out);

解析一个String,返回一个结构体。这么做的目的主要是避开try catch的性能问题,通过返回码来处理异常。这里就很容易出现这样的用法了:

Message msg = new Message();
for (xxxx){
    if (0 == parse(str, msg))

}

当时觉得还挺好,复用了一个对象。实际明显有问题的,这个对象的生命周期不见得只在for循环内部,一旦引用被传递出去,就会有悬挂(java里是不是不这么叫)的问题。多个引用指向了一个对象,计算结果是不可预测的。

主要问题是java里面默认都是传引用的,所以要时刻保持对gc机制的警惕。或者直接实现clone接口。

遇到这样一个问题:有一堆数据,需要统计相同key下相同的column的重复出现次数,实际上就是数据库里面的group by功能,但是建表导入然后计算未免麻烦,何况数据是临时数据,导入计算完毕之后就不需要了。这里用shell下的一些命令来完成。

数据格式

user            tag_id  type        time
AAAAAAAAAAA     tag1    Click       2015:13:37:16
AAAAAAAAAAA     tag1    Click       2015:13:37:16
AAAAAAAAAAA     tag2    Click       2015:13:37:16
BBBBBBBBBBB     tag2    Click       2015:13:37:16
BBBBBBBBBBB     tag2    Click       2015:13:37:16
BBBBBBBBBBB     tag2    EXPOSURE    2015:13:37:16

目的:

统计同一个用户下,同一个tag的点击次数:

实现如下:

  1. 排序

    首先对数据进行排序。这是最基本的,见上篇文章

    sort -k 1 
    
  2. 过滤不需要的行和列。

    awk '{print $1, $2, $3}' |grep "Click" 
    
  3. 这时候出现了一些重复列了,这也就是我们要做group by的数据。

    uniq -c | awk {'print $2, $3, $1'} 
    

后面awk只是调了一下位置。合并起来就是:

sort -k 1  test.txt|awk '{print $1, $2, $3}' |grep "Click"|uniq -c | awk {'print $2, $3, $1'} 

输出结果:

AAAAAAAAAAA tag1 2
AAAAAAAAAAA tag2 1
BBBBBBBBBBB tag2 2

遇到这样一个需求,希望按照第二列排序,第二列相同的情况下按照第一列排序,数据如下:

b   2   c
c   2   b
a   1   b

习惯性的用:

sort -k 2 -k 1 input.txt

输出结果是:

a   1   b
c   2   b
b   2   c

可以看到实际上先按照第二列排序,第二列相同按照第三列排序了。问题在于sort -k默认是按照顺序排序到末尾的。如果要打破默认,需要指定从哪个列到哪个列。

sort -k 2,2 -k 1 input.txt

换个角度说,sort -k 1 -k 2 的效果跟 sort -k 1 是一样的。所以最好还是让数据按照排序列生成,这样看起来也最直观。

HTML中我们可以在form中这样写复选框:

<form action="demo_form.asp">
  <input type="checkbox" name="vehicle" value="Bike"> I have a bike<br>
  <input type="checkbox" name="vehicle" value="Car" checked> I have a car<br>
  <input type="submit" value="Submit">
</form>

但是作为服务端处理起来未免不变,尤其是checkbox list是自动生成的时候。此时可以用group方式把form value组合起来。如下:

{\% for item in items \%}
    <td><input type="checkbox" name="selected_push[]" value=""></td>
{\% endfor \%}

服务端从命令行可以看到收到的post里面是有’selected_push[]‘变量的。但是直接get的结果只有一个。查阅stackoverflow发现RequestContext有单独的getlist函数来处理。果然还是跟PHP不一样啊。

众所周知Python的内码编码是Unicode,所有输入的编码都需要转换成unicode然后转出成为其他编码。Python2中存在unicode对象和str对象两种,在中文处理的时候很容易出问题,而Python3直接全部统一了编码到unicode。

举一个例子说明编码的转换,首先我们的环境是utf-8

LANG=zh_CN.UTF-8
LANGUAGE=zh_CN:zh
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_PAPER="zh_CN.UTF-8"
LC_NAME="zh_CN.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL=zh_CN.UTF-8

然后测试一个从环境的输入和写回到环境。

文件编码gbk:
print '中文'
print u'中文'
输出
    ����
    中文

文件编码utf-8
print '中文'
print u'中文'

输出
    中文
    中文

说明print输出的时候按照default encoding进行了编码。所以只有gbk的编码乱码了。同样对输入的判断,环境如果是utf8,输出不变的话,不会有乱码。但是如果从文件里读取了字符串或者代码里有硬编码字符,就需要考虑编码了。另外,unicode和str相加会有编码问题。比如:

文件编码gbk:    
value = raw_input()
print value + "中文"
输入
    中文
输出
    中文����

value = raw_input()
print value + u"中文"
输入
    en
输出
    en中文
输入
    中文
输出
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

str+str输出肯定是str,所以需要适配环境的编码,第一个乱码可以理解。而str+unicode的时候,str会被按default encoding解码。utf8无法按照python default encoding ascii解码。utf8文件编码下的情况类似。

知乎日报是中国人民喜闻乐见的资讯类应用,Pocket是深受世界人民喜爱的阅读工具。鉴于反碎片化阅读的个人习惯,决定把散落在各个地方的有价值咨询集中到一个应用里面,于是有了如下的工具。

首先我们要parse知乎日报的URL。按照官方的说法每天三次投放,那抓一次就行了。直接用了sed工具

curl -s http://daily.zhihu.com | sed 's/<a href="\(http:\/\/daily.zhihu.com\/story[^"]*\)"/\n\1\n/g' |grep 'http://daily.zhihu.com/story'

“我妈说生活不是眼前的苟且,生活有诗和远方。我 和我妹妹深受这教育。谁要觉得你眼前这点儿苟且就是你的人生,那你这一生就完了。生活就是适合远方,能走多远走多远;走不远,一分钱没有,那么就读诗,诗 就是你坐在这,它就是远方。”

关于房子,我跟大多数人概念不一样。我从小住在清华校园里,家是那种二层的小楼,外表看起来很普通,面积也不是特大,但是特别安静。

这地儿都没动过,也没装修之说,从我生下来就是这样红色的,很老很旧。但我在那儿真觉得挺好,有一个家,但我在那儿真觉得挺好,有一个家,不仅仅是睡觉的 地方,我自己也不知道这房子多少年了,我们也在感慨:后边的院子多好啊,出门就是操场、游泳馆,还有漂亮的女生,白发的先生;四周的邻居,随便踹开一家的 门,里面住的都是中国顶级的大知识分子,进去聊会儿天怎么都长知识,梁思成林徽因就住我前面的院子。小时候有什么问题家里老人就写一张字条,说这问题你问 谁谁谁。我找到人家家里,打开字条一看,哦,你是那谁家的孩子,那你讲吧,都是中国头把交椅啊。这才是住处真正的意义吧,它让你透气,而不是豪华的景观、 户型和装修什么的。

有时候需要手动构造一个Django model对象并保存,遇到如下的情况:

model定义如下:
class AuthHistory(models.Model):
user_name = models.CharField(max_length=100, default=None)
item_id = models.CharField(max_length=100)
datetime = models.DateTimeField()
url = models.CharField(max_length=1000)
title = models.CharField(max_length=1000)
operation = models.CharField(max_length=100, default=None)

构造对象如下:
history = AuthHistory("cxh", tid, datetime.datetime.now(), item['url'], item['title'], operation)

报错:django title invalid literal for int() with base 10:cxh,明显是把第一个字段赋给自增长id了,因为Django会给没有主键的表直接加上id字段作为主键。

手动指定域当然是可以的:

history = AuthHistory( user_name="cxh", item_id=tid, datetime=datetime.datetime.now(), url=item['url'], title=item['title'], operation=operation)

但是未免很麻烦。传值肯定不合理,毕竟id是数据库记录的。试了一下,给id域直接传NULL就行了。

history = AuthHistory(None, "cxh", tid, datetime.datetime.now(), item['url'], item['title'], operation)

Eclipse中需要执行一个java程序的之后只需要在入口类Run就行,但是有时候需要同时开两个程序,尤其对C/S模式的应用来说。针对这种情况,可以分如下三种方式启动另一个程序:

  1. java -cp 指定的类。shell(或者ZSH才有)下貌似是会有提示如下:

    以上方式至少需要保证用到的jar都在classpath中。

  2. 从eclipse中copy执行命令。去调试页面,查看刚才执行的command的属性页面。会看到如下界面,copy命令到shell中执行即可。

  3. maven execute。 命令类似:

    mvn exec:java -Dexec.mainClass=boot.BootStrap
    

    注意是第二个exec后是点,不是:,另外如果有多模块,在root project下需要加module:

    mvn exec:java -pl xxx -Dexec.mainClass=boot.BootStrap 
    

遇到这样一个问题:Django中有字段是根据位来存储信息的,并且不是对应Model数据库中的字段,BitField使用起来比较不太适合。这样就得在模板中根据位来显示不同的内容。查Django并试验,好像位操作不能直接写在if操作符中,同时django也不支持在模板直接调用函数。一个合理的选择是建立自定义的Filter。详见参考文献。基本代码如下:

配置:
mSohuConf={
    "A_mask" : 0x04,
    "B_mask" : 0x02,
    "C_mask" : 0x01,
}

Filter代码:
from django import template
from django.utils.safestring import mark_safe
from .. import config
register = template.Library()
mask_html = (
    (config.mSohuConf['A_mask'], '<span class="label label-danger">A</span>'),
    (config.mSohuConf['B_mask'], '<span class="label label-warning">B</span>'),
    (config.mSohuConf['C_mask'], '<span class="label label-info">C</span>'),
)
default_html = '<span class="label label-default">D</span>'
@register.filter()
def news_tag(value):
    output = default_html
    for mask, html in mask_html:
        if value & mask:
            output += html +'\n'
    return mark_safe(output)

模板:
{\% load news_tag \%}
<td></td>

晚上去看了《一代宗师》3D。3D效果比较一般,基本是字幕3D。但是感觉依然是王家卫那种感觉。故事讲的更清楚了,但是也就少了很多想象的空间。

突然觉得嘉华还不错,会员生日可以免费观影一场,还有爆米花套餐。最近心情抑郁,突然收到这个gift,觉得幸福感好高。就像昨天收到快递里面有个卖家送的幸运豆就高兴了好久。不是低潮的时候往往忽视这些细小的幸福。

最近总在回想人生走过的路,觉得多走了好多弯路。说人生无悔,都是赌气的话。人生若是真的无悔,那该多无趣啊。宫二的这句话,确实勾起了很多感触。27岁的生日,新的开始。全新的自己,打点行装,坚定的走下去。

要27了。

突然有很多感慨,自从不怎写字之后也不怎么愿意表达了。习惯了工作占据大部分时间。好在工作也不见得完全是工作,还是有兴趣的成分在里面,重合度就看心情了。但是工作多了就有种麻木的感觉,觉得似乎不是我想要的人生。

时代发展好快。这似乎已经不是个小资的时代。从学生时代走过来,毕业的热闹一过去,感觉立马进入了快车道。这一年马不停蹄,一身风尘一身疲惫。去阿里就不是什么明智的选择,当时可能是头脑一热吧,也可能是觉得很不屑研究生跟着导师做的东西,非要找一个技术上(看起来)高深莫测的地方。一年下来觉得开始是有兴趣,后来感觉是个挑战,最后感觉就是负担的。跳槽之后心境平和多了,现在至少已经不恨或者不黑什么了,这点还是挺感激张老板和我们组的。人嘛,到了奔三的年纪,还是要客观一些。

最近过得有些抑郁。以前无论什么事情都没觉得怎么样,牙这个事情真是无力吐槽。明天去定治疗方案。所以牙好的亲们,这是一笔财富啊,想吃点好的就吃吧,不要在乎钱。

晚上在搜狐的楼上,看着夕阳晚霞雾霾,觉得真是感慨。从毕业过来快十年了,似乎有所收获,又似乎一事无成。被卷在时代的洪流里面,想抓住什么又没有方向。不过也正常。鸡汤的东西读多了,就不容易被忽悠了,这个时代哪有那么多高大上的故事,每一点成长都是在无比纠结里面过来的。

不过好在还年轻,心态还年轻。慢慢终于可以把自己放到一个独立的位置上,觉得如此就自由了很多。想走什么路,不用在瞻前顾后。总想着回来,就走不远哪。

好没有逻辑。

不过也不需要逻辑了。该治牙治牙,该工作工作,该生活生活。本来就没有什么逻辑。趁年轻,想做什么就去做。

嗯。

偶然发现服务器上的python是2.4的,好多语法都不支持。遂决定升级。

首先yum升级是可以升级到2.6的:

yum install python26
yum install python26-devel
yum install python26-setuptools
ln -s /usr/bin/python2.6 /usr/bin/python

升级之后发现yum不能用了。yum应该是跟python版本绑定了,于是把yum头部改成:

#!/bin/python2.4

之后发现2.6还是不行…我是用了多新的语法啊…就是几个dict comprehension。于是决定升级到2.7。源里面没有,只能手动。

#wget http://python.org/ftp/python/2.7.3/Python-2.7.3.tar.bz2  
#tar -jxvf Python-2.7.3.tar.bz2
#cd Python-2.7.3  
#./configure  
#make all             
#make install
#ln -s /usr/local/bin/python2.7 /usr/bin/python  

安装setup-tools

wget https://pypi.python.org/packages/source/s/setuptools/setuptools-11.3.1.zip --no-check-certificate
unzip setuptools-11.3.1.zip
cd setuptools-11.3.1
python setup.py install

yum不用动了。

遇到这样一个问题,开发机只有一台能上外网,其他的机器上手动更新依赖包简直是要死的感觉。尝试了如下几种方式:

  1. . vpn
    1. pptp
    2. openvpn
  2. . ssh反向代理(其实不是干这个事情的貌似)
  3. . proxy

开始一直不想用proxy,毕竟需要为yum什么的单独配置,不是所有的程序都会去读shell的http_proxy配置。但是vpn配置搞了一天都不成功。openvpn能连接,但是不能共享网络,大概是路由配错了,pptp linux下直接链接不上,可能是只用了chap的握手?反正没成功。最后还是配了proxy,配完才觉得proxy简单易行啊,大部分问题能解决,出现了特别的需求就单独为其设置代理好了。问题不大。

tinyproxy的配置如下:

yum install tinyproxy

# vi /etc/tinyproxy/tinyproxy.conf
  Allow 192.168.1.0/24 # 限制可以使用Proxy的来源网段
ConnectPort 443 

service tinyproxy start

shell配置:
export http_proxy='xxx:8888'
export https_proxy='xxx:8888'

yum配置:
vi /etc/yum.conf
  proxy=http://xxxx:8888

maven配置:
 <proxies>
 <proxy>
    <id>example-proxy</id>
    <active>true</active>
    <protocol>http</protocol>
    <host>proxy.example.com</host>
    <port>8080</port>
    <username>proxyuser</username>
    <password>somepassword</password>
    <nonProxyHosts>www.google.com|*.example.com</nonProxyHosts>
  </proxy>
</proxies>

git配置:
[http]
  proxy =xxxx:xx

配置难度真不是一个数量级的,可见有时候能满足大部分情况,就是最好的解决方案了。

补充:easy_install和pip是默认读取http_proxy的,但是一直不能连接。尝试了很久之后发现是sudo的问题,sudo环境没有执行.bashrc,所以root的http_proxy和当前用户的http_proxy都没有生效。su到root下就可以了。

在octopress里面添加一个分类的时候,经常会遇到分类跟导航页面没有同步更新的情况,即加了一个分类,生成了文章,文章被生成在指定的路径下了,但是首页导航栏的分类没有跟着更新。针对这种情况,修改了一下Rakefile,把分类做成了配置,添加分类的时候可以直接修改一下分类信息,然后rake gen就可以生成对应的导航栏html代码。

修改如下(我以前增加过交互的提示选择分类的功能),需要解释的有如下几点:

  1. “——”是分割线,-的数量不能都一样,毕竟是作为map的key的。
  2. 分类做成map是因为category生成的时候名字自动做成了英文/拼音/中横线的形式…我没搞明白怎么弄的。所以自己手动填一下好了。以后有空想做成手动指定的。
  3. system sublime那个是自动打开sublime写博客。我不习惯用vim写中文的博客…

首先推荐google的编码规范,其次,关于class member ordering的问题,google的解释是:

The ordering of the members of a class can have a great effect on learnability, but there is no single correct recipe for how to do it. Different classes may order their members differently.

What is important is that each class order its members in some logical order, which its maintainer could explain if asked. For example, new methods are not just habitually added to the end of the class, as that would yield "chronological by date added" ordering, which is not a logical ordering.

道理是对的,但是不好执行啊。看了看JDK的顺序,觉得这里说的还是能达成共识的。

  1. Class (static) variables: First the public class variables, then the protected, and then the private.
  2. Instance variables: First public, then protected, and then private.
  3. Constructors
  4. Methods: These methods should be grouped by functionality rather than by scope or accessibility. For example, a private class method can be in between two public instance methods. The goal is to make reading and understanding the code easier.

参考文献:

[1] Google Java Style, https://google-styleguide.googlecode.com/svn/trunk/javaguide.html

[2] Are there any Java method ordering conventions?, http://stackoverflow.com/questions/4668218/are-there-any-java-method-ordering-conventions

起源是这样一道题目:

于是想到通过word dict来算一下:

先去下载了中文词库:

git clone git@github.com:ling0322/webdict.git 

然后去掉词频信息:

awk  '{ if (length($1)==2) print $1}' webdict_with_freq.txt >webdict.txt

先按照出现位置来正则过滤候选集,并且去掉大/日/风/思四个字:

grep '^大.*' webdict.txt| sed 's/大//g' >da.txt
grep '^日.*' webdict.txt| sed 's/日//g' >ri.txt
grep '.*风$' webdict.txt| sed 's/风//g' >feng.txt
grep '.*思$' webdict.txt| sed 's/思//g' >si.txt  

之后的事情就很有意思了,每次join两个文件,因为大/日/风/思四个字是没有交集的,所以结果就是要求的字:

comm -12 <(sort da.txt|uniq ) <(sort ri.txt|uniq ) >da_ri.txt
comm -12 <(sort feng.txt|uniq ) <(sort da_ri.txt|uniq ) >da_ri_feng.txt
comm -12 <(sort si.txt|uniq ) <(sort da_ri_feng.txt|uniq ) >da_ri_feng_si.txt

最后的凶手答案只有一个:

谢谢观看~。

参考文献:

[1] LINUX Shell 下求两个文件交集和差集的办法, http://blog.csdn.net/autofei/article/details/6579320