月度归档:2013年06月

C#反转链表

public class ReverseLinkedList
    {
        void main()
        {
            Node list = InitList();
            Console.WriteLine(list);
            list = list.ReverseList(list);
            Console.WriteLine(list);
        }
        public Node InitList()
        {
            Node head = new Node();
            head.Next = null;
            head.Data = -1;
            Node q, p;
            p = head;
            for (int i = 1; i <= 10; i++)
            {
                q = new Node();
                q.Data = i;
                q.Next = null;
                p.Next = q;
                p = q;
            }
            return head;
        }
    }
    public class Node
    {
        private T data;
        private Node next;
        public T Data
        {
            get { return data; }
            set { this.data = value; }
        }
        public Node Next
        {
            get { return next; }
            set { next = value; }
        }
        public Node ReverseList(Node head)
        {
            if (head.Next == null || head.Next.Next == null)
            {
                return head;   /*链表为空或只有一个元素则直接返回*/
            }
            Node t = null,
                     p = head.Next,
                     q = head.Next.Next;
            while (q != null)
            {
                t = q.Next;
                q.Next = p;
                p = q;
                q = t;
            }
            /*此时q指向原始链表最后一个元素,也是逆转后的链表的表头元素*/
            head.Next.Next = null;  /*设置链表尾*/
            head.Next = p;           /*调整链表头*/
            return head;
        }
        public override string ToString()
        {
            string result = string.Empty ;
            Node p = this.Next;
            while (p != null)
            {
                result += string.Format("{0}t", p.Data);
                p = p.Next;
            }
            return result;
        }
    }

怎么样才是好的程序员(转)

要判断一个程序员是不是好的程序员,主要看他写的代码,因为程序员最重要的事是写代码。
即便不去理解代码的意图,只要看一眼,好的程序员写的代码与差的程序员写的代码基本上就可以看出来。好的程序员写的代码,整洁而规范,视觉上自然有一种美感。空白错落有致,注释恰到好处,命名和排版遵守统一的规范。差的程序员写的代码则经常出现过长的函数,前后不一致的命名方式和排版,过深的嵌套结构,非常复杂的表达式,随处可见的数字等毛病。
再去粗粗阅读,对好的程序员还是差的程序员就会更有把握。好的程序员写的代码,有一种精心雕琢而成的一致性。好的程序员一致会遵守统一的命名方式,如camelCase,而差的程序员的变量命名时不时的就会偏离统一规范。好的程序员的代码中拼写错误几乎不可见,而差的程序员的拼写错误要多得多。好的程序员对于同一类动作,不会忽而用这个动词,忽而又用那个同义词,如add/insert混用。好的程序员采用一致的简写规则,差的程序员则时而不简写,时而简写。好的程序员会很注意名称中形容词与名词谁在前谁在后,而差的程序员没有规则,时而在前时而在后。好的程序员很少会写出大段大段的重复代码,差的程序员却经常搞不定重复代码,他们难以将重复的代码抽取出一个统一的概念进行重用。好的程序员对于对外的API会注重注释与代码的一致性,差的程序员经常注释中的参数名称与函数定义都不一致。好的程序员很少会留下被注释掉的或用#if 0括起的垃圾代码,他们意志坚决,代码有用就要,没用就不要,差的程序员则不一样,他们经常不确信一段代码是否真的需要,他们缺乏保持代码整洁的习惯,因此他们让垃圾代码留着。
如上,即便你不懂他所用的语言,不却关心程序的逻辑,对好的程序员还是差的程序员就能做到八九不离十的判断。程序的好坏几乎总是取决于它们是否“漂亮”,不“漂亮”而好的程序,除了C++ STL源码,我再也没见过(如果你稍仔细看,STL的源码虽然不够“漂亮”,但仍然满足这里提出的一致性原则)。而又好又“漂亮”的代码则随处可见,如Linux Kernel,InnoDB,JDK,JUnit等等。
如果再仔细阅读,就能更准确。好的程序员写的代码,好似浑然天成,简单而直白。函数通常较短小,函数的名称准确的反映函数要完成的工作。逻辑简单而自然,让你读的时候由衷的发出“啊,就应该是这样”的感叹,而差的程序员的代码经常让你发出“怎么是这样?这是再干什么呀?”的疑问。好的程序员会在紧要关头加以画龙点睛般的注释,差的程序员要么没注释,要么注释只是代码的重复,纯粹是废话,更差的是注释是错的,是误导。
好的程序员未必是“语言律师”,即那种非常清楚的了解语言的各个细节,在编程时到处使用的家伙。好的程序员也不常“炫技”,在代码中精心构造一些独具匠心的片断,他们偶而会,但大多数时候总是用直白的语言来表述。
从代码也可以看出一个程序员的团队协作精神。注意团队合作的程序员,会严格按照团队规范写代码,而风格与团队规范不一致的程序员则很可能欠缺团队精神。注意团队合作的程序员会注意给模块的对外接口加以重要的说明,如前置条件、后置条件、参数能否是NULL等等,不注意团队合作的程序员懒于处理这些细节。
好的程序员与差的程序员的生产力差别巨大,项目的周期越长,项目越复杂,项目对质量的要求越高,好的程序员的价值就越大。好的程序员与差的程序员,管理成本也差别巨大,好的程序员只需要与他共同确定设计,代码可以不看,差的程序员的代码经常需要经过多次review,且仍有可能达不到理想的质量。
要成为好的程序员,首先要树立要成为好的程序员的志向,再勤加练习,天长日久,就会越来越好,这些人不怕老。没有志向永远成不了好的程序员,这些人若不在老去之前成为经理就会变成废人。
通过两个小时的笔试和半个小时的面试对于判断程序员来说是不够的。通过笔试与面试,你可以判断一个程序员是否具备算法与数据结构等基础知识,可以判断他对编程语言的特性是否掌握,可以判断他对技术是否关注,然而要知道他能否真的能很好的完成工作,不写代码是不够的。
那些显得对技术充满热情的,未必是好的程序员。这些人可能非常乐意从事有新意的工作,但后续的编码、测试、调试、文案工作则可能让他们感到厌烦。他们可能会提出好的创意,但却经常不能够有始有终的将其完成。公司不需要多少这样的人。
因此招聘的方式需要改善。招聘是最重要的,因为进来后就难以出去,即便是试用。转正条件白纸黑字写的很清楚,只要合格就可以转正,要达到合格并不是很困难。今年部门里进了很多新人,并不是人人都很优秀,但确实也都合格,自然也应该转正。
改善招聘的方法,就是让他写程序,可以出两道题,一道让他写程序,一道让他重构一个已有的较长的程序,一天之内完成。假使可以考他半个月,那么重构是不太需要的,但一天的时间太短,通过重构可以考察阅读并理解代码,并通过重构“化腐朽为神奇”的能力。那些不愿意写别人的代码,不愿意接受别人的代码,经常要重来一遍的人是不理想的。
今年有两个人采用了类似的方法。有一位简历很优秀的人,做了两道编程题被拒了,有一位简历及面试一般的人,通过编程测试,录用了。我感觉比单纯的笔试与面试要准确。

