一切福田,不離方寸,從心而覓,感無不通。

Category Archives: Backend

在程序员的眼里,用户是这样使用他们开发的软件的

我曾经说过,程序员不是一般的人,是具有某种超能力的人。但问题是,程序员往往意识不到自己 的这种特异功能,在他们的眼里,会认为自己很普通,跟常人一样,所以,程序员能做到的事情,其他人——比如他们的客户/软件用户——也应该很容易做到。但 事实上,由于大部分人——绝大部分人(包括软件开发公司的客户/购买软件的用户)——都是电脑小白(对电脑知识/计算机知识/软件知识知之甚少的人)。一 个对于程序员来说很显而易见的软件操作,换成让用户来操作,就会出现各种各样奇怪的事情。这让程序员非常痛苦。 记得有一次,一个客户打电话给我,说他电脑桌面上的大e找不到了,我没听懂,什么大e找不到了?客户解释说:就是那个长的像大个儿的英文字母e的图标找不到了。我倒。终于明白了他指的是桌面上的IE浏览器的图标不见了。 还 有一次,有个客户提出一个需求,要求在页面上增加一个搜索功能,我问它,系统里有搜索功能,为什么还要在这个地方新增一个搜索功能,他说他要的不是那个搜 索,他要的是在这个页面上搜在某个关键词。经过进一步的沟通,我明白了,他要的是浏览器上的快捷键CTRL+F的功能。 因 为用户的这些特征,导致了程序员认为完美的程序,到了客户的手里,却变成极其难用的软件,投诉电话如乡下骂街的泼妇似的响个不停。而事后分析发现,根本原 因都是应为程序员高估了用户对软件的掌控能力,低估了自己对软件的创造能力,于是导致了他们看这些客户使用他们开发的软件时,都是那样一种可笑的行为,如 下图: 在程序员的眼里,用户是这样使用他们开发的软件的 如果是脾气暴躁的程序员,遇到这种情况,难免会对着客户发一顿牢骚,而且,程序员的脾气一般都不是很好,所以,通常跟客户沟通时,项目经理一般都是跟着一起,以免事态激化。 用户虽然给程序员带来很多麻烦,但其实程序员的所有荣耀感都来自客户,因为只有客户用得满意,程序员才会有成就感。比如像下面这几个客户在使用一个新款软件时显露出来的表情,足够让一个处在北京重度雾霾的下午的程序员也能露出笑容: 用户在使用一款新软件时的样子 程 序员虽然脾气不好,但他们都是为工作着想,不带任何个人恩怨。当开发软件有紧急任务时,他们都是任劳任怨的加班加点,当在已经发布的软件中出现了重大 bug时,他们都会深深在自责,会连夜赶制出紧急修复bug,如果不能在第一时间让用户满意,他们会茶不思、饭不想、觉不睡。即使在实在没有短期内完整的 补救措施的情况下,他们也会想出一些歪招,但也是行之有效的方案,让用户暂时度过难关。比如,下面就是一个紧急修复补丁: 紧急修复补丁 用 户应该体谅程序员。程序员的生活实际处在一种十分矛盾的状态中。编程不像其它行业,比如泥瓦匠砌砖,砌一层砖,墙就会高一次。但编程不一样,有时候一个程 序员写了一天的代码,急得满头大汗,但开发进度未必就有所进展,有时候甚至还会倒退。软件编程是一个亦虚亦实的世界,有时候你搞不清一段代码为什么好用, 有时候也会诧异由那样的代码构成的软件也能跑起来,正如下面这张图片中所示: 软件中有鬼 最后,说一下跟程序员打交道的一些注意事项。程序员因为整天和编程逻辑打交道,所以对因果关系特别敏感。如果你的话语的因果关系不是很明确,这会让他们感到疑惑,如果你的话语的因果关系不完整,这会让他们办错事。如果你的话中有if,最好后面用then做结束,或者用else给出选择,主语要明晰。如果不明晰,就会出现下图中出现的事故: 程序员是这样理解这个指示牌上的话的 如果你是一个程序员,你会理解我说的话。 from:http://www.oschina.net/news/53654/how-client-use-their-software

