6月 29

帮忙给别人做个单循环赛的赛程排序

实际上就是排列组合

这个本身没有什么复杂的,唯一有点意思的就是如何打散每个队员的比赛顺序

写了这么一个算法,记录一下

   

  private static string GetFullCode(int code, int length) {
           string result = code.ToString();
           int codeLength= result.Length;
           if (codeLength < length)
           {
               for (int index = 0; index <length- codeLength; index++)
               {
                   result = "0" + result;
               }
           }
           return result;
       }
       private static int GetMinIndex(List<UserInfo> userTable)
       {
           int minIndex = 0;
           int minCount = userTable[minIndex].Count;
           for (int index = 0; index < userTable.Count; index++)
           {
               if (minIndex != index)
               {
                   if (minCount > userTable[index].Count)
                   {
                       minIndex = index;
                       minCount = userTable[index].Count;
                   }
               }
           }
           return minIndex;
       }
       public class UserInfo
       {
           public string Code { get; set; }
           public int Count { get; set; }
           public override string ToString()
           {
               return string.Format("Code:{0},Count:{1}", this.Code, this.Count);
           }
       }

       static void Main(string[] args) {
           int userNumber = 9; //9只队伍
           int length = 3;  //队伍编码长度
           List<Tuple<string, string>> result = new List<Tuple<string, string>>();// 结果

           List<UserInfo> userTable = new List<UserInfo>();
           for (int i = 0; i < userNumber; i++)
           {
               userTable.Add(new UserInfo() { Code = GetFullCode(i + 1,length), Count = 0 });
           }
           int total = (userNumber – 1) * userNumber / 2;
           HashSet<string> hashSet = new HashSet<string>();
           for (int index = 0; index < total; index++)
           {
               while (true)
               {
                   int minIndex1 = GetMinIndex(userTable);
                   userTable[minIndex1].Count++;
                   int minIndex2 = GetMinIndex(userTable);
                   userTable[minIndex2].Count++;
                   if (!hashSet.Contains(userTable[minIndex1].Code + userTable[minIndex2].Code))
                   {
                       result.Add(new Tuple<string, string>(userTable[minIndex1].Code, userTable[minIndex2].Code));
                       hashSet.Add(userTable[minIndex1].Code + userTable[minIndex2].Code);
                       hashSet.Add(userTable[minIndex2].Code + userTable[minIndex1].Code);
                       break;
                   }
                   else//如果一样了,防止形成死循环
                   {
                       userTable[minIndex1].Count–;
                   }
               }
           }

           StringBuilder sb = new StringBuilder();
           foreach (var item in result)
           {
               sb.AppendFormat("{0}\t{1}\n", item.Item1, item.Item2);
           }
           string resultString = sb.ToString();
       
       }

written by ocean

6月 20

Javascript的Eval函数可谓是非常厉害

有一个思路实现

C#利用csc命令动态生成dll,然后加载该程序集到应用中,调用执行方法

java也一样,用javac生成jar包调用

如此一来就可以实现远程执行代码,实现简单的云推送

记录思想,回头研究

—–2012.6.25更新—-

经过一早上的测试,终于实现了功能

直接贴代码

实现类

云推送的类

执行结果

可以很明确的看到.当云推送文件修改的时候,执行结果也跟随着改变了

唯一不足:程序集不能单独卸载,只能跟着appdomain一起卸载,所以造成程序集越来越多

这个可以加以改进

更新

http://blog.wx6.org/2012/338.htm

written by ocean

6月 14

系统

# uname -a               # 查看内核/操作系统/CPU信息
# head -n 1 /etc/issue   # 查看操作系统版本
# cat /proc/cpuinfo      # 查看CPU信息
# hostname               # 查看计算机名
# lspci -tv              # 列出所有PCI设备
# lsusb -tv              # 列出所有USB设备
# lsmod                  # 列出加载的内核模块
# env                    # 查看环境变量

资源