apache2中多站点配置,二级域名配置

  1. 增加站点
    sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/mynewsite
    
  2. 配置站点
    sudo vi /etc/apache2/sites-available/mynewsite
    
    ServerAlias *.sheng00.com
    
  3. 开启站点
    sudo a2ensite mynewsite
    sudo service apache2 restart
    
  4. 关闭站点
    sudo a2dissite mynewsite
    sudo service apache2 restart
    

站点配置中,如果想配置二级域名的站点,ServerAlias 要写成二级域名,比如xx.sheng00.com

Android:通过Url打开App

Android支持通过Url打开App,比如下面的Url
scheme://host/datastring
要打开这样的Url,首先在配置文件AndroidManifest.xml里使用<data>添加一种App打开的格式,代码如下

<?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
  package=”com.sheng00.customuridemo”
  android:versionCode=”1″
  android:versionName=”1.0″ >
  <uses-sdk
    android:minSdkVersion=”9″
    android:targetSdkVersion=”17″ />
  <application
    android:allowBackup=”true”
    android:icon=”@drawable/ic_launcher”
    android:label=”@string/app_name”
    android:theme=”@style/AppTheme” >
    <activity
      android:name=”com.sheng00.customuridemo.MainActivity”
      android:label=”@string/app_name” >
      <intent-filter>
        <action android:name=”android.intent.action.MAIN” />
        <category android:name=”android.intent.category.LAUNCHER” />
      </intent-filter>
      <!– Open links like scheme://host/?… –>
      <intent-filter>
        <action android:name=”android.intent.action.VIEW” />
        <category android:name=”android.intent.category.DEFAULT” />
        <category android:name=”android.intent.category.BROWSABLE” />
        <data android:scheme=”scheme” android:host=”host” />
      </intent-filter>
    </activity>
  </application>
