2012-04-02 时机稍纵即逝,有时候努力了很多,不如时机把握的好。犹豫是犹豫者的墓志铭,有时候考虑了太多,反而会失去很多。也许一开始就能知道自己想要什么,也许就……

Google各种服务的IPv6 Hosts地址

2012年4月26日  571 views 1 条评论

之前本博客写过一篇可以通过修改本地Hosts文件来访问Google +的文章,陆陆续续获得了1w+的点击量。不过后来因为没有一直更新IP,貌似现在那些IP都已经不好用了,所以今天我又去网上淘了一套Google服务IPv6的Host地址。

刚刚试了一下,效果非常理想,G+、Docs、Drive、Youtube都无障碍访问。为了防止以后找不到这些数据了,现将Host内容附录于下。在此感谢文档原作者Versus Clyne。

原文档地址:https://docs.google.com/Doc?docid=0ARhAbsvps1PlZGZrZG14bnRfNjFkOWNrOWZmcQ

本站镜像页面(防止docs访问不了):http://test.codeup.org/Google-hosts-IPv6.htm

Hosts文件

鉴于拷贝下文比较费事,我将我本地的Host文件附在这里,大家可以直接下载替换。

hosts文件存放位置:

Windows:%SystemRoot%\system32\drivers\etc\          例如C:\Windows\system32\drivers\etc

Linux:/etc

  hosts (301.5 KiB, 190 hits)

Hosts文件内容

#Google和各种网站的IPv6服务hosts

#利用IPv6技术翻墙,保证Google服务可用,校园网用户使用IPv6应该不收取上网费用(至少我们学校如此)

#最下方有各种网站的IPv6 hosts列表

#欢迎转载,请注明来源,以便网友及时更新,谢谢

#本文的发布地址:http://docs.google.com/View?id=dfkdmxnt_61d9ck9ffq

#本文的共享链接:http://docs.google.com/Doc?docid=0ARhAbsvps1PlZGZrZG14bnRfNjFkOWNrOWZmcQ

#有新的Google地址需要添加?请在这里提交或在线编辑,帮助完善此列表,谢谢~

#欢迎穿越传阅

# 5/7 v*.lscache*.l.google.com IP 地址变更(youtube 视频储存服务器除外,谁有日本 yt 的 IP 告诉我- -),由日本东京改为澳洲悉尼,速度我测试变快了
# 5/10 更新 v*.lscache*.c.google.com 感谢 JL Hwung 的提供
# 7/12 《电脑报》你威武!(2010年7月12日G14版第四列)
# 您正在查看的版本更新于 2012-04-25;详细更新日志请见 http://code.google.com/p/ipv6-hosts/source/list (RSS 链接

#顺便提供能够解析出 Google IPv6 地址的 DNS 服务器 (其 ISP 已加入 Google over IPv6 计划),这样不需要修改 hosts,只需改变本机 DNS 设置就可以自动解析出 IPv6 地址,由HE提供:2001:470:20::2 ordns.he.net (ipv6) 74.82.42.42 (ipv4,在内地可能会遭污染,可以和本 hosts 文件配合使用 by www.lostriver.net)

#最近好像有0.5不停的在举报本文有不适宜内容(滥用行为),然后接连收到10余封google发来的本文审核通过可以发表的邮件,建议大家备份一下本文,免得某些人把本文404,reset什么的之类- -

#用文本编辑器打开hosts文件,将以下内容复制进去,保存即可(hosts 文件没有后缀)

#Windows 用户可以以管理员身份直接运行 notepad “%SystemRoot%\system32\drivers\etc\hosts” 进行编辑

#Linux 用户在终端中执行 sudo gedit /etc/hosts 即可开始编辑

#关闭某个IPv6的转发请在那一行的最前面添加#号,启用请去除最前面#号,每行中间的#号是为了区分地址和注释,不用理睬- -

阅读全文…

【细节决定成败】switch篇

2012年4月15日  113 views 没有评论

前几天在给埃及局点提供补丁时犯了个低级错误,在switch的一个case中忘了写break语句,造成功能在大部分情况下都是正常的,只有个别场景出现了很诡异的问题,通过函数入参日志还看不出任何问题。

由于switch的各case之间肯定是非常相似的,所以这种问题造成的后果不一定能够立即体现出来,因为执行了下一个case中的逻辑后返回的结果很有可能也是正确的。

