1283 最小周长
题目来源: Codility
基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题
一个矩形的面积为S,已知该矩形的边长都是整数,求所有满足条件的矩形中,周长的最小值。例如:S = 24,那么有{1 24} {2 12} {3 8} {4 6}这4种矩形,其中{4 6}的周长最小,为20。

阅读全文 »

  最近开始阅读陆敏技先生机械工业出版社出版的《编写高质量代码:改善C#程序的157个建议》一书,打算把其中涉及的所有的观点做一下总结和分析,用于总结和事后翻阅,如果有侵权请联系我删除。

建议一:正确操作字符串

确保尽量小的装箱

  在自己编写的代码中,应当尽可能地避免编写不必要的装箱代码。

1
2
var str1 = "str1" + 9;
var str2 = "str2" + 9.ToString();

  第一句代码中,+ 连接时是将 值类型 int 转换为 引用类型 string 之后在进行 Concat 操作,故而性能更差。

  装箱之所以带来性能损耗的原因是,装箱需要以下三个步骤:

  1. 首先,会为值类型在托管堆中分配内存。除了值类型本身所分配的内存外,内存总量还要加上类型对象指针和同步块索引所占用的内存。
  2. 将值类型的值复制到新分配的堆内存中。
  3. 返回已经成为引用类型的对象的地址。

避免分配额外的内存空间

  频繁的进行字符串的拼接操作时,最好使用 StringBuilder,字符串的任何方法或者进行任何运算都会在内存中创建一个新的字符串对象。

建议二:使用默认转型方法

  1. 使用类型的转换运算符。
  2. 使用类型内置的 Parse、TryParse,或者如 ToString、ToDouble 和 ToDateTime 等方法。
  3. 使用帮助类提供的方法。
  4. 使用 CLR 支持的转型

建议三:区别对待强制转型与 as 和 is

  1. 如果类型之间都上溯到了某个共同的基类,那么根据此基类进行的转型(即基类转型为子类本身)应该使用 as。子类与子类之间的转型,则应该提供转换操作符,以便进行强制转型。
  2. as 操作符永远不会抛出异常,如果类型不匹配则会返回 null。
  3. as 不能操作基元类型,如果涉及基元类型的算法,就需要通过 is 转型前的类型进行判断,以避免转型失败。
  4. C# 7.0 中提供了 is 的新语法,以下两个方法其实是完全等价的:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public void A2(object obj)
    {
    var str = obj as string;
    if (str != null)
    Console.WriteLine(str);
    }
    public void A3(object obj)
    {
    if (obj is string str)
    Console.WriteLine(str);

    }

建议四: TryParse 比 Parse 好

Parse 和 TryParse 如果执行成功,他们的效率在一个数量级上,但如果执行失败,Parse 方法在转化失败的时候会引发异常,极大地消耗效率,而 TryParse 并不会。

建议五: 使用 int? 来确保值类型也可以为 null

  业务需求中,int 类型的字段在无意义时在业务上为 null 比它的默认值 0 更为合适。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
var instance = new Mutex(true, "SingleStart", out bool createdNew); //同步基元变量
if (createdNew)
{
Application.Run(new Form());
instance.ReleaseMutex();
}
else
{
Application.Exit();
}
}
}
阅读全文 »

开始做的时候也遇到了奇葩的情况、创智提供的dll只能在有UI的Winform、WPF上使用,WebForm、WPF、WebService完全没办法使用,Console在加上了[STAThread]的线程Attribute之后也可以成功调用,推测和dll使用MFC编写有关、但是各种引入MFC的dll均无果,一筹莫展之际把问题提到了交流群里,吾乐吧的牛总给出了可行的解决方案—-使用WCF来调用。

有了具体解决方案一切就顺风顺水了,但是完成程序之后又出现了奇葩的问题,部署到服务器也会出现外部组件异常的问题,本机调试可以部署却不行,很明显就是环境的问题了,由于dll为非托管dll,我们无法从错误中得到有效的错误信息,从环境下手尝试解决,虽然最终成功了,但是目前还并不清楚到底是因为什么,这里的经验是MSSOAP、MSXML、WebMatrix一定要装,如果还是不能成功运行可以考虑安装VS环境试试看。期待能有高手给出具体的解决之道。

阅读全文 »

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//声明和需进行跨线程调用的方法相同形参表的委托
public delegate void AddStatusInfoToFormCallback(string str);
private void AddStatusInfoToForm(string str)
{
//检测调用控件的线程和创建控件的线程是否相同
//如果调用控件的线程和创建创建控件的线程不是同一个则为True
if (InvokeRequired)
{
//使用委托调用本方法
var d = new AddStatusInfoToFormCallback(AddStatusInfoToForm);
Invoke(d, str);
}
else
{
//当前线程调用
Controls.Clear();
}
}
阅读全文 »

redhat 的更新包只对注册的用户生效,所以我们需要自己手动更改成CentOS 的更新包,CentOS几乎和redhat是一样的,所以无需担心软件包是否可安装,安装之后是否有问题。

阅读全文 »