龙生   15 Jul 2014
View Details

不小心把所有的快捷方式lnk文件都设置成了用Word打开,该怎么改回来

龙生   10 Jul 2014
View Details

IIS6中配置FastCGI运行PHP

环境说明: 操作系统:使用windows 2003 server 32位系统,IIS6。 PHP版本:官方下载PHP 5.3.26 VC9 x86 Non Thread SafeZIP版本。 IIS6 FastCGI安装包:FastCGI for IIS x86版本。 PHP路径:C:\php-5.3.26\ FastCGI相关文件和路径 : C:\WINDOWS\system32\inetsrv\fcgiext.dll C:\WINDOWS\system32\inetsrv\fcgiext.ini 配置步骤: 解压PHP文件,修改目录名放到C盘。目录地址为C:\php-5.3.26\ 复制php.ini-production改名为php.ini,先参考PHP.ini参数说明修改。 并修改PHP对FastCGI支持: 安装下载的FastCGI for IIS工具,本文下载的文件名为fcgisetup_1.5_rtw_x86.msi。安装完成后无提示,直接打开文件C:\WINDOWS\system32\inetsrv\fcgiext.ini在最后[Types]后添加以下

检查IIS是否配置正确了FastCGI的调用。如下图: from:http://www.magicwinmail.com/setupiis/iis6fastcgi.html

龙生   04 Jul 2014
View Details

array_slice() 函数

定义和用法 array_slice() 函数在数组中根据条件取出一段值,并返回。 注释:如果数组有字符串键,所返回的数组将保留键名。(参见例子 4) 语法

参数 描述 array 必需。规定输入的数组。 offset 必需。数值。规定取出元素的开始位置。 如果是正数,则从前往后开始取,如果是负值,从后向前取 offset 绝对值。 length 可选。数值。规定被返回数组的长度。 如果 length 为正,则返回该数量的元素。 如果 length 为负,则序列将终止在距离数组末端这么远的地方。 如果省略,则序列将从 offset 开始直到 array 的末端。 preserve 可选。可能的值: true – 保留键 false – 默认 – 重置键 例子 1

输出:

例子 2 带有负的 offset 参数:

输出:

例子 3 preserve 参数设置为 true:

输出:

例子 4 带有字符串键:

输出:

龙生   30 Jun 2014
View Details

C#集合类Queue