# free -m                # 查看内存使用量和交换区使用量
# df -h                  # 查看各分区使用情况
# du -sh <目录名>        # 查看指定目录的大小
# grep MemTotal /proc/meminfo   # 查看内存总量
# grep MemFree /proc/meminfo    # 查看空闲内存量
# uptime                 # 查看系统运行时间、用户数、负载
# cat /proc/loadavg      # 查看系统负载

磁盘和分区

# mount | column -t      # 查看挂接的分区状态
# fdisk -l               # 查看所有分区
# swapon -s              # 查看所有交换分区
# hdparm -i /dev/hda     # 查看磁盘参数(仅适用于IDE设备)
# dmesg | grep IDE       # 查看启动时IDE设备检测状况

网络

# ifconfig               # 查看所有网络接口的属性
# iptables -L            # 查看防火墙设置
# route -n               # 查看路由表
# netstat -lntp          # 查看所有监听端口
# netstat -antp          # 查看所有已经建立的连接
# netstat -s             # 查看网络统计信息

进程

# ps -ef                 # 查看所有进程
# top                    # 实时显示进程状态

用户

# w                      # 查看活动用户
# id <用户名>            # 查看指定用户信息
# last                   # 查看用户登录日志
# cut -d: -f1 /etc/passwd   # 查看系统所有用户
# cut -d: -f1 /etc/group    # 查看系统所有组
# crontab -l             # 查看当前用户的计划任务

服务

# chkconfig –list       # 列出所有系统服务
# chkconfig –list | grep on    # 列出所有启动的系统服务

程序

# rpm -qa                # 查看所有安装的软件包

written by ocean

6月 05

New和Override这两个关键字是互斥的。不可以同时使用

written by ocean

6月 05

Server.Transfer,Response.Redirect区别

Server.Transfer只能够转跳到本地虚拟目录指定的页面,URL地址不变,携带上下文

Response.Redirect则十分灵活,URL地址改变,HTTP状态 302

using的用法

1,引入命名空间

2,using别名

3,try,finally语法糖.自动调用Dispose方法

    要求对象必须实现IDisposable接口的Dispose方法

new用法

1,运算符,实例化对象

2,修饰符,用来隐藏继承成员中同名方法或者成员

3,泛型约束

访问修饰符
public 公有访问。不受任何限制。
private 私有访问。只限于本类成员访问,子类,实例都不能访问。
protected 保护访问。只限于本类和子类访问,实例不能访问。
internal 内部访问。只限于本项目内访问,其他不能访问。
protected internal 内部保护访问。只限于本项目或是子类访问,其他不能访问

ref,out的区别

两者都是按地址传递的,使用后都将改变原来的数值。

ref可以把参数的数值传递进函数,但是out是要把参数清空

就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所以你必须初始化一次。

两个的区别:ref是有进有出,out是只出不进。

written by ocean

6月 04

所谓泛型,即通过参数化类型来实现在同一份代码上操作多种数据类型。泛型编程是一种编程范式,它利用“参数化类型”将类型抽象化,从而实现更为灵活的复用。

面向对象的语言好处是使得程序员可以很方便地重用代码, 在面向对象中程序员可以写一个子类去继承自一个父类,写不同的程序能够重用以前的代码, 会减少很多代码的工作量。
但是算法能不能重用呢? 答案是肯定的, CLR提供了一个算法重用的机制, 就是泛型。

1. 减少装箱/拆箱(提高性能)

2.  限制泛型参数的类型

首先有一点需要说明,泛型类型和普通类型在静态构造函数上有一点不同。

对于普通类型,静态构造函数只在此类型第一次初始化的时候才会执行,

而泛型类型的静态构造函数会在 每种特定类型(即泛型参数T被替换为Int32或者String等等)的第一次初始化的时候执行。

3.  节点类型不同的链表

泛型标识
泛型的写法的确是麻烦, 一堆的< 和 >, 不管是读和写都很麻烦, 有什么方法能走点近道呢?

