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

Category Archives: Backend

SQL server的一道入门面试题背后的思考

  最近看到一个SQL Server的小例子,发现完全可以作为SQL server的一道入门面试题。题目如下: 例:有一合同表Contract Id Name Total buget 1 合同名称 100  102,22 2 合同名称2 300 ,102,22, 3 合同名称3 200  103,23, 要求:用SQL语句更新表的buget字段,如果前后没有”,”要加上”,”(即一个英文逗号)。(10分) 创建表数据: View Code use Testdb2 go IF NOT OBJECT_ID(‘[Contract]‘) ISNULL DROPTABLE [Contract] GO Createtable [Contract] (ID intprimarykey identity(1,1) ,[Name] nvarchar(50) null ,Total floatnull ,buget Nvarchar(500) null ) go insertinto [Contract] select‘合同名称’,  100,’102,22′ unionall select‘合同名称2′, 300,‘,102,22,’ unionall select‘合同名称3′, 300,’101,23,’  分析:这道题乍看很简单,由于肯定用到Replace,所以很自然的结合left,right,从而得到以下语句 方法一: update [Contract] set buget=‘,’+buget whereleft(buget,1)=‘,’ update [Contract] set buget=buget+‘,’whereright(buget,1)=‘,’ 如果能写成一个 SQL语句,可以加1分。 update [Contract] set buget=(casewhen (left(buget,1)!=‘,’andright   (buget,1)!=‘,’) then‘,’+buget+‘,’ whenleft(buget,1)!=‘,’then‘,’+buget whenright(buget,1)!=‘,’then  buget+‘,’ else buget end) 如果能从字符串的开关和结尾这个思路出发,结合Reverse,可以提到如下方法: 方法二: update [Contract] set buget=‘,’+buget where charindex(‘,’,buget)<>1 update [Contract] set buget=buget+‘,’where charindex(‘,’,reverse(buget))<>1 该方法,主要涉及charindex函数和reverse函数。 说实话,我当时就这两种思路,这也是SQL中常见的基本用法。但出人意料的第三种方法出现了。 方法三: UPDATE [contract] SET Buget = ‘,’+Buget+‘,’ UPDATE [contract] SET Buget = REPLACE(Buget,‘,,’,‘,’) 解析:该方法最主要的亮点不在于语法的精妙,而在于其思路的异于常规。先给两边补上逗号,再替换双逗号为单逗号。这在实际编程中确实难能可贵。换句话说,如果没有事先思考过的话,这反映了解题者反应敏捷,思路开放。因此,至少可以再加3分。 当然,此语句其实还是有bug,比如如果原bug字段中间有两个逗号,那么在Replace时就会更新掉不应该更新的内容。不过,稍加修正,限定replace的范围即可, 受此思路启发,可以引申得到以下类似方法: 方法四: UPDATE [contract] SET Buget = substring(BuGet,2,len(BuGet)-1) wherecharindex(‘,’,buget)=1 UPDATE [contract] SET Buget = substring(BuGet,1,len(BuGet)-1) wherecharindex(‘,’,reverse(buget))=1 UPDATE [contract] SET BuGet = ‘,’+BuGet+‘,’ 该方法是先去掉两边的逗号,再给每条记录加上逗号,比起方法三来,稍显繁琐,这也反衬了方法三的巧妙。 当然,也可以结合前面的思路稍作修正,这里就不再赘述,请读者自己思考。 感悟:释迦牟尼说过“人生需要经过六项修炼:布施、持戒、忍辱、精进、禅定、智慧。”,SQL编程,或C#、Java,甚至Javascrip的某个领域也是如此。技术是死的,思路是鲜活的,有时候,思路能轻易地突破技术很难实现的死角。到了一定程度时,会发现潜意识里已经被惯性思维塞满,而无法接受新鲜思维方式或思路,如果一段时间内持续如此,那么,我们应该警醒,把自己的头脑放空,把自己置于一个初学者的地位,重新开始“精进”的修炼! 原文链接:http://www.cnblogs.com/downmoon/archive/2011/03/02/1968615.html  

龙生   19 Feb 2013
View Details