队列(Queue)在程序设计中扮演着重要的角色,因为它可以模拟队列的数据操作。例 如,排队买票就是一个队列操作,新来的人排在后面,先来的人排在前面,并且买票请求 先被处理。为了模拟队列的操作,Queue在ArrayList的基础上加入了以下限制: · 元素采用先入先出机制(FIFO,First In First Out),即先进入队列的元素必须先离 开队列。最先进入的元素称为队头元素。 · 元素只能被添加到队尾(称为入队),不允许在中间的某个位置插入。也就是说, 不支持ArrayList中的Insert方法。 · 只有队头的元素才能被删除(称为出队),不允许直接对队列中的非队头元素进行 删除,从而保证FIFO机制。也就是说,不支持ArrayList中的Remove方法。 · 不允许直接对队列中非队头元素进行访问。也就是说,不支持ArrayList中的索引访 问,只允许遍历访问。 下面的实例展示了如何创建Queue对象,并向Queue对象中入队数据、出队数据、遍历 数据。 创建TestQueue类,在TestQueue.cs中输入如下代码: using System; using System.Collections.Generic; using System.Text; using System.Collections; namespace Chapter12 { class TestQueue { static void Print(Queue list) { Console.Write("队列内容:"); foreach (string str in list) System.Console.Write(str + " "); } static void Main(string[] args) { Queue list = new Queue(); //Add elements Console.WriteLine("输入字符串添加到队列(#号结束):"); string str; do { str = Console.ReadLine(); if (str == "#") break; else { list.Enqueue(str); } } while (true); TestQueue.Print(list); Console.WriteLine(); //Remove elements Console.WriteLine("出队字符串:"); while (list.Count != 0) […]

龙生   30 Jun 2014
View Details

volatile(C# 参考)

volatile 关键字指示一个字段可以由多个同时执行的线程修改。 声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。 这样可以确保该字段在任何时间呈现的都是最新的值。 volatile 修饰符通常用于由多个线程访问但不使用 lock 语句对访问进行序列化的字段。 volatile 关键字可应用于以下类型的字段: 引用类型。 指针类型(在不安全的上下文中)。 请注意,虽然指针本身可以是可变的,但是它指向的对象不能是可变的。 换句话说,您无法声明“指向可变对象的指针”。 类型,如 sbyte、byte、short、ushort、int、uint、char、float 和 bool。 具有以下基类型之一的枚举类型:byte、sbyte、short、ushort、int 或 uint。 已知为引用类型的泛型类型参数。 IntPtr 和 UIntPtr。 可变关键字仅可应用于类或结构字段。 不能将局部变量声明为 volatile。 示例 下面的示例说明如何将公共字段变量声明为 volatile。 C#

下面的示例演示如何创建辅助线程,并用它与主线程并行执行处理。 有关多线程处理的背景信息,请参见托管线程处理和线程处理(C# 和 Visual Basic)。 C#

龙生   30 Jun 2014
View Details

ManualResetEvent详解

1. 源码下载: 下载地址:http://files.cnblogs.com/tianzhiliang/ManualResetEventDemo.rar Demo: 2. ManualResetEvent详解 ManualResetEvent 允许线程通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态,此线程可被视为控制 ManualResetEvent。调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。一旦它被终止,ManualResetEvent 将保持终止状态(即对 WaitOne 的调用的线程将立即返回,并不阻塞),直到它被手动重置。可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false。   using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ManualResetEventDemo {     class MREDemo     {         private ManualResetEvent _mre;         public MREDemo()         {             this._mre = new ManualResetEvent(true);         }         public void CreateThreads()         {             Thread t1 = new Thread(new ThreadStart(Run));             t1.Start();             Thread t2 = new Thread(new ThreadStart(Run));             t2.Start();         }         public void Set()         {             this._mre.Set();         }         public void Reset()         {             this._mre.Reset();         }         private void Run()         {             string strThreadID = string.Empty;             try             {                 while (true)                 {                     // 阻塞当前线程                     this._mre.WaitOne();                     strThreadID = Thread.CurrentThread.ManagedThreadId.ToString();                     Console.WriteLine("Thread(" + strThreadID + ") is running…");                     Thread.Sleep(5000);                 } […]

龙生   30 Jun 2014
View Details

浅谈ThreadPool 线程池

相关概念:     线程池可以看做容纳线程的容器;     一个应用程序最多只能有一个线程池;     ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池;     每排入一个工作函数,就相当于请求创建一个线程; 线程池的作用: 线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率。 如果一个线程的时间非常长,就没必要用线程池了(不是不能作长时间操作,而是不宜。),况且我们还不能控制线程池中线程的开始、挂起、和中止。 什么时候使用ThreadPool? ThreadPool 示例一 : ThreadPool_1.cs using System; using System.Text; using System.Threading; namespace 多线程 { public class Example { public static void Main() { // Queue the task.             ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc)); Console.WriteLine("Main thread does some work, then sleeps."); Thread.Sleep(1000); Console.WriteLine("Main thread exits."); } static void ThreadProc(Object stateInfo) { // No state object was passed to QueueUserWorkItem, // so stateInfo is null.             Console.WriteLine("Hello from the thread pool."); } } } ThreadPool 示例二 : ThreadPool_2.cs using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace CS_Test { class ThreadPool_Demo { // 用于保存每个线程的计算结果         static int[] result = new int[10]; //注意:由于WaitCallback委托的声明带有参数, //      所以将被调用的Fun方法必须带有参数,即:Fun(object obj)。         static void Fun(object obj) { int n = (int)obj; //计算阶乘             int fac = 1; for (int i = 1; i <= n; i++) { fac *= i; } //保存结果             result[n] = fac; } static void Main(string[] args) { //向线程池中排入9个工作线程             for (int i = 1; i <= 9 ; i++) { //QueueUserWorkItem()方法:将工作任务排入线程池。                 ThreadPool.QueueUserWorkItem(new WaitCallback(Fun),i); // Fun 表示要执行的方法(与WaitCallback委托的声明必须一致)。 // i   为传递给Fun方法的参数(obj将接受)。             } //输出计算结果             for (int i = 1; i <= 9; i++) { Console.WriteLine("线程{0}: {0}! = {1}",i,result[i]); } } } } ThreadPool的作用: 参考来源: C#多线程学习(四) 多线程的自动管理(线程池)  [叩响C#之门]写给初学者:多线程系列( 十一)——线程池(ThreadPool) from:http://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html

龙生   30 Jun 2014
View Details

盘点前 10 名的免费跨浏览器测试工具

在多个平台上测试多种浏览器不但是很困难的 – 它几乎不可能的,因为没有那些好的测试工具。今天,我们就为大家提供很多涉及到跨浏览器测试的选择,并且告诉你那些“顶级的浏览器测试工具”,你应该使用哪一个。 这前10名的免费跨浏览器测试工具没有特定的顺序,因为他们对于任何特定的设备都同样有效。如果你手动去测试,可能既困难又耗费时间。因为你只能不断的安装更多的浏览器在你的设备上。 不要忘了在下面评论一下,留点反馈信息来改善我的博客质量额。如果你喜欢这篇文章,可能有兴趣看看其他相关的一些文章: 1. Browsera Browsera 可以测试和报告在您的网站上的跨浏览器布局的差异和脚本错误。 Browsera不同于其他跨浏览器测试服务。其他服务,如Litmus,Browsershots,BrowserLab,以及 SuperPreview,它们仅仅截取每一个特定的页面,你必须具体再分析才行。 官方网站 2. BrowserStack BrowserStack提供实时的,基于Web的浏览器测试的能力。可以即时访问每个桌面和移动浏览器(目前超过300个),具有在内部服务器进行本地测试的能力,并且提供一个安全的设置。 官方网站 3. Lunascape Lunascape是一款免费的三重引擎的浏览器。这意味着,你可以用三叉戟(IE),蛤蚧(火狐)和Webkit(Chrome和Safari)运行和测试一个新的网站,并且可以排在一起比较渲染引擎的效果。 官方网站 4. CrossBrowserTesting CrossBrowserTesting允许用户与超过100分辨率/浏览器/操作系统组合,测试他们的网站。它还为移动网络浏览器提供重要的支持,因为现在的互联网流量正从主要的桌面电脑用户向移动用户进行转移。 官方网站 5. Browserling Browserling和Testling作为我们部署测试流程的一部分,是基于我们公布的JavaScript库的PubNub JavaScript的用户群。这可以对快速测试所有的JavaScript环境提供一流的服务。 官方网站 6. Browsershots Browsershots可以为你设计的网页在不同的操作系统和浏览器中进行屏幕截图。这是一个免费开源的在线Web应用程序,开发人员提供了一个简单方法来测试在他们的网站在一个地方的浏览器兼容性。 官方网站 7. Litmus Litmus 提供跨浏览器网页测试,而且可以发送到你电子邮件进行预览。只要填写一个网址,它就会告诉你怎样适应当下流行的Web浏览器。 官方网站 8. Spoon Spoon 是一个很好的资源,它可以让你实时使用最流行的浏览器测试你的网站,包括Opera,火狐,Chrome和Safari等。 不过IE浏览器是不允许的,因为微软不提供许可。 官方网站 9. Sauce Labs Sauce Labs 提供了一个相当独特的跨浏览器测试体验。它并不是简单地把你的网站在不同的浏览器进行截图,而是室可以让你记录你网站的实时测试效果。 官方网站 10. Ghostlab Ghostlab提供同步测试滚动,点击,重新加载等,并形成信息输入到所有的连接设备,这意味着你可以测试整个用户体验,而不仅仅是一个简单的页面。 官方网站 总结:已经工作的时候很少用到专业的浏览器测试工具。大都是用个ieTest加上火狐和chrome就搞定一切了,多了也就是用个在线网页测试工具。一些细微的兼容性测试也是自己慢慢修改,费时又耗力。想要确保代码在各种主流浏览器的各个版本中都能正常工作,建议还是用一下上面提供的这些浏览器兼容性测试工具吧,应该能够事半功倍! 注:原文参考自:Top 10 Great Free Cross Browser Testing Tools 。本文由欲思原创编译,部分翻译删改或有误请谅解。 稿源:欲思博客 » 盘点前10名的免费跨浏览器测试工具 from:http://www.oschina.net/news/53246/free-cross-browser-testing-tools

龙生   30 Jun 2014
View Details

lucene.net 3.0.3、结合盘古分词进行搜索的小例子(分页功能)

//封装类   [csharp] view plaincopyprint? using System;   using System.Collections.Generic;   using System.Linq;   using System.Web;   using Lucene.Net.Analysis;   using Lucene.Net.Index;   using Lucene.Net.Documents;   using System.Reflection;   using Lucene.Net.QueryParsers;   using Lucene.Net.Search;   namespace SearchTest   {       /// <summary>       /// 盘古分词在lucene.net中的使用帮助类       /// 调用PanGuLuceneHelper.instance       /// </summary>       public class PanGuLuceneHelper       {           private PanGuLuceneHelper() { }             #region 单一实例           private static PanGuLuceneHelper _instance = null;           /// <summary>           /// 单一实例           /// </summary>           public static PanGuLuceneHelper instance           {               get               {                   if (_instance == null) _instance = new PanGuLuceneHelper();                   return _instance;               }           }           #endregion             #region 分词测试           /// <summary>           /// 分词测试           /// </summary>           /// <param name="keyword"></param>           /// <returns></returns>           public string Token(string keyword)           {               string ret = "";               System.IO.StringReader reader = new System.IO.StringReader(keyword);               Lucene.Net.Analysis.TokenStream ts = analyzer.TokenStream(keyword, reader);               bool hasNext = ts.IncrementToken();               Lucene.Net.Analysis.Tokenattributes.ITermAttribute ita;               while (hasNext)               {                   ita = ts.GetAttribute<Lucene.Net.Analysis.Tokenattributes.ITermAttribute>();                   ret += ita.Term + "|";                   hasNext = ts.IncrementToken();               }               ts.CloneAttributes();               reader.Close();               analyzer.Close();               return ret;           }           #endregion             #region 创建索引           /// <summary>           /// 创建索引           /// </summary>           /// <param name="datalist"></param>           /// <returns></returns>           public bool CreateIndex(List<MySearchUnit> datalist)           {               IndexWriter writer = null;               try               {                   writer = new IndexWriter(directory_luce, analyzer, false, IndexWriter.MaxFieldLength.LIMITED);//false表示追加(true表示删除之前的重新写入)               }               catch               {                   writer = new IndexWriter(directory_luce, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);//false表示追加(true表示删除之前的重新写入)               }               foreach (MySearchUnit data in datalist)               {                   CreateIndex(writer, data);               }               writer.Optimize();   […]

龙生   27 Jun 2014
View Details
1 221 222 223 280