</manifest>

注意,第二个<intent-filter>中的data绑定了url 在页面中出现scheme://host/类似这样的链接,点击就可以直接打开app app中处理链接地址代码如下

package com.sheng00.customuridemo;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }
  @Override
  protected void onResume() {
    super.onResume();
    Intent intent = getIntent();
    if (intent != null) {
      String action = intent.getAction();
      String dataString = intent.getDataString();
      if(dataString!=null){
        TextView tv = (TextView) findViewById(R.id.tv);
        tv.append("n" + dataString);
      }
    }
  }
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }
}

运行效果
运行效果

源代码:https://github.com/shengoo/myandroidcode/tree/master/CustomUriDemo

苹果即将推出iRadio音乐流媒体服务

苹果在主要音乐团体的一系列处理后,推出其自己的音乐流媒体服务

与索尼音乐公司的交易意味着iPhone制造商现在有三组安排到位,扫清了道路,为它作出的一项重大周一公布。
该协议将载苹果的大肆宣传的“网络收音机”的服务,还设有音乐,环球音乐和华纳音乐,与现有服务,如Spotify和潘多拉的竞争。
iRadio服务预计将扩展的iTunes,将是一个由广告支持的免费服务,流音乐根据听者的偏好,根据他们现有的库。
苹果的音乐服务将用户现有的iTunes资料库的信息来预测他们可能会喜欢的其他音乐,唱片公司希望它也将鼓励人们要额外下载。
索尼报称耐致力于流媒体服务,并没有该标签将签署的iRadio时间为下周的全球开发者大会在旧金山,苹果有望推出该平台。黄奇帆周围的服务,去年以来已建立。谷歌推出了自己的音乐订阅服务“全通”上个月。
它可能还需要数周后,苹果公司宣布的iRadio平台准备向公众推出之前,建议。
苹果在音乐行业交易的谈判分别由埃迪,谁负责苹果的iTunes商店,App Store和iBookstore的,据说改进了早期的音乐公司提供。
主要音乐唱片抵制史蒂夫·乔布斯的iTunes音乐服务,并没有要签署新的音乐流媒体协议,可能会成为一个破坏性的先例数字音乐的计划。
环球音乐被认为是同意使用费为12.5美分,每100轨道流,广告收入的份额,一次性付款和最低保证金额。
上周末,华纳音乐的华纳Chappell的部门成为第一个音乐出版公司的iRadio同意交易。
苹果提供华纳Chappell的10PC广告收入的iRadio,这是双率最大的出版商赚取来自潘多拉。
苹果和索尼公司拒绝对此发表评论。

专业程序员必知的技巧:敲打代码

编写生产质量级别的代码似乎是一个明摆着的目标,但计算机行业却费了不少时日才弄明白正确的实现之道。例如,Windows 95曾经有个Bug会让操作系统在连续运行49.7天之后挂起—但是该Bug花了4年时间才暴露,有Bug这件事本身并不特别让人觉得惊讶,时间之所以这么长是因为其他Bug在不到49.7天的时候就让Windows 95崩溃了。