这种错误是非常低级的,低级到我都不太好意思写在这里了。但是这种错误又感觉很容易发生,这已经不是我第一次犯这种错误了。之前在做PMS插件时也发生过一次,那次也是功能在部分情况下很正常,只在一种很特殊的场景下会有问题。上次也是定位了很久才发现是个如此低级的问题。已经在同一个地方跌倒了两次,那么绝对不能再有第三次……

今天稍微总结了一下犯这种错误的原因,主要分成两个场景:

1、新写一个switch语句,在写完一个case后直接开始逻辑处理,如果这个case下的逻辑比较复杂,很有可能在写完逻辑后就忘了写break语句了。

2、修改原有的switch语句,有时候修改某个case语句,直接把此case下的所有语句都干掉重写,这时候很容易把break语句一起干掉了。然后在写新的逻辑时就很有可能只关注新的逻辑而遗漏了这个break语句。

之前犯错的两次分别就是以上两种场景,说白了就是只关注case下的逻辑而忽略了switch语句的本身。现在我能想到的预防措施就是要向括号配对一样检查case与break的配对情况,每写一个case语句后首先把break加上。

与此类似的还有if else,有时候也会存在if下逻辑复杂,写完后忘记else分支的情况。为预防此种情况,在写完if语句后必须将else语句先写下来,哪怕else下是个空语句。

分类: 心得笔记 标签: , , ,

自省,无关技术

2012年4月3日  130 views 没有评论

四月第一篇,无关技术。

就像刚刚更新的心情一样, 时机稍纵即逝,有时候努力了很多,不如时机把握的好。犹豫是犹豫者的墓志铭,有时候考虑了太多,反而会失去更多。也许一开始就能知道自己想要什么,也许就……

今天有些莫名的不爽,也许是期望无法达到的失落,也许是对自己的瞻前顾后犹犹豫豫的失望,也许仅仅是阴天下雨造成的不爽,也许it is nothing…

人需要反思,需要自省,需要改变自己。我的记忆中,旁人对我童年的评价,大多是老实、稳重、内向,还有那么一点点羞涩。曾经的我觉得这样没有什么,但后来发现内向的人并不吃香,所以现在我渴望表现自己,我开始变得话多,好撩人,变得开朗外向起来。当然,这是我自己的感觉,至少,相对以前的我,我觉得还是有改变的。

改变,是由于自省发现了不足,希望渴望改变现状。如今,我或许又要经历这样的一次过程,需要再一次改变。我曾经一直觉得,多思有益,考虑周全是没有错误的,但事实上过多的考虑,其实就是犹豫,就是迷惑,就是一种无能的体现,一种对自己的不信任,一种对自我的否定。就像一开始说的那样,时机稍纵即逝,如果在机会面前没有果断的决定,别人,不会那么友好的等你慢慢下定决心。上天对人是公平的,也是残酷的。机会摆在你的面前你没有珍惜,你没有抓住,就不要期望会有太美好的结果。

以前,我也隐约觉得,自己不够果断,遇事有些犹豫。但每次都被自己冠以考虑周全的帽子,事后还会自己啊Q一把,如果怎么怎么样了,或许情况比现在还不如呢?典型的保守派啊,现在还没有什么是需要守的,哪里会有不劳而获啊,行动,才是最好的决定。不然,就会如现在一般失落,总是想着假如当时怎样怎样,现在会怎样怎样。没有那么多假如,没有那么多如果,世上没有后悔药,我们要对自己的决定负责。犹豫是犹豫者的墓志铭,如果继续犹豫,失去的将更多。

这是一次反思,这是一次自省。从现在起,要坚决,要果断,要把握时机,要找清方向,要弄懂自己真正想要什么!一次新的开始,一个新的自我,不要畏惧改变,不要恐惧变化,唯一不变的,就是变化。

2012-04-02,一个旧的结束,一个新的开始,从自省……开始。

分类: 随笔 标签:

【zz】120行俄罗斯方块(Javascript版)

2012年3月10日  207 views 没有评论

最近比较流行特简洁的俄罗斯方块,前几天从csdn上看到有人写了这个120行的JS版,感觉挺有意思的,就转录于此。
原作者是CSDN论坛上的 lihanbing这段代码最有意思的是只要新建一个文本文件,将如下代码拷入,手动将文件后缀名修改为.html,然后双击就能运行。

