12月日常开发小结

  • A+
所属分类:.NET技术
摘要

之前做了一个异常通知的需求,简单来说就是程序执行异常了发送一封邮件和通知给指定的人员,我的做法也很简单,在利用异常捕获在catch中将捕获到的异常发送.


一、异常信息

之前做了一个异常通知的需求,简单来说就是程序执行异常了发送一封邮件和通知给指定的人员,我的做法也很简单,在利用异常捕获在catch中将捕获到的异常发送.

上线之后有同事说异常了没有发,我也不知道是不是真的异常了没发,因为之前自己测了好多遍通过了的,抱着将信将疑的态度去结合日志分析代码,后面发现确实是这样.

代码如下:

public Task Execute() {     try     {         CalculationRawData();     }     catch (Exception ex)     {                PushException?.Invoke(this, new ExceptionResponse(Company, nameof(CalculationJob),ex));     }         return Task.FromResult(0); }              
 public void CalculationRawData()  {      try      {          //dosomthing      }      catch (Exception ex)      {          Logger.Writelog("ex.InnerException.Message");      }  } 

为什么没有被发送?

根据上面2段代码分析出,在CalculationRawData方法中虽然捕获了异常但是并没有抛出,所以导致Execute没有接收到异常,自然也不会调用发送接口.
所以日常开发中对异常的处理只用一个统一的入口,在业务中尽量不要对异常进行处理,因为处理不好会导致真正有用的问题信息被吞了,增加排查成本.

二、implicit 和 explicit

讲道理工作这些年,这2个关键字基本没用过,应该不止我一个人吧!!

implicit 关键字用于声明隐式的用户自定义的类型转换运算符。 如果可以确保转换过程不会造成数据丢失,则可使用该关键字在用户定义类型和其他类型之间进行隐式转换。

explicit 关键字声明必须通过显示的调用用户定义的类型转换运算符来进行转换。

1.implicit
 //自定义转换类  public struct TimeRange  {      public DateTime StartTime { get; set; }      public DateTime EndTime { get; set; }      public TimeRange(DateTime startTime, DateTime endTime)      {          StartTime = startTime;          EndTime = endTime;      }       public static implicit operator double(TimeRange timeRange)      {          return (timeRange.EndTime - timeRange.StartTime).TotalHours; ;      }  } 
static void Main(string[] args) {     DateTime star = DateTime.Now;     DateTime end = DateTime.Now.AddDays(1);     //根据起始日期和结束日期算出间隔时间,默认隐式转换     double result =  new TimeRange(star, end); } 
2.explicit
static void Main(string[] args) {     DateTime star = DateTime.Now;     DateTime end = DateTime.Now.AddDays(1);    //根据起始日期和结束日期算出间隔时间,必须显示声明转换     double result =  (double)new TimeRange(star, end); } 

三、快速转换

1.快速将Int数组转换为String数组
int [] arr = new int[] { 4,2, 4,6 };  string[] result = Array.ConvertAll(arr, Convert.ToString); 
2.快速将List<string>转换为List<int>
 List<string> list = new List<string>() { "1","2","3","1"};  var result = list.ConvertAll(int.Parse); 

四、这可能是真的

其实并不代表是这一个月的小结,有一部分其实也有挺长一段时间了,所以记录一下。

1.为什么会产生Bug

就我自己根据这些年的开发经验和亲身经历和做过的项目,如果一旦程序出问题,无论是从承担责任或者解决问题的角度来说,从设计>开发>测试>运维>实施>直到用户,第一个祭天的永远是开发人员,确实因为东西是你做的,设计人员会说已经跟你讲清楚了,运维和测试人员会说谁知道你写的什么东西,Bug测都测不出来,最后连实施都会和用户一起鄙视你" 这tm什么垃圾软件"。

首先我得阐明我的态度,这不是针对谁,因为每个人都很不容易,并且很努力,有些观点可能不太容易被认可或者接受,但是确实是这么回事,因为这个东西是见人见智的,胡说胡有理,如果有人真的很在意,可以当做一个吐槽来看.
现实虽然就是这么无奈,但是我们必须去面对,因为只有剖析出问题所在,才能更清晰的看到本质,以至于得到实实在在的提高,在此作为一个开发总结了一下,产生Bug主要有以下几大原因:

1. 模糊的需求

有时候有一个需求来了,并没有仔细的去阅读需求,也没有仔细去和提出需求的人进行需求交底和反向交底,因为在普遍开发的认知里,写需求的人都是不懂需求的人,加上在无数次的"这是哪个xx提的需求?","为什么要这样啊?","真tm xx"

经过了长时间岁月的打磨,导致大部分在阅读需求时只是囫囵吞枣式的快速扫描一眼, 扫描过程中只摘取一些敏感字眼,然后全凭自己想当然,久而久之养成了一种先入为主的习惯,然后做出来的需求就是......额 ,不敢想象.

如何解决?

一定要仔细客观的阅读并核对用户提出的需求,然后独立分析进行反向交底,哪怕是一张很抽象的图,或者几行字都行,因为你说的话有可能在当时只是你自己认为自己讲清楚了,恰恰并不是每个人都能明白你的意思,又或是你压根就没说清楚,就算多耗点时间也没关系,磨刀不误砍柴工,如果可能拉上测试,至于为什么,那就是避免你后续做完之后,再讲第二次,第三次,懂的都懂.

2. 超乎寻常的自信

我觉得作为开发自我认可的标准并开发不是写代码多6,解Bug做需求多快,而是迷之自信,最骚的是不接受反驳,写完就提测,不说单元测试,连基本的过一遍都没有,恰恰这样却带来了不少坏处,理想的情况就是在测试阶段问题被发现了,然后一堆Bug,不太理想的情况就是测试也没测出来,然后被用户测出来了...

如何解决?

1.在写完之后,自己先整体CodeReview一遍,通常可以发现一些写法和设计缺陷并及时修改,然后最少测试3遍,测试3遍,测试3遍.

2.对于大的功能模块,写出开发版本的测试用例,写了你才能更好的进行单元测试.

3. 锻炼自己的编码内功

对API不熟悉,掌握程度不够导致出现的比比皆是,所以在用任何一个自己感觉不熟悉的api时,一定要查清楚他的方法,例如获取字典集合中取一个不存在的key "a1"对应的值,不熟悉的人经常写出直接取keyValuePairs["a1"]那就直接错了,正确使用keyValuePairs.TryGetValue("a1",out int c),像这样的细节还有很多,不一一列举,只是想表达这个意思

 Dictionary<string, int> keyValuePairs = new Dictionary<string, int>();  keyValuePairs.Add("a", 2);  keyValuePairs.Add("b", 3);  
4. 不及时复盘

为什么说要及时复盘?可以将日常开发的一些小技巧,或者解决过的典型Bug和解决办法,例如常见的

1.未将对象引用到实例.
2.参数长度超出数据库可存储的范围.
3.索引越界.
4.某个特殊的业务导致需要特殊处理.

都记下来,然后定期或者不定期的拿出来复盘一下,或者在新需求做完之后,把记录拿出来作为标准检查一下,保证之前犯过的错,和解决过的问题不会再出现。

5. 不要带着情绪做事情

这个自行脑补吧,因为每个人都有自己的个性和脾气,你可以不认可所有人,也可以认为所有人都是垃圾,但是在工作中不要表现出来带着情绪做事,这样会对你周围,或者对你自己有很大影响,谨记"要么忍,要么滚"!

6. 测试不靠谱

为什么说测试不靠谱,不是特意为鄙视或者挑起冲突而说的,也只是客观的,因为在绝大部分的小公司中的测试都是针对业务线的,加上水平也层次不齐,遇到一个经验相对丰富,会写Sql或者对绝大部分测试工具或者性能测试熟悉的你就偷着乐吧,因为我遇到的有一部分连用例都不写,我不知道是不会写,还是说嫌太麻烦了,上来一通乱点,以至于连自己点到哪里了都不清楚。

假如无法改变,又必须解决呢?

1.提高代码健壮性,减少bug把问题风险降到最小.

2.换个环境可能会好一点,但也有可能更糟糕...