答案有两种方法: 继承 和 使用Using 关键字。
如果我们在程序中用的了List<DateTime> dtl=new List<DateTime>(); 这样的代码很多的话, 我们就能写一个DateTimeList的类来继承List<DateTime>
Interanl class DateTimeList: List<DateTime>{
//这里边不需要写代码
}
所以在程序中我们就可以使用DateTimeList来替换所有使用到List<DateTime>的地方。

第二种方法使用Using关键字
我们可以给List<DateTime>声明一个别名DateTimeList, 如下代码:
Using DateTimeList=System.Collections.Generic.List<System.DateTime>;
然后我们就可以在程序中使用DateTimeList这个类型了。

两种方法的区别是第二种方法中, DateTimeList和List<DateTime>完全等价, 而在第一种方法中, 有如下注意点: 任何使用类型List<DateTime>的地方都可以使用DateTimeList替换, 但是使用DateTimeList的地方不能使用List<DateTime>替换, 因为两者是继承关系而非等价关系。

在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制。如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。这些限制称为约束。约束是使用 where 上下文关键字指定的。

下表列出了五种类型的约束:

约束 说明

T:struct

类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。

T:class

类型参数必须是引用类型,包括任何类、接口、委托或数组类型。

T:new()

类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new() 约束必须最后指定。

T:<基类名>

类型参数必须是指定的基类或派生自指定的基类。

T:<接口名称>

类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。

T:U

为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。这称为裸类型约束.

一.派生约束

1.常见的

public class MyClass5<T> where T :IComparable { }

2.约束放在类的实际派生之后

public class B { }

public class MyClass6<T> : B where T : IComparable { }

3.可以继承一个基类和多个接口,且基类在接口前面

public class B { }

public class MyClass7<T> where T : B, IComparable, ICloneable { }

二.构造函数约束

1.常见的

public class MyClass8<T> where T :  new() { }

2.可以将构造函数约束和派生约束组合起来,前提是构造函数约束出现在约束列表的最后

public class MyClass8<T> where T : IComparable, new() { }

三.值约束

1.常见的

public class MyClass9<T> where T : struct { }

2.与接口约束同时使用,在最前面(不能与基类约束,构造函数约束一起使用)

public class MyClass11<T> where T : struct, IComparable { }

四.引用约束

1.常见的

public class MyClass10<T> where T : class { }

五.多个泛型参数

public class MyClass12<T, U> where T : IComparable  where U : class { }

六.继承和泛型

public class B<T>{ }

1. 在从泛型基类派生时,可以提供类型实参,而不是基类泛型参数

   public class SubClass11 : B<int>
   { }

2.如果子类是泛型,而非具体的类型实参,则可以使用子类泛型参数作为泛型基类的指定类型

   public class SubClass12<R> : B<R>
   { }

3.在子类重复基类的约束(在使用子类泛型参数时,必须在子类级别重复在基类级别规定的任何约束)
   public class B<T> where T : ISomeInterface { }
   public class SubClass2<T> : B<T> where T : ISomeInterface { }

4.构造函数约束
   public class B<T> where T : new()
   {
       public T SomeMethod()
       {
           return new T();
       }
   }
   public class SubClass3<T> : B<T> where T : new(){ }

