Monthly Archives: July 2012

© 2012 . All rights reserved.

poj3468–绝对经典的线段树题

线段树题,本题对线段树的操作有建树(MakeTree())、查找(Query())、更新(update())。建树一次完成,时间花费为O(LogN);查询的时间复杂度鄙人还不会分析O(∩_∩)O~,最坏可能是O(N),不过这种情况应该很难出现;更新的算法值得商榷,不同的策略时间复杂度会相差很大。下面讲解两种比较用以想到的更新策略。更新方法一:每次都将所有能更新的节点更新,这种方式最坏情况下将会更新树中所有节点,此时时间复杂度为O(N)。本题使用这种方法会TLE。更新方法二:每次都尽量少的更新节点信息,与第一种方法相比,Node内会多一个变量en,我把它形象的称之为“势能”,计算结果时要将该的所有父节点的“势能”也考虑在内。这种方法的时间复杂度也不好分析,但明显优于第一种方法。这一题对时间卡的很紧,主要是花在树的更新上。关于线段树可以先参阅:http://www.cppblog.com/hoolee/archive/2012/07/29/185531.html以下是本题代码: #include<stdio.h>#include<stdlib.h>#define LEN 100010#define LEN0 6550000typedef struct {    int a, b;    int l, r;    long long sum;//记录该区间内的部分和    long long en;//记录该节点“势能”。}Node;int count;Node A[LEN0];int allNum[LEN];void MakeTree(int i){    A[i].en = 0;    int a = A[i].a;    int b = A[i].b;    int mid = (a + b) / 2;    if(a == b)    {        A[i].sum = allNum[a];        return;    }    int l = ++count;    int r = ++count;    A[l].a = a;    A[l].b = mid;    A[r].a = mid + 1;    A[r].b = b;    MakeTree(l);    MakeTree(r);    A[i].sum = A[l].sum + A[r].sum;    A[i].l = l;    A[i].r = r;}long long Query(int t, int aa, int bb, long long en){    int a = A[t].a;    int b = A[t].b;    if(a == aa && b == bb)//1    {        return A[t].sum + en * (bb - aa + 1);     }    int mid = (a + b) / 2;    if(bb <= mid)//2        return Query(A[t].l, aa, bb, en + A[t].en);    if(aa >= mid + 1)//3        return Query(A[t].r, aa, bb, en + A[t].en);    long long suml = Query(A[t].l, aa, mid, en + A[t].en);//4    long long sumr = Query(A[t].r, mid + 1, bb, en + A[t].en);    return suml + sumr;}void Update(int t, int aa, int bb, int c){    int a = A[t].a;    int b = A[t].b;    int mid = (a + b) / 2;    int l = A[t].l;    int r = A[t].r;    A[t].sum += (bb - aa + 1) * c;    if(aa == a && bb == b)    {        A[t].en += c;        return;    }    if(bb <= mid)        Update(l, aa, bb, c);    else if(aa >= mid + 1)        Update(r, aa, bb, c);    else    {        Update(l, aa, mid, c);        Update(r, mid + 1, bb, c);    }    }int main(){    int i, j;    int N, Q;    int a, b, c;    scanf(“%d%d“, &N, &Q);    for(i = 1; i <= N; i++)        scanf(“%d“, &allNum[i]);        count = 0;    int t = ++count;    A[t].a = 1;    A[t].b = N;    MakeTree(t);    char str[50];    getchar();    for(i = 0; i < Q; i++)    {        gets(str);        if(str[0] == ‘Q‘)        {            sscanf(&str[1], “%d%d“, &a, &b);            long long sum = Query(1, a, b, 0);            printf(“%lld\n“, sum);        }        else if(str[0] == ‘C‘)        {            sscanf(&str[1], “%d%d%d“, &a, &b, &c);            Update(1, a, b, c);        }    }    //system(“pause”);} 小鼠标 2012-07-31 20:40 发表评论 from C++博客-首页原创精华区 http://www.cppblog.com/hoolee/archive/2012/07/31/185779.html How to Display Children Clothes woolrich outlet Beyonce And Tina Knowles on or whatever you’re eating will go straight to my hips chanel shoesFashion Design for Capri One Piece Jumpsuits

© 2012 . All rights reserved.