面试题:一道冒泡算法笔试题的演进史

  给定N个整数,请使用冒泡算法按照从大到小的顺序排序 1.可对N个整数的某一段(连续的M整数)排序  2.要求具有一定的可测试性 3.C#语言  ——————-- 思路: 1.冒泡算法 2.针对部分排序 3.可测试性 先上一段最简单的代码实现冒泡算法--这里错误的使用了选择排序,请参看改进版本的修正 int[] list= new int[] {1, 2, 3, 4, 5};         for (int i=0;i<list.Length;i++)             for (int j=i+1;j<list.Length;j++)             {                                 if (list[i]<list[j])                 {                     int tmp=list[i];                     list[i]=list[j];                     list[j]=tmp;                 }             }         for (int i=0;i<list.Length;i++)             System.Console.Write("{0}\t",list[i]);         System.Console.WriteLine(""); 观看上述代码,有如下发现 1)行1,主要进行数据的初始化工作,准备数据  2)行2-11,主要实现冒泡排序算法 3)行12-14,主要是显示结果 4)行1-14,包含算法实现,调用,实现和使用糅合在一起 第一次改进: 1)数据初始化部分,其实属于调用部分,此时用的是数组,扩展性较差,这里改成List<int>,并将此步重构成函数 //初始化N个数据void Init(List<int> list,int count){    System.Random a=new Random();    for (int i=0;i<count;i++)        list.Add(a.Next(100));} 这里初始化数据,主要是减少人工干预,自动产生测试数据,实际生产过程中,是需要按照实际情况,选取一些比较特殊的数据作为测试数据的. 2)冒泡排序算法实现过程部分,也可以重构成函数 //实现冒泡算法——这里错误的使用了选择排序     void Bubble(List<int> list)     {                 for (int i=0;i<list.Count;i++)             for (int j=i+1;j<list.Count;j++)             {                                 if (list[i]<list[j])                 {                     int tmp=list[i];                     list[i]=list[j];                     list[j]=tmp;                 }             }         } 正确的冒泡排序为 void Bubble(List<int> list)     {         bool bFlag=false;         for (int i=0;i<list.Count;i++)         {             bFlag=false;             for(int j=list.Count-1-1 ;j>i-1;j--)             {                 if (list[j]<list[j+1])                 {                     int tmp=list[j+1];                     list[j+1]=list[j];                     list[j]=tmp;                     bFlag=true;                 }             }             if (!bFlag) break;         }     }     将排序的代码,重构成函数,使得算法可以非常容易进行测试,只需要将精心设计的测试数据传给函数,就可以了 3)显示结果,也是重构成函数 //显示结果 void Print(List<int> list) {     for (int i=0;i<list.Count;i++)         System.Console.Write("{0}\t",list[i]);     System.Console.WriteLine(""); } 4)最终调用过程 public static void Main(){    List<int> list=new List<int>();    //产生测试数据    Init(list,8);        //打印测试数据    Print(list);        //按照从大到小的顺序排序    Bubble(list);    //打印排序后的结果    Print(list);    }  第二次改进: 第一次改进中,基本解决冒泡算法和可测试性的问题,但是还有一个重要问题没有解决,就是针对N个整数中的某一段连续M个数据进行排序,所以这次的改进主要集中在<冒泡排序算法实现>函数的改进 很明显,要实现这个功能,只需要,在 Bubble这个函数增加两个参数,标识出M的上下限,Bubble变成如下形式