七.泛型方法(C#2.0泛型机制支持在"方法声名上包含类型参数",这就是泛型方法)

1.泛型方法既可以包含在泛型类型中,又可以包含在非泛型类型中

public class MyClass5
   {

       public void MyMethod<T>(T t){ }
   }

2.泛型方法的声明与调用

public class MyClass5
   {
       public void MyMethod<T>(T t){ }
   }
   public class App5
   {
       public void CallMethod()
       {
           MyClass5 myclass5 = new MyClass5();
           myclass5.MyMethod<int>(3);
       }
   }

3.泛型方法的重载

//第一组重载
void MyMethod1<T>(T t, int i){ }

void MyMethod1<U>(U u, int i){ }

//第二组重载
void MyMethod2<T>(int i){ }
void MyMethod2(int i){ }

//第三组重载,假设有两个泛型参数
void MyMethod3<T>(T t) where T : A { }
void MyMethod3<T>(T t) where T : B { }

//第四组重载

public class MyClass8<T,U>
   {
       public T MyMothed(T a, U b)
       {
           return a;
       }
       public T MyMothed(U a, T b)
       {
           return b;
       }
       public int MyMothed(int a, int b)
       {
           return a + b;
       }
   }

4.泛型方法的覆写

(1)public class MyBaseClass1
   {
       public virtual void MyMothed<T>(T t) where T : new() { }
   }
   public class MySubClass1:MyBaseClass1
   {
       public override void MyMothed<T>(T t) //不能重复任何约束
       { }
   }

(2)public class MyBaseClass2
   {
       public virtual void MyMothed<T>(T t)
       { }
   }
   public class MySubClass2 : MyBaseClass2
   {
       public override void MyMothed<T>(T t) //重新定义泛型参数T
       { }
   }

八.虚拟方法

public class BaseClass4<T>
   {
       public virtual T SomeMethod()
       {
           return default(T);
       }
   }
   public class SubClass4 : BaseClass4<int> //使用实参继承的时候方法要使用实参的类型
   {
       public override int SomeMethod()
       {
           return 0;
       }
   }

   public class SubClass5<T> : BaseClass4<T> //使用泛型继承时,方法也是泛型
   {
       public override T SomeMethod()
       {
           return default(T);
       }
   }

九.编译器只允许将泛型参数隐式强制转换到 Object 或约束指定的类型

class MyClass<T> where T : BaseClass, ISomeInterface
   {
       void SomeMethod(T t)
       {
           ISomeInterface obj1 = t;
           BaseClass obj2 = t;
           object obj3 = t;
       }
   }

变通方法:使用临时的 Object 变量,将泛型参数强制转换到其他任何类型

class MyClass2<T>
   {
       void SomeMethod(T t)
       {
           object temp = t;
           BaseClass obj = (BaseClass)temp;
       }
   }

十.编译器允许您将泛型参数显式强制转换到其他任何接口,但不能将其转换到类

class MyClass1<T>
   {
       void SomeMethod(T t)
       {
           ISomeInterface obj1 = (ISomeInterface)t;  
           //BaseClass obj2 = (BaseClass)t;           //不能通过编译
       }
   }

十一.使用临时的 Object 变量,将泛型参数强制转换到其他任何类型

class MyClass2<T>
   {
       void SomeMethod(T t)
       {
           object temp = t;
           BaseClass obj = (BaseClass)temp;
       }
   }

十二.使用is和as运算符

public class MyClass3<T>
   {
       public void SomeMethod(T t)
       {
           if (t is int) { }
           if (t is LinkedList<int>) { }
           string str = t as string;
           if (str != null) { }
           LinkedList<int> list = t as LinkedList<int>;
           if (list != null) { }
       }
   }

总结:

1、C#的泛型能力由CLR在运行时支持,它既不同于C++在编译时所支持的静态模板,也不同于Java在编译器层面使用“擦拭法”支持的简单的泛型。

2、C#的泛型支持包括类、结构、接口、委托四种泛型类型,以及方法成员。

3、C#的泛型采用“基类,接口,构造器,值类型/引用类型”的约束方式来实现对类型参数的“显式约束”,它不支持C++模板那样的基于签名的隐式约束。

written by ocean

6月 01

默认情况下,Eclipse的编辑器只有在输入”.”后才会唤醒代码自动补齐功能,如果想在输入任意字符的情况下都由Eclipse帮你联想method名、变量名的话,只需要这样简单设置一下:

1. 打开window→ preferences

2. 面板左侧依次点Java → Editor → Content Assistant

3. 注意右侧最下面,有一块叫做Auto-Activation的区域,在Auto activation triggers for Java旁边的框内,默认是只有”.”的,我们只需要添加上abcdefghijklmnopqrstuvwxyz(别忘了原先的.)

4. 如果你想让自动补齐的联想更快的话,就把Auto activation delay设置的小一点的吧 🙂

如下图所示:

written by ocean

6月 01
//值类型
int a = 1;
int b = a;
a = 2;
Console.WriteLine("a is {0},b is {1}", a, b);
 
//结果:
//a is 2,b is 1
 

//字符串
string str1 = "ab";
string str2 = str1;
str1 = "abc";
Console.WriteLine("str1 is {0},str2 is {1}", str1, str2);
Console.Read();

 
//结果:
//str1 is abc,str2 is ab
 
从结果看,字符串有点像值类型,但是MSDN上的解释是引用类型
http://msdn.microsoft.com/zh-cn/library/t63sy5hs(VS.80).aspx
 

值类型

值类型包括:

  • 所有数字数据类型

  • BooleanCharDate

  • 所有结构,即使其成员是引用类型

  • 枚举,因为其基础类型总是 SByteShortIntegerLongByteUShortUIntegerULong

引用类型

引用类型包括:

  • String

  • 所有数组,即使其元素是值类型

  • 类类型,如 Form

  • 委托

查看具体引用是否相同

如果Net能够查看内存地址就容易了,但不允许,只能通过间接方法来实现,看下面:

staticvoid TestRefAddress()
{
String str1 = "abc";
String str2 = "abc";
int a = 1;
int b = 1;
StringBuilder strb1 = new StringBuilder("abc");
StringBuilder strb2 = new StringBuilder("abc");
Console.WriteLine("Reference equal for string:" + Object.ReferenceEquals(str1, str2)); //结果true
Console.WriteLine("Reference equal for int:" + Object.ReferenceEquals(a, b)); //结果false
Console.WriteLine("Reference equal for StringBuilder:" + Object.ReferenceEquals(strb1, strb2)); //结果false
Console.WriteLine("Value equal for string:" + str1.Equals(str2)); //结果true,类似于值类型
Console.Read();
}

结果为何出现如此情况,分析如下:

    Console.WriteLine("Reference equal for string:" + Object.ReferenceEquals(str1, str2)); //结果true,不同对象,但引用地址相同
Console.WriteLine("Reference equal for int:" + Object.ReferenceEquals(a, b)); //结果false,值类型装箱操作造成
Console.WriteLine("Reference equal for StringBuilder:" + Object.ReferenceEquals(strb1, strb2)); //结果false,不同对象,引用地址不同
Console.WriteLine("Value equal for string:" + str1.Equals(str2)); //结果true,类似于值类型

由第一条结果,可以判定不同的String的,相同的值,其引用地址相同,再由第四条结果,str1.Equals(str2),两者结合,可得出结论,两个String,

如果赋值为同一个值,在内存中只有一个字符串存在,两个引用的地址相同。由此引出String的不变性。

String的不变性

string最为显著的一个特点就是它具有恒定不变性:我们一旦创建了一个string,在managed heap 上为他分配了一块连续的内存空间,

我们将不能以任何方式对这个string进行修改使之变长、变短、改变格式。

所有对这个string进行各项操作(比如调用ToUpper获得大写格式的string)而返回的string,

实际上另一个重新创建的string,其本身并不会产生任何变化。
string   对象称为不可变的(只读),因为一旦创建了该对象,就不能修改该对象的值。有的时候看来似乎修改了,

实际是string经过了特殊处理,每次改变值时都会建立一个新的string对象,变量会指向这个新的对象,

而原来的还是指向原来的对象,所以不会改变。这也是string效率低下的原因。

String的不变,并非说string不能改变,而是其值不能改变。

在例子中str1="ab",这时在内存中就将“ab”存下来,如果再创建字符串对象,其值也等于“ab”,

str2="ab",则并非再重新分配内存空间,而是将之前保存的“ab”的地址赋给str2的引用,这就能印证例子2中的结果。

而当str1="abc"其值发生改变时,这时检查内存,发现不存在此字符串,则重新分配内存空间,存储“abc”,

并将其地址赋给str1,而str2依然指向“ab”的地址。可以印证例子1中的结果。

结论:

String是引用类型,只是编译器对其做了特殊处理。

written by ocean