这些年、我收集的JQuery代码

  1. 如何创建嵌套的过滤器 //允许你减少集合中的匹配元素的过滤器, //只剩下那些与给定的选择器匹配的部分。在这种情况下, //查询删除了任何没(:not)有(:has) //包含class为“selected”(.selected)的子节点。 .filter(“:not(:has(.selected))”) 2. 如何重用元素搜索 var allItems = $(“div.item”); var keepList = $(“div#container1 div.item”); //现在你可以继续使用这些jQuery对象来工作了。例如, //基于复选框裁剪“keep list”,复选框的名称 //符合 <DIV>class names: $(formToLookAt + ” input:checked”).each(function() { keepList = keepList.filter(“.” + $(this).attr(“name”)); }); </DIV> 3. 任何使用has()来检查某个元素是否包含某个类或是元素 //jQuery … Continue reading

© 2012 . All rights reserved.

代码整洁之道

      现在的软件系统开发难度主要在于其复杂度和规模,客户需求也不再像Winston Royce瀑布模型期望那样在系统编码前完成所有的设计满足用户软件需求。在这个信息爆炸技术日新月异的时代,需求总是在不停的变化,随之在2001年业界17位大牛聚集在美国犹他州的滑雪胜地雪鸟(Snowbird)雪场,提出了“Agile”(敏捷)软件开发价值观,并在他们的努力推动下,开始在业界流行起来。在《代码整洁之道》(Clean Code),提出一种软件质量,可持续开发不仅在于项目架构设计,还与代码质量密切相关,代码的整洁度和质量成正比,一份整洁的代码在质量上是可靠的,为团队开发,后期维护,重构奠定了良好的基础。在这本书中作者提出了注重实际开发实践的细节,而不是站在空洞的理论来谈论整洁之道。 什么是整洁代码?不同的人会站在不同的角度阐述不同的说法。而我最喜欢的是Grady Booch(《面向对象分析与设计》作者)阐述:      “整洁的代码简单直接。整洁的代码如同优美的散文。整洁的代码从不隐藏设计者的意图,充满了干净利落的抽象和直截了当的控制语句。”        整洁的代码就是一种简约(简单而不过于太简单)的设计,阅读代码的人能很清晰的明白这里在干什么,而不是隐涩难懂,整洁的代码读起来让人感觉到就像阅读散文-艺术的沉淀,作者是精心在意缔造出来。 一:命名       命名包括变量、函数、参数,类等,一个好的命名能够很好的表述其所承载的业务,从命名上就已经很好的答复了为什么存在,做了什么事,应该怎么用等的大部分的问题,阅读者看到它的时候不必去深究其实现细节,一切都在命名上一目了然。一个好的命名必须是名副其实,不存在歧义(双关语或常见属于冲突),直接了当(否定语句或者误导性命名)。 二:函数:       从汇编/C时代开始的到现在函数一直都存在与我们开发中不可或缺的一部分,结构化组织,重用.作为函数式语言的一等公民,所有程序的第一组代码。 好的函数必须足够的小,其次还是足够的小。很容易想像阅读上千行的代码,是多么巨大的自我心理挑战,在实习的时候工作于毫无分层逻辑的WinForm平台下,完全依赖RAD模式带来后置cs页面上千行的代码,每次修改都令我恼怒,恨不得重写整个业务逻辑。 一个函数在于短小精悍,只作一件事情,并做好这件事,只做一件事才能得到更好的利用函数名表述自己。 好的函数还应该是CQS(查询命令分离)无副作用的(不存在隐藏歧义的背后逻辑),并对其他类型不存在“依恋情节(Feature Envy)“(类中的变量被所有的函数使用这是理想的高内聚,万物皆有其位,而后物尽归其位)。 函数的参数应该足够的少,无最好,一次之,再次为二,尽量避免三个以及三个以上,对于太多的参数你可能该采用IntroduceParameterObject(引入参数对象)。 重复的代码。重复在软件系统是万恶的,我们熟悉的分离关注点,面向对象,设计原则…都是为了减少重复提高重用,Don’t repeat yourself!(DRY)。 三:注释、格式:      并不是写出完备的注释就是好的开发人员,如果代码清晰的表述自己意图,那么注释反而多余。在《重构-改善现有代码之道》中Martin Fowler指出多余的注释是一种代码坏味道。就是好的注释随着项目的维护不断的重构很多时候也会变得不那么适应,而我们很少会去主动维护。再则误导性的注释更为使用者所憎恨。当然有时我们也得使用注释,注释并不是万恶的,当我们没法用代码来描述自己的时候,我们需要注释去描述意图;多余有副作用的代码给使用者提供警告注释。TODO开发时进度控制,比如你在进行较大规模领域重构,目前有些逻辑不再适应,不那么自然,而对它的重构还在任务列表最后,你可以选择标注在TODO中,最后完成从ToDoList中去掉每一个TODO任务。     良好的代码格式,会使得我们阅读更容易,一套共同的格式会让我们查找理解更快速。每个团队都应该遵循一套固定的代码格式规范,整个软件系统的统风格统一,而不是各自为政各成一体。 四:对象和数据结构:     数据结构指的就是数据的载体,暴露数据,而几乎没有有意义的行为的贫血类。最常见的应用在分布式服务,以wcf,webservice,reset之类的分布式服务中不可或缺的数据传输对象(DTO)模式,DTO(Request/Response)就是一个很典型的数据载体,只存在简单的get,set属性,并且更倾向于作为值对象存在。而对象则刚好相反作为面向对象的产物,必须封装隐藏数据,而暴露出行为接口,DDD中领域模型倾向于对象不仅在数据更多暴露行为操作自己或者关联状态。     数据结构和对象之间看是细微的差别却导致了不同的本质区别:使用数据结构的代码便于在不改动现在数据结构的前提下添加新的行为(函数),面向对象代码则便于不改动现 有函数的前提下添加新的类。换句话说就是数据结构难以添加新的的数据类型,因为需要改动所有函数,面向对象的代码则难以添加新的函数,因为需要修改所有的类。在任何一个复杂的系统都会同时存在数据结构和对象,我们需要判断的是我们需要的是需要添加的新的数据类型还是新的行为函数。    隐藏作为面向对象主要特性中的最重要特性,封装隐藏是面向对象中最重要的特性,一个好的面向对象代码肯定是对对象的内部细节做到很好的隐藏封装,封装过后才有是多态,委派之类的。一个好的面向对象的代码一定是具有很好的隐藏封装,易于测试,不稳定因素往往集中在一处很小或者固定的位置,不稳定因素的变更不会导致更大面积的修改扩散。   对象的隐藏要求:方法不应和任何调用方法返回的对象操作,换句话之和朋友说话,不和陌生人说话(迪米特法则,或被译为最小知识原则),比如:ctxt.getOptions().getSearchDir().getAbsolutePath(),就是迪米特法则的反例模式。 … Continue reading