新的实现(注意,这里我的冒泡算法的实现是不对的,我用的是选择排序,经过一个园子里的兄弟提醒,我查过资料,发现的确用错了) 选择排序(Selection sort) 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。 void Bubble(List<int> list,int low,int high){    int iHigh= list.Count<high+1? list.Count : high+1 ;    int iLow=low<0? 0 :low ;    //System.Console.WriteLine("{0}\t{1}",iLow,iHigh);    for (int i=iLow;i<iHigh;i++)        for (int j=i+1;j<iHigh;j++)        {                            if (list[i]<list[j])//比较不一定相邻            {                int tmp=list[i];                list[i]=list[j];                list[j]=tmp;            }        }    } 下面是更正后的冒泡排序代码 冒泡排序(BubbleSort) 依次比较相邻的两个数,将小数放在前面,大数放在后面。 static void Bubble(List<int> list,int low,int high)     {         int iHigh= list.Count<high+1? list.Count : high+1 ;         int iLow=low<0? 0 :low ;                  bool bFlag=false;         for (int i=iLow;i<iHigh;i++)         {             bFlag=false;             for(int j=iHigh-1-1 ;j>i-1;j--)             {                 if (list[j]<list[j+1])//比较相邻                 {                     int tmp=list[j+1];                     list[j+1]=list[j];                     list[j]=tmp;                     bFlag=true;                 }             }             if (!bFlag) break;         }         }   并提供一个重载函数

调用: public static void Main() {     List<int> list=new List<int>();     //产生测试数据     Init(list,8);         //打印测试数据     Print(list);         //按照从大到小的顺序排序,针对序号2-5的之间的数据     Bubble(list,2,5);     //打印排序后的结果     Print(list);  } 至此,题目要求的目的全部达到,不过还是少了点什么,下面进行第三次改进 第三次改进: 第一次改进和第二次改进的结果,还是采用面向过程的方法,第三次改进侧重与面向对象的方法,就是封装 三个主要函数中都有List<int> list参数,这个是主要数据,我们用类来封装它,如下给出完整代码 public class BubbleSort {     List<int> _list;     public BubbleSort()     {         _list=new List<int>();     }     public BubbleSort(List<int> list)     {         _list=list;     }          public void Sort()     {                 Sort(    _list,0,_list.Count-1);             }         public void Sort(int low,int high)     {         Sort(    _list,low,high);     }     //实现冒泡算法--这里错误使用选择排序,请替换为第二次改进中的正确实现      public void Sort(List<int> list,int low,int high)     {         //int iHigh= list.Count<low+count? list.Count : high ;         int iHigh= list.Count<high+1? list.Count : high+1 ;         int iLow=low<0? 0 :low ;         //System.Console.WriteLine("{0}\t{1}",iLow,iHigh);         for    (int i=iLow;i<iHigh;i++)             for    (int j=i+1;j<iHigh;j++)             {                                 if (list[i]<list[j])                 {                     int tmp=list[i];                     list[i]=list[j];                     list[j]=tmp;                 }             }         }                  //初始化N个数据     public void Init(int count)     {         _list.Clear();         System.Random a=new Random();         for    (int i=0;i<count;i++)             _list.Add(a.Next(100));     }     //显示结果     public  void Print(List<int> list)     {         Print(list,0,list.Count-1,true);     }     public  void Print(List<int> list,int low,int high,bool IsNewLine)     {         int iHigh= list.Count<high+1? list.Count : high+1 ;         int iLow=low<0? 0 :low ;                  for    (int i=iLow;i<iHigh;i++)             System.Console.Write("{0}\t",list[i]);         if (IsNewLine)             System.Console.WriteLine("");     }     public void Print(int low,int high,bool IsNewLine)     {         Print(_list,low,high,IsNewLine);     }     //将排序的M个数据用红色显示     public void Print(int low,int high)     {         Print(0,low-1,false);         System.Console.ForegroundColor=ConsoleColor.Red;         Print(low,high,false);                 System.Console.ResetColor();         Print(high+1,_list.Count,true);     }          public void Print()     {         Print(_list);     }     //for test     public void Test()     {         //产生测试数据         Init(10);             //打印测试数据         Print();             //按照从大到小的顺序排序         int[] iLowHigh=new int[]{4,7};         Sort(iLowHigh[0],iLowHigh[1]);         //Sort(-1,8);         //Sort(0,18);         //Sort(-1,18);         //打印排序后的结果         //Print();          Print(iLowHigh[0],iLowHigh[1]);          } } 调用代码:

 

龙生   20 Nov 2012
View Details

iis 6.0 http转向 https(很简单)

  在网上找了好多资料都没找到,无意当中找的了一片文章(国外的网站)帮我解决了问题,因此想与大家分享。 首先错误信息(见图一): 图一 解决方法: 一、验证SSL需要选中的网站(见图二) 1、首先打开所要修改的网站然后右击选择“属性” 2、选择“目录安全性”-->在安全通信中选择“编辑” 3、选择“要求安全通信(SSL)”后点击“确定”。   图二 二、创建一个HttpRedirect.htm 文件保存到“C:\InetPub” HttpRedirect.htm中的代码:

  三、用HttpRedirect.htm文件替换403文件(见图三) 1、打开你的网站右击选择“属性” 2、选择“自定义错误”点击编辑 3、在“文件”中添加HttpRedirect.htm文件(路径为:C:\Inetpub\HttpRedirect.htm) 图三 四、测试 输入的网址:http://会自动跳转到https://   参考网址: http://www.jppinto.com/2009/01/automatically-redirect-http-requests-to-https-on-iis-6/   转自:http://www.cnblogs.com/nanyaxu/archive/2012/11/19/2777507.html

龙生   20 Nov 2012
View Details

Windows7安装OpenSSH

OpenSSH很老了,所以… 最开始只是因为openSSH启动不了,才用的MobaSSH,它配置简单兼容性好,缺点就是偷偷的建立了一个账户,让我感觉很不爽。所以决定把OpenSSH配置好。经过检查,发现OpenSSH安装的时候已经把环境变量添加好了,因此在命令行窗口是可以直接输入执行 ssh chmod等等命令的,但是当我输入ls的时候,提示缺少cygintl-2.dll,所以这个提醒了我更换检索词。最终解决这个问题。 下载地址: http://sourceforge.net/projects/sshwindows/files/OpenSSH for Windows – Release/3.8p1-1 20040709 Build/setupssh381-20040709.zip/download 1. 默认安装 2. 补上cygintl-2.dll和cygwin1.dll 下载:http://samanthahalfon.net/resources/cygwin_includes.zip 将它们复制到c:\Program Files (x86)\OpenSSH\bin目录下,如果提示覆盖,则覆盖之,不然进行下面操作,会提示 不能启动opensshd服务 OpenSSH Error 1067:The process terminated unexpectedly 系统出错,进程意外终止 3. 开始安装 cd "c:\Program Files (x86)\OpenSSH\bin" mkgroup -l >> ..\etc\group 生成一个group mkpasswd -l [-u <username>] >> ..\etc\passwd 比如: mkpasswd -l -u mxio >> ..\etc\passwd 这样就生成用户名mxio的passwd文件, 它调用的是系统用户名和密码 cd ..\..\etc 给权限..\bin\chown mxio * ..\bin\chmod 600 * 4. 启动opensshd服务 不出问题会提示启动成功 net start opensshd 5. 测试连接 ssh mxio@localhost

龙生   19 Nov 2012
View Details

WPF:在异步操作中使用CommandManager手动更新Command执行状态(转载)

WPF判断命令(Command)是否能够执行是通过ICommand.CanExecute事件,在实际程序中路由命令一般是通过CommandBinding来使命令得到实际操作代码,但是这个CanExecute事件的调用是由WPF控制的,有些时候,比如命令执行后进行一些异步耗时操作,操作完成后会影响CanExecute事件结果,但是WPF不会立即做出反应,那么这个时侯就需要手动调用CommandManager.InvalidateRequerySuggested对命令系统进行一次刷新。 比如下面这个小程序 <Window.CommandBindings> <CommandBinding Command="New" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed" /> </Window.CommandBindings> <StackPanel> <Button Command="New">执行工作</Button> <TextBlock Name="tbl" Text="等待执行"></TextBlock> </StackPanel>     // // 事件执行代码 //   privatevoid CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute =!finished; }   privatevoid CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) { System.Threading.ThreadPool.QueueUserWorkItem(dowork);   }   bool finished =false; void dowork(object obj) { updateUI("开始工作"); System.Threading.Thread.Sleep(1000); updateUI("工作结束"); finished =true; }   void updateUI(string msg) { Dispatcher.BeginInvoke((Action)(() => tbl.Text = msg)); }   程序按钮点击后下面文字显示“工作结束”,这时按钮理应是禁用的(因为此时CanExecute结果是false),但实际上按钮没有被禁用,只有界面发生改变后(如焦点,按键变化,或者按钮再次被点击),按钮才会被禁用,因为此时WPF才调用相应的CanExecute事件。   手动调用CommandManager.InvalidateRequerySuggested就可以解决问题,注意这个函数只有在UI主线程下调用才会起作用。 void dowork(object obj) { updateUI("开始工作"); System.Threading.Thread.Sleep(1000); updateUI("工作结束"); finished =true; //手动更新 updateCommand(); }   void updateCommand() { Dispatcher.BeginInvoke((Action)(() […]

龙生   26 Oct 2012
View Details

WPF Timer替代者

做过WinForm开发的都会郁闷WPF竟然没有Timer。 今天想在WPF中用Timer可是发现WPF没有Timer类,找了半天发现新增了一个 DispatcherTimer确实好用和WinForm中Timer用法相似。 —————————————————————————————————————————-- 引:银光中国 在 WPF 中不再有类似 WinForm 中的 Timer 控件,因此,需要使用 DispatcherTimer 类来实现类似 Timer 的定时执行事件,该事件使用委托方式实现。DispatcherTimer 类 在 System.Windows.Threading 下,需要 using System.Windows.Threading 命名空间。    MSDN事例: 创建了名为 dispatcherTimer 的 DispatcherTimer 对象。 事件处理程序 dispatcherTimer_Tick 被添加到 dispatcherTimer 的 Tick 事件中。 使用 TimeSpan 对象将 Interval 设置为 1 秒,并启动了计时器。  

  Tick 事件处理程序将更新显示当前秒数的 Label,并且它将对 CommandManager 调用 InvalidateRequerySuggested。  

转自:http://www.cnblogs.com/midcn/archive/2011/03/18/1987928.html

龙生   26 Oct 2012
View Details

C#操作注册服务卸载服务启动服务停止服务

   

龙生   25 Oct 2012
View Details

线程间操作无效: 从不是创建控件“label1”的线程访问它

Thread thread=null; //定义线程  //开始线程   private void button1_Click(object sender, EventArgs e)   {   thread = new Thread(new ThreadStart(StartThread));   thread.Start();//开始线程   }   private void StartThread()   {   int i = 0;   while (true)   {   this.label1.Text = i.ToString(); //此处报错   i++;   }   }   //结束线程   private void button4_Click(object sender, EventArgs e)   {   thread.Abort();   }   问题:当我们运行的时候会出现错误:"线程间操作无效: 从不是创建控件“label1”的线程访问它。" 解决方案:在程序运行的时候增加一句话,如下: public Form1() {InitializeComponent();Control.CheckForIllegalCrossThreadCalls = false; //这是增加的一句话 }  缺点:将UI传给了子线程,违背了弱耦合、封装的思想。子线程去更新UI的状态,如果有多个不同主线程要获取子线程状态,怎么办?   

龙生   22 Oct 2012
View Details

C#进制转换

 

龙生   15 Oct 2012
View Details

详解在IIS中配置并运行WCF服务

  【IT168 技术文档】WCF是Microsoft为构建面向服务的应用提供的分布式通信编程框架,是.NET Framework 3.5的重要组成部分。使用该框架,开发人员可以构建跨平台、安全、可靠和支持事务处理的企业级互联应用解决方案。  在IIS中运行服务     之前我们让Derivatives Calculator服务在一个.NET可执行文件中运行,在这个练习中,我们将让服务在IIS中运行。     利用IIS作为宿主程序来运行WCF服务通常有许多好处。     ·将项目构建到\bin目录中     为了方便部署,我们需要对服务项目进行配置,让它编译到一个bin目录中。     1. 在Solution Explorer中右键单击DerivativesCalculatorService项目并选择Properties菜单项。     2. 在Project designer中,单击Build选项卡。     3. 将Output path从bin\Debug\改为bin\,如图所示。   Project designer中经过调整的Output path属性     4. 选择File | Save All菜单项。     5. 选择File | Close菜单项来关闭Project designer。     现在,在构建服务时产生的所有文件都会被输出到\bin目录中。     ·添加一个.svc文件     为了让WCF服务能够在IIS中运行,我们需要用一种特殊的内容文件(.svc文件)表示它。这种模型和ASMX页面在IIS中的表示方法类似。.svc文件包含一个WCF专用的处理指示符(@ServiceHost),这个指示符告诉WCF运行库在收到消息时激活服务。     1. 在Solution Explorer中右键单击DerivativesCalculatorService项目并选择Add | New Item菜单项。     2. 在Add New Item对话框中,选择Text File模板。 wordend 相关阅读:     3. 在Name文本框中输入Service.svc。     4. Add New Item对话框看起来应该如图所示。   添加一个svc文件     5. 单击Add按钮。     6. 在Service.svc文件中添加下面这行语句。 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/ <%@ServiceHost Service="DerivativesCalculatorService.Calculator" […]

龙生   15 Oct 2012
View Details
1 260 261 262 282