<html>
<style>.c {margin :1px;width:19px;height:19px;background:red;position:absolute;}
.d {margin :1px;width:19px;height:19px;background:gray;position:absolute;}
.f {top:0px;left:0px;background:black;position:absolute;}
</style>
<body></body><html>
<script>
    var over=false,shapes=("0,1,1,1,2,1,3,1;1,0,1,1,1,2,2,2;2,0,2,1,2,2,1,2;0,1,1,1,1,2,2,2;1,2,2,2,2,1,3,1;1,1,2,1,1,2,2,2;0,2,1,2,1,1,2,2").split(";");
    function create(tag,css){
        var elm=document.createElement(tag);
        elm.className = css;
        document.body.appendChild(elm);
        return elm;}
    function Tetris(c, t, x, y){
        var c=c?c:"c";
        this.divs = [create("div",c),create("div",c),create("div",c),create("div",c)];
        this.reset = function(){
            this.x = typeof x != 'undefined'?x:3;
            this.y = typeof y != 'undefined'?y:0;
            this.shape = t?t:shapes[Math.floor(Math.random()*(shapes.length-0.00001))].split(",");
            this.show();
            if(this.field&&this.field.check(this.shape,this.x,this.y,'v')=='D'){
                over=true;
                this.field.fixShape(this.shape,this.x,this.y);
                alert('game over');}}
        this.show = function(){
            for(var i in this.divs){
                this.divs[i].style.left = (this.shape[i*2]*1+this.x)*20+'px';
                this.divs[i].style.top = (this.shape[i*2+1]*1+this.y)*20+'px';}}
        this.field=null;
        this.hMove = function(step){
            var r = this.field.check(this.shape,this.x- -step,this.y,'h');
            if(r!='N'&&r==0){
                this.x-=-step;
                this.show();}}
        this.vMove = function(){
            if(this.field.check(this.shape,this.x,this.y- -1,'v')=='N'){
                this.y++;
                this.show();}
            else{
                this.field.fixShape(this.shape,this.x,this.y);
                this.field.findFull();
                this.reset();}}
        this.rotate = function(){
            var s=this.shape;
            var newShape=[3-s[1],s[0],3-s[3],s[2],3-s[5],s[4],3-s[7],s[6]];
            var r = this.field.check(newShape,this.x,this.y,'h');
            if(r=='D')return;
            if(r==0){
                this.shape=newShape;
                this.show();}
            else if(this.field.check(newShape,this.x-r,this.y,'h')==0){
                this.x-=r;
                this.shape=newShape;
                this.show();}}
        this.reset();}
    function Field(w,h){
        this.width = w?w:10;
        this.height = h?h:20;
        this.show = function(){
            var f = create("div","f")
            f.style.width=this.width*20+'px';
            f.style.height=this.height*20+'px';}
        this.findFull = function(){
            for(var l=0;l<this.height;l++){
                var s=0;
                for(var i=0;i<this.width;i++){
                    s+=this[l*this.width+i]?1:0;}
                if(s==this.width){
                    this.removeLine(l);}}}
        this.removeLine = function(line){
            for(var i=0;i<this.width;i++){
                document.body.removeChild(this[line*this.width+i]);}
            for(var l=line;l>0;l--){
                for(var i=0;i<this.width;i++){
                    this[l*this.width- -i]=this[(l-1)*this.width- -i];
                    if(this[l*this.width- -i])this[l*this.width- -i].style.top = l*20+'px';}}}
        this.check = function(shape, x, y, d){
            var r1=0,r2='N';
            for(var i=0;i<8;i+=2){
                if(shape[i]- -x < 0 && shape[i]- -x <r1)
                    {r1 = shape[i]- -x;}
                else if(shape[i]- -x>=this.width && shape[i]- -x>r1)
                    {r1 = shape[i]- -x;}
                if(shape[i+1]- -y>=this.height || this[shape[i]- -x- -(shape[i+1]- -y)*this.width])
                    {r2='D'}}
            if(d=='h'&&r2=='N')return r1>0?r1-this.width- -1:r1;
            else return r2;}
        this.fixShape = function(shape,x,y){
            var d=new Tetris("d",shape,x,y);
            d.show();
            for(var i=0;i<8;i+=2){
                this[shape[i]- -x- -(shape[i+1]- -y)*this.width]=d.divs[i/2];}}}
    var f = new Field();
    f.show();
    var s = new Tetris();
    s.field = f;
    s.show();
    window.setInterval("if(!over)s.vMove();",500);
    document.onkeydown = function(e){
        if(over)return;
        var e = window.event ? window.event : e;
        switch(e.keyCode){
        case 38: //up
            s.rotate();
            break;
        case 40: //down
            s.vMove();
            break;
        case 37: //left
            s.hMove(-1);
            break;
        case 39: //right
            s.hMove(1);
            break;}}