© 2012 . All rights reserved.

学生终究要面对社会

       今天是7月的最后一天了,强迫自己写点东西。曾经不止一次想要写一篇博文,却总被自己的懒惰给阻止,存了三篇草稿了,可是没有一篇继续写下去。原本每周一记的想法也成了海市蜃楼,可望而不可即。        缺少了这种习惯以后,再静下心来去写一些需要组织逻辑,需要斟酌语言的东西就会茫然而无所适从。记得自己高中的时候,自己还是一个带着知识分子忧患意识的小愤青、小文青,没事的时候爱看点文学,看点哲学,写点让人耳目一新的东西,虽然有时为了表现独具一格的思维难免显得牵强附会,但终究是有思考的时候,有自己的想法,或者说,有着“不切实际”的追求。         高中的时候,自己搞NOIP,最初自己的进步是非常快的,因为那知识语言的基础,可是到了后来,到了学习DFS,BFS的时候就有点浮躁了,陷入寻找各种C++资料,各种Delphi资料,各种汇编资料的深渊,一陷就是两年,直到自己参加省赛的时候,才直到原来自己还要参加比赛,自己学习的是算法,而不是资料搜索学。囤了上百G的资料,最后连自己有哪些资料都不知道了,可是没有一点是自己真正去看过的。都是立马要用的时候,再去百度去谷歌再找,硬盘里的东西,很少去整理去回顾,也许这就是所说的“资料收集强迫症”或者“下载强迫症”吧。        上了大学以后,也真正接触了程序,接触了代码。看着自己写的东西一点一点变成产品,变成“能用”的东西,而不仅仅是一道给个输入然后跑出个输出再到OJ的测评器里查看是否AC的题目。当时虽然很高兴,可因为有高中的惨痛例子在前,所以也很理智地告诫自己,不要得意忘形,人在学习一门新的知识的时候,往往很有激情,因为自己对它感兴趣,一旦感觉自己入了门,开始一些深层次的东西的时候,就容易在门外徘徊,不停地寻找资料,不停的收集保存资料,然后看看这,看看那,然后就没有然后了。只能等到下一个转折点,让自己终结这一段学习历程。稍一总结,其实就是两个字:浮躁!         人有时候是非常奇怪的,明明知道不能这么做,可偏偏有要这么做。而且不静下来仔细想想的话都没有发觉原来自己还在这么做。每每有好的想法,有好的做法,却总是半途而废,不能坚持。在互联网的环境下,大部分的阅读似乎都是浅阅读,正如《浅薄:互联网如何毒化了你的大脑》所说的那样,无法专心去做一件事,在code或read的同时总是忍不住去打开一个网页,去刷刷微博,上个人人,然后思维就乱了,再然后心就静不下来了,一天很容易就过去了。         其实写了这么多,感觉自己有点黔驴技穷了,再多的观点也没有了,也没有刘未鹏大哥那样深入的洞察力和对时间的思考。自己不能为了写一篇博客而写博客,去多写一些自己没有概念非常牵强的东西,写多了只会惹人生厌,因为自己没有那个能力。        每次写非代码层次的东西,都要思索斟酌好久,因为发现,每次总结自己缺点的时候,上一次总结的那几个缺点依然存在,再写也是些重复的东西,这也是自己很久不更新博文的原因。写着写着,却又想通了一点,如果不总结,如何知道自己的这些缺点依然存在,缺少了认识自我反省自我的空间,又如何去改正自我提高自我。所有的成长都不是一蹴而就的,至少对自己来说是这样的,因为自己最了解自己,当把自己放到一个非常低位置去思考自己的时候,会发现自己身上非常多的弱点,非常多的缺陷,包括情感上的和智力上的。其实正是因为自己知道这些缺陷,才能在一件一件事情发生前或者发生后去分析到底是哪些缺陷影响了自己,哪些缺陷在阻碍自己的成长阻碍自己发展。深刻认识自己,正视自己的不足,趋利避害,而不要感情用事,这才是人生真正应该拥有的态度。        其实很多时候,自己都在为那些认为“技术之高无上”的人担忧,因为我们要交往的,不只是技术,还有很多人,好人坏人、脾气好的脾气不好的、甚至是奇葩,我们都避免不了,该接触的时候都要接触。前几天给学校的一个老师做东西,做完了以后他又要求再加一个功能,再加一个内部办公的功能,要能上传各种报表,还要能分析统计报表,导出报表,让一两天给他做完,当时其实非常生气,这种东西早不说,你以为加个模块就是你看见的点点鼠标就完了吗,你知道点一下鼠标背后要做多少工作吗。后来想想,自己确实不该生气,首先,生气了也不能朝他发火,因为不熟,还因为他是老师,自己是学生。其次,遇到这种事情第一想法是发火,撂挑子不干了本身就是不正确的,不管以后工作了环境有多宽松,奇葩还是不可避免地要遇到的,缺少涵养没有从容的心态是不行的,况且这个老师也确实不懂,给他好好解释是可以的。所幸,有另一老师给他解释了一下,延长了时间。        对待事物的心态是非常重要的,一定要从容,努力提高自己的涵养,不随意发火。不再对着IE6怒骂,也不再因为不明确的需求诅咒,对待同学的指责和各种所谓领导的“指示”,不再心生怨愤。改变自己能改变的,对自己改变不了的就不要太在意了。不管世俗还是世故,是成熟了还是丧失了追求,这么做对自己来说终归是一种保护。无论如何,这样总比满口的尼玛、cao、开口闭口老子不干了要好得多。        不浮躁,不怨愤,认识自己,静下心来扎扎实实学技术,走向社会坦荡圆滑去做人,自己无力为之的就由他去吧,保持自己的底线就行。毕竟,我们是小民,是匹夫,虽有责于国家,却无权去改变。达则兼济天下 穷则独善其身喽。终究要走出校园,面向社会的我们也应该收一收棱角,现实一点了。        有点乱,但却是自己这几天所想的。写写想想,写了一个多小时,留待日后翻翻~ 本文链接 from 博客园_首页 http://www.cnblogs.com/fuyunbiyi/archive/2012/07/31/2617419.html romantic relationship comparing level fashion and beauty magazines and having pahtogenic the diet … Continue reading