通往高质量代码的道路有两条,你可以二选一:一开始就内置质量,或者事后再敲打它。前者需要你在日复一日的编码中遵循众多戒律;后者则要求大量测试,到头来,在自以为完工之后,你会发现还有很多工作要做。
事后敲打(beat-it-in-afterward)是常见的工作方式,行业占统治地位的瀑布开发方法就是这样:规格说明、设计、构建、测试。测试是最后的步骤。产品来到测试部门,很快就崩溃了。于是,又回到工程部门,修复Bug。接着,把另一版提交给测试部门,又由于其他原因崩溃。就这样,来来回回,许多月(甚至是数年)流逝。
在程序员们深入具体实践之前,我们会从技巧1——敲打代码开始,帮你建立正确的思维方式。
你可能认为编写可靠代码是再明显不过的工作要求了。招工广告上不可能写:“急聘:具备良好工作态度、团队合作精神和桌上足球技巧的程序员。有则更佳:会编写可靠的代码。”可有问题的程序还是有这么多,怎么回事?
在深入探讨保证代码质量的日常实践之前,让我们先讨论“编写可靠代码”的含义。它不仅仅是一份实践清单,它还是一种思维方式。在把产品交到客户手中之前,你必须敲打自己的代码和整个产品。
客户终究敲打你的产品,以一种你不曾预料到的方式使用它。他们用它的时间会很长,而且会在你没有测试过的环境里用它。你必须考虑的问题是:打算让客户发现多少Bug?
你现在对代码敲打的次数越多,在交到客户手中之前,能清除掉的Bug就越多,留给客户的Bug就越少。
质量保证的形式
1.代码评审
保证代码质量最简单的方法就是让另一个程序员去读它。别出心裁的评审过程并没有必要,而且就连结对编程也算是一种形式的实时代码评审。团队将利用代码评审捕获Bug,贯彻编程风格和标准,同时在团队成员间传播知识。我们将在“技巧8:代码评审要早且多”中讨论代码评审。
2.单元测试
在你一个类接着一个类、一个方法接着一个方法地构建应用的业务逻辑时,验证代码的最佳方式就是单元测试。这种内部零件级的测试被设计用来对逻辑的各部分单独验证。
3.接受测试
单元测试立足于由内而外地审视产品,接受测试则被设计成模拟真实世界的用户,代表他们与系统交互。理想状况下,它们是自动执行的,而且以某种叙述式的风格书写出来。例如,某银行自动柜员机应用会有类似这样的接受故事:若我的活期存款为0,当我在ATM的“活期存款”中选择“取款”时,那么我应该看到“对不起,今天的晚餐吃泡面吧。”
它不像莎翁著作那样文采飞扬,但这些测试操练了整个系统:从用户界面一直到业务逻辑。无论它们是自动执行的,还是人工执行的,你的公司需要知道—在任何客户使用它之前—所有系统组件正在像预期的那样协调工作。
4.负载测试
负载测试将产品置于真实的压力条件下,然后度量它的响应。例如,某网站可能需要在数据库有100万条记录的条件下在100毫秒内展示指定页面。这些测试将揭示正确但不恰当的行为,如需要线性伸缩但却以指数级别伸缩的代码。
5.定向探索测试
接受测试覆盖了产品的所有指定行为,它可能来自于产品需求文档或会议。但程序员通常还是有办法使之崩溃—总有些黑暗角落被规格说明疏忽掉。定向探索测试就是要将这些边界情况挖出来。
这种测试通常是人工执行的,可能是程序员自己,用于探索和发现问题。但最初探索之后,任何有用的测试就会被加到接受测试套件之中。
该测试有一个专业化的变种,如安全审计。在这些情况下,专业测试人员会利用他们的领域知识(可能也包括代码评审)来指导他们的测试。
6.机构测试
硬件产品需要不同的机构认证:FCC度量电磁辐射,确保产品不会导致无线电干扰;美国保险商实验室(UL)检查当你将产品置于火上或舔电池电极时会发生什么。这些测试都在新产品发布之前进行,每次硬件变化都会影响认证。
7.环境测试
硬件产品的运行温度和湿度也需要在推至极限时测试。这些测试是用环境室来完成的,它可以同时控制这两个因素;当产品在其间运行时,它会经历所有四种极限条件。
8.兼容性测试
一旦产品需要跟其他产品进行互操作(如某字处理程序需要跟其他字处理程序交换文档),这些兼容性的论断就需要定期验证。它们可能会访问一组已保存的文档,也可能会实时地将你的产品连接到其他产品上。
9.耐久性测试
你会注意到这里提到的大多数测试都是尽量频繁且快速地运行。可有些Bug只会在一段时间的使用之后现身。前面提到的49.7天的Bug很好说明了这一点—它源于每毫秒递增的32位计数器,在49.7天之后,它会从最大值反转成0。测试若不持续运行上一会儿,你就无法发现类似Bug。
10.Beta测试
产品在这一阶段被送到了真实客户手中—他们知道自己要参加测试,并同意发现问题时提交报告。Beta测试的目的就在于我们在本技巧一开始讨论的:Beta测试者将以你意想不到的方式使用产品,试用它一段时间,并在你没有测试过的环境中测试产品。
11.运行中测试
公司可能会在产品上市之后继续测试。尤其是硬件产品,如偶尔从制造线上拔掉一个单元并证明制造线能工作正常是一种很有用的方法。这些运行中测试的设计目的就是为了捕获因零件或装配过程中的变化而导致的问题。
实践 VS 思维方式
你的团队可能采用类似“所有代码都必须有单元测试”或“所有代码必须先评审后检入(check in)”的实践。但这些实践没有一个能保证代码坚若磐石。想想若公司根本就没有采用一个质量实践,这种状况下该怎么做,即你将如何敲打代码以保证它的可靠性?
这是在继续深入之前你需要建立的思维方式。提交可靠的代码。质量实践只是达到目的的一种手段—最终的裁判是客户手中产品的可靠性。你想让你的名字跟市面上满是Bug的垃圾产品挂钩吗?不,当然不想。
行动指南
在上述所有形式的测试中,你的公司采用了哪些?在源代码中寻找单元测试,向测试部门询问接受测试计划,问问Beta测试是如何进行的以及向哪个部门提交反馈。再问下资深工程师:这是否足以保证客户有一个平滑的体验?
在定向探索测试上多花些时间,哪怕你的“方向”有点儿模糊。实际用一下产品,看看你是否可以让它崩溃。如果可以,那就相应地记下Bug报告。
Josh Carter,资深软件设计师,具有超过20年编程行业从业经验。热衷于编程和追逐前沿技术,但同时谨记史蒂夫?乔布斯的箴言“真正的艺术家能让产品面市”。他还涉足工程管理领域,曾经主管大型企业软件开发团队。目前已出版多本关于计算机软件的技术书籍,同时他还在主流计算机杂志的技术专栏发表文章。