</script>

【笔记迁移】C++Primer笔记 2010/9/8

2012年2月29日  198 views 没有评论

13章复制控制


智能指针类的实现是通过使用计数类来管理指针成员的。计数类将指针成员再次封装,并含有一个计数器来记录有多少个对象包含这个指针成员。需要注意的是要将使用计数类的类设为友元。同时在计数类的友元类中要转换对指针的操作为对计数类的对象的操作。在复制的时候,首先将左操作数的计数类对象减一(如果计数器减一后为零,则删除对象),然后将右操作数的计数类对象赋值给做操作数,这样左右操作数共用同一个计数器类的对象,同一个指针只有一个计数器类的对象。析构函数中也要对计数类的计数器进行操作(减一,为零则删除)。

让智能指针负责删除共享对象,可以避免悬垂指针的出现。

class U_Ptr{
    friend class HasPtr;
    int *ip;
    size_t use;
    U_Ptr(int *p):ip(p),use(1){}
    ~U_Ptr(){delete ip;}
};//这是一个计数类的示例。

智能指针


值型类给指针成员提供值语义将对指针的操作变为对指针所指向的值的操作,复制值型对象时,会得到一个不同的新副本,对副本所做的改变不会反映在原有对象上,反之亦然。
这样就解决了所有因共享对象而产生的一系列的问题,但是同时也不可以使用共享对象了。


复制构造函数,赋值操作符,析构函数 这三者是紧密联系的,如果定义了其中一个,一般也要定义剩余的两个。这三个函数时“复制控制”函数的主要部分,
他们定义了复制、赋值或撤销该类型对象的含义,对特殊的成员进行管理。
定义复制控制函数最为困难的部分通常在于认识到他们的必要性。分配内存或其他资源的类几乎总是需要定义复制控制函数来管理所分配的资源。


14章重载操作符与转换


内置逻辑与(&&)和内置逻辑或(||)操作符使用短路求值,如果重新定义该操作符,丢失操作符的短路求值特征。


如果要将类用作关联容器键类型,则应定义<操作符和==操作符,因为许多算法假定这些操作符石存在的。例如sort算法使用<操作符,而find算法使用==操作符。
如果定义了==操作符,相应的也应该定义不等操作符!=。而如果定义了<或某个关系操作符,则应将全部四个关系操作符都定义(>,>=,<,<=)。

//重载了某个操作符,则应将其相关的其他操作符也要重载


成员与非成员操作符重载:

  • 成员操作符重载有一个默认的参数即当前对象的this指针,这是默认的左操作数,所以复制运算符=重载时只需要一个右操作数作为参数既可。ClassType& operator = (const ClassType&);
  • 当左操作数不是当前类的对象时,我们就必须使用非成员实现方式,例如输出操作符<<的左操作数应该是ostream对象。ostream& operator<< (ostream& out,const ClassType& s);//二元操作符重载时第一个参数为左操作数,第二个参数为右操作数。

一般非成员实现时要在类中显式声明此重载函数

成员与非成员


成员或非成员实现 :

  • 赋值(=)、下标([])、调用(())和成员访问箭头(->)等操作符必须定义为成员,将这些定义为非成员函数将在编译时出错。
  • 改变对象状态或与给定类型紧密联系的其他一些操作符,如自增、自减和解引用,通常应定义为成员函数。
  • 对称的操作符,如算术操作符、相等操作符、关系操作符和位操作符,最好定义为普通非成员函数。

成员与非成员


当重载输出操作符的时候所做的格式或应尽量的少尤其不要输出换行符,如果需要对输出进行格式化,我们应该让用户自己来控制输出细节。

阅读全文…

【笔记迁移】C++Primer笔记 2010/9/6

2012年2月29日  171 views 没有评论

13章复制控制


编写自己的复制构造函数时,必须显式复制需要复制的任意成员。显示定义的复制构造函数不会进行任何自动复制。


即使对象赋值给自己,赋值操作符的正确工作也非常重要。保证这个行为的通用方法是显式检查对自身的赋值。最需要注意的是在赋值的时候做操作数的删除操作,如果不进行检查,
可能会出现先删除之后又将已经删除掉的数据赋值给做操作数,造成数据丢失。