© 2012 . All rights reserved.

当爬虫被拒绝时(Access Denied)

     由于要准备测试数据,不得不大量爬取某个网站的内容。为了防止被封,特意将爬虫设计为单线程同步的爬虫。结果在爬了大约3万个页面的时候,对方发回Access Denied。等一段时间后再启动爬虫,结果还是Access Denied。这时才明白这样的想法太天真了,当初就应该找其它方法来避免才对。而本文则记述了这些其它方法。 1. 伪装user agent       User agent 是HTTP协议的中的一个字段, 其作用是描述发出HTTP请求的终端的一些信息。 服务器通过这个字段就可以知道要访问网站的是什么人了。每个浏览器,每个正规的爬虫都有其固定的user agent,因此只要将这个字段改为这些知名的user agent,就可以成功伪装了。不过,不推荐伪装知名爬虫,因为这些爬虫很可能有固定的IP,如百度爬虫。与此相对的,伪装浏览器的user agent是一个不错的主意,因为浏览器是任何人都可以用的,换名话说,就是没有固定IP。推荐准备若干个浏览器的user agent,然后每次发送请求的时候就从这几个user agents中随机选一个填上去。IE的几个user agent如下: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2) Mozilla/4.0 (compatible; MSIE 6.0; … Continue reading

© 2012 . All rights reserved.

设计模式学习总结-解释器模式(Interpreter Method)

问题:在面向对象的设计中和开发中,经常会遇到,有一些请求或操作,很难用对象的形式来表示或者处理,比如我们写一个简单的算术计算工具计算“a+b”,可以简单的定义一个方法,接收两个变量,做算术“+”计算返回结果,可是如果让这个方法可以实现“加减乘除”四则运算,我们又要修改方法加入一个运算符参数,但是由于需求变化,又要加入多个操作数的运算如:“a+b-c*d”,该如何处理呢?穷举方法定义所有可能出现的操作显然是不可能的,我们能否定义一种来解析算术表达式的方法,直接将算术表达式作为字符串传递给计算方法,计算方法将算术表达式解析后再计算返回结果?定义:Interpreter模式是一种行为模式,给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 意图:将某一特定领域的比较复杂问题,表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,来应对使用普通的编程方式实现面临非常的频繁变化的问题。(建立语法树,然后用语法将表达式进行解析。) 参与者:•抽象表达式(Abstract Expression)角色:声明一个所有的具体表达式角色都需要实现的抽象接口。这个接口主要是一个interpret()方法,称做解释操作。•终结符表达式(Terminal Expression)角色:实现了抽象表达式角色所要求的接口,主要是一个interpret()方法;文法中的每一个终结符都有一个具体终结表达式与之相对应。比如有一个简单的公式R=R1+R2,在里面R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。 •非终结符表达式(Nonterminal Expression)角色:文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,“+”就是非终结符,解析“+”的解释器就是一个非终结符表达式。•环境(Context)角色:这个角色的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,我们给R1赋值100,给R2赋值200。这些信息需要存放到环境角色中,很多情况下我们使用Map来充当环境角色就足够了。  UML: 代码说明: 一个解析算术表达式计算的例子,为了快速说明问题,例子仅支持双操作数运算 /// <summary>/// 抽象表达式(Abstract Expression)角色/// </summary>public abstract class  Expression{        public abstract void Interpret();} /// <summary>/// 具体的算术解析器表达式/// </summary>public class CalculatorExpression : Expression{    public int Value;        string Expression;    public CalculatorExpression(string _expression)    {        Expression = _expression;    }    public override void Interpret()    {        string[] Numbers = Expression.Split(‘+‘,‘-‘);                 if (Expression.IndexOf(‘+‘)>-1)        {            this.Value = int.Parse(Numbers[0]) + int.Parse(Numbers[1]);        }        else if (Expression.IndexOf(‘-‘) > -1)        {            this.Value = int.Parse(Numbers[0]) - int.Parse(Numbers[1]);        }        else if (Expression.IndexOf(‘*‘) > -1)        {            this.Value = int.Parse(Numbers[0]) * int.Parse(Numbers[1]);        }        else if (Expression.IndexOf(‘/‘) > -1)        {            this.Value = int.Parse(Numbers[0]) / int.Parse(Numbers[1]);        }    }}/// <summary>/// 环境(Context)角色/// </summary>public class ContextCalculator {    /// <summary>    /// 计算方法    /// </summary>    /// <param name=”expression”></param>    /// <returns></returns>    public int Calculate(string expression)    {        CalculatorExpression ex = new CalculatorExpression(expression);        ex.Interpret();        return ex.Value;    }}public void InterpreterTest(){    ContextCalculator c = new ContextCalculator();    //传入表达式计算    //无论是扩展为多操作数,还是加入括号,客户端都不会受到影响。    c.Calculate(“2+1“);} 优点:•可以很容易地改变和扩展文法,因为该模式使用类表示文法规则,你可使用继承来改变或扩展文法,实现灵活的扩展。•容易实现文法,因为定义抽象语法树中各个节点的类的实现大体类似,这些类都易于直接编写。缺点:•文法中的每一条规则至少定义了一个类,对于复杂的文法表示会产生比较大的类层次结构,难以管理和维护。•因为文句会分析成树结构,解释器需要递归访问它,所以效率会受影响。  应用场景:如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。 PS:.Net系统中提供了很多解释器,如:LINQ,正则表达式等等。   本文链接 from 博客园_首页 http://www.cnblogs.com/ejiyuan/archive/2012/07/31/2617203.html Cook on low heat for 30 minutes Isabel Marant Sneakers What sets a trend for fashion each year compared to … Continue reading

© 2012 . All rights reserved.

线上旅行市场数据分析(信息图)

喜欢在旅行路上签到“我在这里”,又或者喜欢上传旅行照片到社交网上?你不是一个人在做这件事。旅行本该和技术离得很远,但目前美国线上旅行市场1620亿的规模却告诉我们,这一切不容小视。 这张信息图对线上旅行市场进行了归纳,让我们来看看人们的旅行是如何受社交媒体、互联网影响的: Via Funsherpa 除非注明,本站文章均为原创或编译,转载请注明: 文章来自36氪 您可能感兴趣的文章: 开发者开始对Android平台感兴趣?或许这幅“各平台吸引力”图能告诉我们 Windows Phone7月欧洲市场份额增长23.5%,Lumia610和Lumia900功劳最大 大数据可视化的绝妙案例:互联网地图,浩瀚宇宙中的网站“星球” from 36氪 http://www.36kr.com/p/141226.html proper way to beat increasing price bands burberry schal 150 offers a truck for everyone food budget for family of three that helped me to discern … Continue reading

© 2012 . All rights reserved.

Android数据库ORMlite框架翻译系列(第一章)

前言   个人感觉android上sqlite已经比较好用,但是如果需要在android上像J2EE那样开发的话那么sqlite还是显得比较复杂,这个时候你当然可以选择一些android平台上的ORM框架。ORM框架是做什么的,android平台上有哪些好用的ORM框架,这些问题你通通可以google得到你满意的结果,在此不做解释。本系列主要是翻译ORMlite文档。   为什么翻译ORMlite?简单点说就是因为个人觉得ORMlite是android平台上不错的ORM框架,官方也提供了很多相关介绍。但是几乎没有看到有中文文档。为了更多人可以学习到这个框架所以决定把官方的文档翻译成中文。个人英语水平非常有限,但是本人会尽力,如果文中有不妥的翻译之处敬请告之。文档中的比较杂的内容就不在文档中进行翻译,比如参见xxx连接,这些没有意义。主要翻译的技术文档而非专业英语,但基本会保持原文档的内容。 ————————————————————————————- 1 获得开始 1.1 下载ORMlite jar     为了使用ORMLite,你需要下载相关的jar文件。ORMLite发布包是一个默认库,不过相关jar文件也可以通过网络从内部资源库里面获得。 通过JDBC连接SQL 数据库的用户需要下载ormlite-jdbc-4.41.jar和ormlite-core-4.41.jar两个文件。在android应用中使用,你需要下载ormlite-android-4.41.jar和ormlite-core-4.41.jar两个文件。在有ORMlite后台实现的JDBC中或者是Android中你都需要ormlite-core发布包。ORMLite没有任何外部依赖,即使可能有你想用的其他选用包。 1.2 配置class 下面是个class通过使用ORMlite 注解配置持久化到数据的例子。@DatabaseTable 注解配置Access类到数据库名为accounts的表。@DatabaseField注解映射Account中的每个字段到数据库中相同名字的字段。 一个字段需要配置成数据库中表的主键那么可以通过使用id=true 注解字段。并且,值得一提的是一个无参的构造器是必须的,这样的话通过查询可以返回一个对象。   @DatabaseTable(tableName = “accounts”)public class Account {@DatabaseField(id = true)private String name;@DatabaseFieldprivate String password;public Account() {// ORMLite needs a no-arg constructor}public Account(String name, String password) {this.name = name;this.password … Continue reading

© 2012 . All rights reserved.

Android中EditTex焦点设置和弹不弹出输入法的问题

  今天编程碰到了一个问题:有一款平板,打开一个有EditText的Activity会默认弹出输入法。为了解决这个问题就深入研究了下android中焦点Focus和弹出输入法的问题。在网上看了些例子都不够全面,在这里全面总结下。   一:EditText为什么会默认弹出输入法?     同样的代码,碰到有EditText控件的界面时有的机子会弹出输入法,有的机子不会弹出。不好意思,这问题我也一头雾水,谁知道可以告诉我,否则我就把这个问题留下来,以后研究android源码时再搞个清楚。但是…我有解决方案。   二:默认弹出和默认关闭输入法的解决方案。   1.默认关闭,不至于进入Activity就打开输入法,影响界面美观。   ①在布局文件中,在EditText前面放置一个看不到的LinearLayout,让他率先获取焦点:   <LinearLayout android:focusable=”true” android:focusableInTouchMode=”true” android:layout_width=”0px” android:layout_height=”0px”/>   ②方法二:先看一个属性android:inputType:指定输入法的类型,int类型,可以用|选择多个。取值可以参考:android.text.InputType类。取值包括:text,textUri, phone,number,等.   Android SDK中有这么一句话“If the given content type is TYPE_NULL then a soft keyboard will not be displayed for this text view”,   先将EditText的InputType改变为TYPE_NULL,输入法就不会弹出.然后再设置监听,再重新设置它的InputType.   editText.setOnTouchListener(new OnTouchListener() {                                     public boolean onTouch(View … Continue reading

© 2012 . All rights reserved.

FFLIB 多进程并发框架

         三年来一直从事服务器程序开发,一直都是忙忙碌碌,不久前结束了职业生涯的第一份工作,有了一个礼拜的休息时间,终于可以写写总结了。于是把以前的开源代码做了整理和优化,这就是FFLIB。虽然这边总结看起来像日记,有很多废话,但是此文仍然是有很大针对性的。针对服务器开发中常见的问题,如多线程并发、消息转发、异步、性能优化、单元测试,提出自己的见解。 面对的问题          从事开发工程中,遇到过不少问题,很多时候由于时间紧迫,没有使用优雅的方案。在跟业内的一些朋友交流过程中,我也意识到有些问题是大家都存在的。简单列举如下: 多线程与并发 异步消息/接口调用 消息的序列化与Reflection 性能优化 单元测试 多线程与并发          现在是多核时代,并发才能实现更高的吞吐量、更快的响应,但也是把双刃剑。总结如下几个用法: 多线程+显示锁;接口是被多线程调用的,当被调用时,显示加锁,再操作实体数据。悲剧的是,工程师为了优化会设计多个锁,以减少锁的粒度,甚至有些地方使用了原子操作。这些都为领域逻辑增加了额外的设计负担。最坏的情况是会出现死锁。 多线程+任务队列;接口被多线程调用,但请求会被暂存到任务队列,而任务队列会被单线程不断执行,典型生产者消费者模式。它的并发在于不同的接口可以使用不同的任务队列。这也是我最常用的并发方式。   这是两种最常见的多线程并发,它们有个天生的缺陷——Scalability。一个机器的性能总是有瓶颈的。两个场景的逻辑虽然由多个线程实现了并发,但是运算量十分有可能是一台机器无法承载的。如果是多进程并发,那么可以分布式把其部署到其他机器(也可部署在一台机器)。所以多进程并发比多线程并发更加Scalability。另外采用多进程后,每个进程单线程设计,这样的程序更加Simplicity。多进程的其他优点如解耦、模块化、方便调试、方便重用等就不赘言了。 异步消息/接口调用          提到分布式,就要说一下分布式的通讯技术。常用的方式如下: 类RPC;包括WebService、RPC、ICE等,特点是远程同步调用。远程的接口和本地的接口非常相似。但是游戏服务器程序一般非常在意延迟和吞吐量,所以这些阻塞线程的同步远程调用方式并不常用。但是我们必须意识到他的优点,就是非常利于调用和测试。 全异步消息;当调用远程接口的时候,异步发送请求消息,接口响应后返回一个结果消息,调用方的回调函数处理结果消息继续逻辑操作。所以有些逻辑就会被切割成ServiceStart和ServiceCallback两段。有时异步会讲领域逻辑变得支离破碎。另外消息处理函数中一般会写一坨的switch/case 处理不同的消息。最大的问题在于单元测试,这种情况传统单元测试根本束手无策。 消息的序列化与Reflection          实现消息的序列化和反序列化的方式有很多,常见的有Struct、json、Protobuff等都有很成功的应用。我个人倾向于使用轻量级的二进制序列化,优点是比较透明和高效,一切在掌握之中。在FFLIB 中实现了bin_encoder_t 和 bin_decoder_t 轻量级的消息序列化,几十行代码而已。 性能优化          已经写过关于性能方面的总结,参见          http://www.cnblogs.com/zhiranok/archive/2012/06/06/cpp_perf.html      有的网友提到profiler、cpuprofiler、callgrind等工具。这些工具我都使用过,说实话,对于我来说,我太认同它有很高的价值。第一他们只能用于开发测试阶段,可以初步得到一些性能上参考数据。第二它们如何实现跟踪人们无从得知。运行其会使程序变慢,不能反映真实数据。第三重要的是,开发测试阶段性能和上线后的能一样吗?Impossible ! … Continue reading

© 2012 . All rights reserved.

多样化的力量

Union Square Venture著名投资人Fred Wilson两张图让你看清投资多样化的力量:假如投资数额相当,那么在10家投资的公司中,投资人的所有收益只来自一家公司,即最后的那个大赢家。但是,基本上没人能猜准到底哪家公司会成为最后的大赢家。 投资创业公司风险很大,假如你只是把钱投在一家公司上面,那你很有可能血本无归;假如你把钱投在了两家公司上面,你还是很有可能会亏钱;当这个数字扩展到5的时候,你可能会从5项投资中捞回本钱。而当这个数字扩展到10的时候,你就可能开始从这种投资组合中赚钱了。 这个说法后面涉及的数学计算实际非常简单。假设每家创业公司有33%的概率为投资人赚到钱,有33%的概率让投资人不赚也不亏,有33%的概率完全失败,还有10%能带来很大的投资回报率(超过10倍),你就可以模拟出下面的结果来: (注:在上面这个表格中,Fred Wilson总共模拟了10家公司。按照上面的概率上述的每种类公司的数量应该分别是3.3,3.3,3.3和1家。模拟的结果中有两家公司会让投资人赚到钱,即Amount Returned=150,000;有四家公司会让投资人血本无归,即Amount Returned=0;还有三家公司能全额返还投资资金,即Amount Returned=50,000。) 从这个表格可以看到,投资人在上述的10个投资组合的所有利润都来自一家公司,那个大赢家。假如你没把钱投在那家公司上面,那就相当于你总共投资了450,000美元,然后也可以收回450,000美元。那你何必费那么大的劲,你还不如把钱存在银行里。 所以你才需要投足够多的公司,以保证在你所投的所有公司中起码有一个大赢家,而这也意味着你要下足够的赌注。 这里面还有一点非常重要,就是差不多每笔投资的钱都应该是一样的。在投钱的时候,你可别自作聪明,认准了某家公司会成功,然后在这家公司上多投一些钱,又在那些你拿不准的公司上面少投了些钱。 其实在投资创业公司的时候只有一件事情确信无疑的,那就是,不存在什么确定的事情,也不存在一定成功的公司。 同样的投资组合,假如投资人随机地给这些公司投不同数额的钱,模拟结果会怎样呢: 你可以看到,即便上述的10家公司的投资回报率(最后一栏)跟上面的那张图是一样的,你在这10家公司上面投钱的数额在很大程度上会影响到你最终的收益。其实最后就是取决于你在那个大赢家上面投了多少钱。因为我并不认为你可以成功预测到底哪家公司会成为最后的大赢家,所以我的观点是,你最好在投资数额上保持一致。 作为一名投资人,你肯定会遇到这样的情况,即有些公司投得很好,也有些投资完全看走眼。假如你将多样化作为自己的投资策略,那么碰到上面的情况也就更容易处理了。但假如你把钱投在了一家公司上面,那遇上那些情况你的日子就相当惨烈了。创业者会在一件事情全力以赴,假如那事成了,他们也会得到相应的回报。但是,投资人不应该把钱投在一家创业公司上,而应该想着多样化投资组合。   除非注明,本站文章均为原创或编译,转载请注明: 文章来自36氪 您可能感兴趣的文章: “情景故事”与“大V测试” 一家创业公司对于专利的看法 纽约时报消息称,苹果考虑花数亿美元对Twitter进行战略投资 生活就是游戏,游戏改变世界 VC们是如何挣钱的(创业者是否应该关注这件事)? from 36氪 http://www.36kr.com/p/140377.html Developed over two episodes burberry schal Accurate Control Of A … Continue reading

© 2012 . All rights reserved.

抛弃AJAX?! "服务器推"之初体验

以聊天室为例子,说起写聊天室,大家随口都能说出个大概: 即每隔一段时间向服务器异步请求更新,用四个字母代替之就是AJAX。   其实我们转念想想,我们使用AJAX的目的就是使页面能实时地更新,倘若我们的动态页面能够实时地更新,我们干嘛还费这些周折?   先看一个小试验: 1 <?php2 while(true){3 echo ‘Hello’;4 sleep (1000);5 }6 ?> 如果如我们所愿,则页面将每隔一秒都会显示一个‘hello’   看到这,也许知道我们聊天室的消息显示页面该怎么写了,请看伪代码。 1 <?php 2 $currentData = getData(); 3 while (true){ 4 $differences=getData(); 5 if ($differences!=$currentData){ 6 echo $differences; 7 } 8 sleep (10000); … Continue reading