作者Josh Carter,资深软件设计师,具有超过20年编程行业从业经验。热衷于编程和追逐前沿技术,但同时谨记史蒂夫?乔布斯的箴言“真正的艺术家能让产品面市”。他还涉足工程管理领域,曾经主管大型企业软件开发团队。目前已出版多本关于计算机软件的技术书籍,同时他还在主流计算机杂志的技术专栏发表文章。

百度诉360抄袭索赔50万

导语:百度与360是宿敌了,在360推出搜索后,二者矛盾日渐尖锐,二者对簿公堂,明争暗斗升级。前一阵,百度公司向北京市第一中级人民法院提起360不正当竞争诉讼和侵犯商标的诉讼。北京一中院判决360败诉,要求360停止不正当竞争行为、连续15日在首页道歉声明,赔偿损失45万元;近日,百度诉360抄袭索赔50万,目前,此案正在进一步审理中。

京华时报讯(记者裴晓兰)记者昨天获悉,北京百度网讯科技有限公司认为北京奇虎科技有限公司经营的360搜索网站,抄袭了百度站长平台的文档内容和格式,现已诉至北京西城法院要求索赔50万元。

百度诉称,百度站长平台于2011年9月16日在百度网站正式上线,其中百度站长平台帮助文档、百度sitemap工具帮助文档是公司创作的,旨在帮助广大第三方网站经营者创建和提交sitemap数据给百度站长平台的参考信息,具有独创性,原告依法对上述两个文档作品享有著作权。

2013年1月24日,北京奇虎科技有限公司经营的360搜索网站正式上线,在该平台使用帮助页面中,站长平台栏目项下的sitemap提交文档中,抄袭了百度站长平台帮助对应文档、百度sitemap工具帮助文档的文字内容和格式。

原告认为,奇虎公司未经许可、授权,抄袭其创作的文档作品并通过信息网络向公众传播,构成了对原告著作权的侵权,由于原被告双方存在同业竞争,被告的侵权行为给原告造成了巨大经济损失。原告起诉要求被告停止侵权,刊登声明公开赔礼道歉、消除影响并赔偿经济损失50万元。

目前,此案正在进一步审理中。

苹果未来将在流媒体服务中插入音频广告

消息称,苹果将在其即将推出的音乐流媒体服务中插入音频广告。这样一来苹果流媒体的商业模式将更类似于老牌音乐流媒体 Pandora,为用户提供个性化音乐广播,但不允许用户搜索特定某一首音乐,并在音乐广播中插入音频广告,广告收益与音乐公司分成。音乐公司从 Pandora 广告收益中得到的分成是 4%,从苹果流媒体广告收益中得到的分成将会在 10% 左右。由于苹果在技术和用户基础方面的优势,苹果的流媒体广告将会比 Pandora 更具针对性。Pandora 依赖于用户注册信息中的性别、位置信息以及用户的听音乐习惯来为用户派发广告。苹果判断个性化广告的数据更加精确且丰富,比如苹果可以通过手机定位得到位置信息,可以从用户 iTunes 购买历史判定用户消费习惯。
传苹果将在下周 WWDC 上推出其音乐流媒体服务。