爆栈思想 – 如何强迫开发人员提高代码质量

劳逸结合

在微博看见有同学说花了不少时间修警告,修上瘾了,不想回家吃饭。首先,这位同学,身体健康是自己的,热爱工作也好,给老板卖命也好,也得work life balance,劳逸结合。

警告有什么不好?

首先,为什么要把警告给修了呢?一般来说,警告来自编译器,分几种情况:

  • 编译器认为有潜在错误的可能,譬如类型转换丢失数据等
  • 冗余代码,譬如多余的变量等,在C#中经常遇到的是try/catch(Exception ex),这个ex异常变量很多开发人员都不会使用,所以就成了警告。

这些警告,说白了,首先是碍眼、闹心,像我这种推崇代码质量追求性能的有代码洁癖的开发人员,我就不能容忍警告。

然而,代码洁癖不是最重要的,如果因为像long <-> int之间类型转换过程中导致数据丢失,那这种警告必须修复,因为错误到了生产环境后的修复成本会高很多。

怎么修复警告?

有同学说:把警告屏蔽掉,世界就安静了,problem solved!但是,这种掩耳盗铃的伎俩迟早会导致麻烦找上门来。

我曾经在一个公司做过,其主系统几百万行代码而已,几百个警告,修了我好久,都修好了,一段时间之后,发现又有几十个,身心俱疲。这显然是开发人员完全不理解为什么警告要修复,也不理解怎么避免警告。

在另外一家公司,2200万行代码,70万个单元/整合测试,没有一个警告,因为任何警告都被视为错误无法编译通过。当然,开发人员的平均水平高也是很重要的一个原因。

所以,要么狠下心把警告视为错误让开发人员老实修复,要么培养提高他们的素质。不过,根据我10多年的开发经验,不能相信开发人员的自律,必须两手都要抓,两手都要硬,因为你永远不知道哪天被猪队友坑了。在这点上,Visual Studio有“把警告视为错误”的选项。

Visual Studio大法好,你值得拥有!

怎样强迫开发人员提供技术水平?

在某司呆过,他们自己从头实现了一整套的分布式编译、测试系统,没错,简单来说他们实现了自己的Team City。这套重新发明的轮子有很强悍的地方,譬如几百种的非常严格、全面的代码风格、质量控制规则,你想到和没想到的都有,譬如,多一个空格都会被视为错误无法编译通过,一般新开发人员来到,会被逼疯。但是,这样下来,整个系统看起来都像是同一个开发人员写出来的。

当然,大部分公司都没有这样的资源去做这样的一套系统,但是,我们完全可以引入一些比较严格的自动化代码质量控制规则(即便通过插件)。

关于被动、主动的层次,英文里面是:passive(被动)-> responsive (反应)  -> active (主动) -> proactive (积极) -> pre-emptive

在代码质量控制上,我们也应该用各种规则防止被坑爹。

 

想知道为什么我这么多年来能掌握那么多种技术,不仅仅是广度,还有深度,达到我所说的“爆栈”吗?

在《爆栈之旅》,我根据大家都实际情况、水平、方向等规划职业路径,手把手带你做实战的项目,用最高效的办法达到你想要的高度。

爆栈之旅

是否想技术水平快速提升?是否希望快速成为公司的技术骨干?

核心价值
  • 把我这10多年来所学到的知识、总结的经验、吸取的教训分享出来
  • 针对不同的学生量身定制规划学习成长路线、1对1个人指导、代码审阅等
  • 解答各种技术问题
  • 为公司提供技术解决方案

请查看本站右边的信息联系我。

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。

爆栈思想 – 我究竟值多少钱?

价格和价值

首先,我们需要明白,价格不一定等于价值。价格就是大家去购物看见商品上的那个标价,但是价值往往是另外一回事。

我究竟值多少钱?

我经常和那些找工作的朋友说,对薪资要求,一般有3种心态:

  • 我宁愿现在要求少一点,先把offer拿到手,进去之后再好好表现争取升职、加薪
  • 我会看市场,结合自身实际情况,合理地要求
  • 我会尽量抬高要求,譬如我现在拿10万,我会更下一家公司说我现在拿15万,这样他们为了追逐我,就一定会给15万以上

我多次提及,一个公司养一个员工,远远不止工资这么多,譬如你拿工资10万,加上各种税、年假病假、招聘费用、资源(工位摊分成等等)、培训,实际上公司要为你付出15万甚至更多,而且商家都是逐利的,公司会从你获取20万甚至更多,这意味着,你要求10万,公司会尽可能地榨取你起码20万的付出。

简单地来说,没有免费的午餐,你获得多少,付出的必须更多。

我没有跟进中国的市场,我只知道BAT等互联网公司哄抬了开发人员的身价,动辄几十万、上百万工资加一大票的期权股份。

单纯澳洲来说:

  • 人年平均收入大概是7万多(这几年的大概数字,没有跟进最新的)
  • 悉尼的开发人员(笼统地平均,忽略前端、后端、数据、爆栈的区别)
    • 初级开发人员(0 – 3年经验):5-7万
    • 中级:8-10万
    • 高级:11-13万
    • 小头目/架构师:14-16万
    • ….如此类推

 

想知道为什么我这么多年来能掌握那么多种技术,不仅仅是广度,还有深度,达到我所说的“爆栈”吗?

在《爆栈之旅》,我根据大家都实际情况、水平、方向等规划职业路径,手把手带你做实战的项目,用最高效的办法达到你想要的高度。

爆栈之旅

是否想技术水平快速提升?是否希望快速成为公司的技术骨干?

核心价值
  • 把我这10多年来所学到的知识、总结的经验、吸取的教训分享出来
  • 针对不同的学生量身定制规划学习成长路线、1对1个人指导、代码审阅等
  • 解答各种技术问题
  • 为公司提供技术解决方案

请查看本站右边的信息联系我。

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。

爆栈思想 – 偏好与偏见

偏好

相比英剧,我更喜欢美剧。相比现代流行歌曲,我更喜欢70年代-90年代的经典爱情歌曲。这是偏好。

偏见

偏好和偏见还是有很大区别的。譬如:

  • 一些开发技术文章,同类对比的时候,只字不提C井,尽管这些文章中的截图C井很明显地出现在突出的位置(排名很高)
  • 比较cloud服务的时候说Google的、IBM的、AWS就是不说排名第二的Azure
  • 开源领域不谈微软的贡献,又譬如宁愿离开GitHub去gitlab
  • 《最强大脑》那个组合拆了的汉字的游戏,用的Hololens,就没说微软的

当然,你们可以说是这是选择自由。

很多时候,这些偏见来源于坐井观天,他们对微软的认识还停留在10年前,现在:

  • .NET可以在各个平台上跑,完全开源,而且性能(语言+平台)在各个性能比较网站上的评分追平甚至超过Java,远远抛离你们想象中的那些主流解决方案
  • SQL Server不仅能在Windows上跑,而且还能在Linux上跑
  • Visual Studio不仅仅是给Windows开发者做桌面程序的,现在MacOS和Linux越来越多开发人员拥抱Visual Studio Code了
  • 大家常用的SO(StackOverflow),使用了大量微软的技术,包括C#和ASP.NET

 

想知道为什么我这么多年来能掌握那么多种技术,不仅仅是广度,还有深度,达到我所说的“爆栈”吗?

在《爆栈之旅》,我根据大家都实际情况、水平、方向等规划职业路径,手把手带你做实战的项目,用最高效的办法达到你想要的高度。

爆栈之旅

是否想技术水平快速提升?是否希望快速成为公司的技术骨干?

核心价值
  • 把我这10多年来所学到的知识、总结的经验、吸取的教训分享出来
  • 针对不同的学生量身定制规划学习成长路线、1对1个人指导、代码审阅等
  • 解答各种技术问题
  • 为公司提供技术解决方案

请查看本站右边的信息联系我。

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。

.NET的前世今生与将来

笔者注

谨以此文纪念我敬重的于2016年9月17日去世的 装配脑袋 逝世两周年

让大家久等了,前后花了1年的时间,几经改版,终于完成撰写了一万字长文,回顾和展望.NET这16年来的成功与失败。最终能成文是因为我给自己承诺必须赶在 装配脑袋 逝世两周年前发表。愿天堂没有bug,活着的开发人员珍惜写好每一行代码的机会。

前言

.NET正式诞生了16年了,目前是微软技术栈的主要开发平台。笔者有幸在2002年在生产环境使用.NET 1.0 beta,一直到现在.NET Core 2.1,见证了.NET从最开始蹒跚学步的婴儿,到现在在各大领域大放异彩的巨人。

在过去的10多年中,开始那些年,.NET被质疑、误解,一些开技术人员觉得.NET就是Java的复制品,没有什么值得学习和使用的,而且,一些反微软阵营的技术人员,为了反对而反对。正是由于这些偏见,至今,一些公司仍然不愿意使用.NET,即便.NET从第一天开始就已经提交到ECMA标准和使用Rotor开放了代码和免费使用。

本文试图给大家展示一个完整的.NET历史、现状、生态圈,希望在.NET拥抱开源界的时候,业界也能拥抱.NET,更多技术人员参与到.NET的大家庭中来。

现在,让我们一起回顾一下.NET过去10多年的发展吧。

.NET技术栈

如果你想对.NET的整个技术栈有全面的理解和并希望深入研究,可以看笔者的爆栈下面的.NET技术栈:http://overflowstack.github.io/

爆栈网

爆栈网Kayow.com融合了我10多年来的经验、心得、吸取的教训,频繁地发表高质量的技术文章: http://kayow.com

误解

现在业界/一些开发人员对.NET这个平台有诸多误解,他们的想法可以概括如下:
  • .NET是封闭的
    • 实际上,.NET从第一天开始便把标准提交到ECMA,并且利用Rotor 开放了源代码(详见这里),感谢RednaxelaFX的指正
  • .NET只能在Windows平台上跑
    • .NET 2004年开始就能在Linux上面跑了(Mono,详见后面内容)
  • .NET带来的费用高
    • .NET是开源的,可以在多平台跑,没有费用可言
  • .NET性能低
    • .NET(相关开发语言如C#)的性能在多个性能测试平台上是领先的(详见后面内容)
  • .NET是微软的
    • 这是典型的为了反而反,类似的幼稚行为是在微软最近收购了GitHub后,一些开发人员马上迁移到GitLab上,然而他们可能不知道:
      • GitLab是在微软Azure托管的(不过他们最近迁移到Google Cloud了)
      • GItLab之前发生过因为PostgreSQL主数据库备份/恢复出错导致了客户数据丢失的问题

前世

Windows 32

在2000年前,在微软平台上做开发,一般用的Windows 32 API,主要有以下几种开发方案:
  • Visual C++
    • 通用解决方案,可以是桌面应用(如MFC),也可以是C/S应用
  • Visual BASIC
    • 快速应用开发(RAD)的一种,一般做图形界面(GUI)应用
    • 组件一般采用ActiveX(COM),利用注册表做接口管理
    • 提醒:VB在.NET没有缺席
  • Delphi
    • 另外一种RAD,兼顾了VB的组件化和VC++的很好的底层API交互支持
    • Anders Hejlsberg是这个产品的首席架构师(提醒,他是.NET的核心人物之一,看下面内容)
做Win 32开发,会面对一个问题:版本控制,因为接口改变了,但因为发布管理不统一,导致了不同版本互相覆盖,调用错乱,这就是饱受诟病的.DLL地狱(Windows类库一般用.DLL做后缀):
  • 标准Win32 DLL:要么随意放到Windows System32目录,要么Program Files (x86)目录
  • ActiveX DLL:虽然统一用注册表做版本信息管理,但是因为发布的时候版本没定义好,导致使用regsvr32.exe注册的时候可能会把上一个版本覆盖
做Web开发,当年微软提供了ASP(Active Server Pages),使用VBScript做服务器端脚本,利用ActiveX做实际业务交互,譬如ADODB做数据库存储,但是这个解决方案在内存处理、安全方面都存在诸多问题。

前期

背景

诞生

微软剑桥研究院的技术人员,在1998年开始研究下一代的开发技术,他们的思维很超前,去年他们发了一篇文章,介绍这个项目的发展史,上面的图片,清晰可见一些.NET的特性,还有一些还没有被实现。

.NET这个开发平台,学习多个开发平台的特性,譬如Java,把开发语言Java等(笔者注:别的Java平台语言下面提及)编译成中间语言(IL),运行时JIT。不过.NET更进一步,支持本地化编译。

2002年,微软正式对外发布了.NET 1.0。

最近,Oracle宣称.NET的主要对手Java的安装量超过20亿,笔者还没有找到.NET安装量的官方数字,但是我们可以做一个保守估计:

  • Windows XP开始预装.NET
  • Windows XP预装版本开始到Windows 10
  • 保守估计超过30亿

.NET的名字

相信很多人会问,为什么会取.NET这个名字?适逢当年2000-2002年互联网大潮,微软打算推出一个适应互联网需求的开发平台,所以干脆用了.NET这个名字。当时很多公司开发的产品都加了.NET后缀,甚至公司域名都采用了.NET而不是.COM。

.NET特性

首先,.NET是一个开发平台,从1.0开始支持GUI(WinForm)、CUI(控制台)、Windows Service、Remoting等等Windows平台的开发,也支持ASP.NET (WebForm)开发web系统,所以从最开始,.NET就支持多平台开发。可以说.NET从第一天开始便是为了互联网而生的。

.NET编译生产的文件叫程序集Assembly,就是代码物理的集合,命名空间用来逻辑归类代码。

语言 vs 平台

有一些同学把语言和平台搞混了,譬如他们会说.NET是一种语言。让我们来捋一下关系吧:
  • 平台:.NET
    • 语言:C#,F#,VB.NET,等等
  • 平台:JVM
    • 语言:Java、Scala、Clojure,等等
有趣的是,现在流行的开发平台大多采用了类似的编译、运行、调优机制:
  1. 编译成中间语言(IL)
  2. 运行时即时编译成machine code(JIT,后述)
  3. 有办法改变JIT的行为(调优)
  4. 有办法预编译成machine code

言归正传,.NET平台上最主流的3种开发语言分别是C#、VB.NET和F#。

Pascal之父、Delphi首席架构师Anders Hejlsberg,当年还在Borland,被微软CEO Bill Gates重金邀请加盟微软,主导开发.NET平台上的全新开发语言,这就有了现在.NET平台上最流行的开发语言C# ,取义C++的++ ,即(C++)++,合在一起就是4个+,碰巧和音符的C♯一样,所以读作C sharp,不是C井,谢谢。因为这个升C的字符比较难敲,所以,一般用数字3上面的那个#符号代替(对,♯和#不是同一个字符)。C#是目前全球最流行的开发语言之一。

如果你想深入了解C#,可以参考Jon Skeet编写的《C# in depth》,JK很奇怪,他是在Stack Overflow上是排名第一的回答者,C#专家,然而,他却是在Google工作的(潜伏的卧底?)。

笔者对BASIC有着非常深厚的感情,第一次接触这个语言是1992/1993年的时候,后来用了GWBASIC、TrueBASIC、TurboBASIC、QBASIC、QuickBASIC、Visual BASIC (1.0版本还是DOS下的,用的ASCII字符拼接成图形界面)。

如果你用Visual BASIC 5/6,相信不会对VB.NET太陌生,尽管VB.NET用起来有点别扭。VB.NET表面上是微软照顾老VB用户在.NET平台上的实现,但这个语言实在太别扭。在VB 11.0之前,它是尽量和C#高度交互的,很多语言特性都尽量“兼容”,但是11.0之后,开发团队决定和C#分道扬镳,各自演进。

说起VB.NET,相信一些开发人员还记得@装配脑袋,他从老VB开始就是忠实用户,在博客、技术会议中和大家分享各自VB.NET/编译器技术和心得,他两年前不幸因病去世,愿天堂没有bug。

VC++一直以开发高性能著称程序,在.NET世界,VC++.NET,可以和.NET程序集交互,当然,你仍然可以选择写不基于.NET的代码。不过,如果你用.NET的话,为什么不直接用C#?除了VC++.NET,微软还有C++/CLI这个专门设计来和.NETA交互的兼容C++的语言,用来开发.NET托管代码。

如果你需要高性能、喜欢函数式编程,那么F#这个函数式的开发语言会比较适合你,它天生以高性能并行计算著称。可能你还已经猜到,F#里的F代表Functional函数式。

微软当年雄心勃勃,希望把.NET打造为大一统的开发平台,当年Java如日中天,微软自然不会放过这个机会:难道还有直接把对手的支持者拉拢过来的而扩大市场更好的办法吗?此消彼长,道理大家都懂。所以微软推出了J#。不过这个项目有点尴尬,最开始是想和Java进行交互,利用Java成熟的平台组件,后来项目没有被维护了,但是,.NET 4.5之前,想要自己读写zip文件,.NET框架内置的类库中,只有J#有一个类库,否则只能用第三方的方案。

J#出师未捷身先死,长使英雄泪满襟。然而这并没有阻止.NET的雄心。大家知道JVM是一个运行平台,在这基础上,有各种语言,Java是老大哥,Scala有取而代之的趋势,最近Google因为不满Oracle拿Java版权大棒乱挥舞,近年大力扶植JetBrains的Kotlin。同样,.NET平台上,也有多种语言,除了上述的几种,还有Fantom、Visual COBOL、ClojureCLR等。

为了和动态语言交互,.NET引入了 Dynamic Language Runtime (DLR),这样,各自动态语言就可以和.NET互相调用,而这个平台下的语言一般有一个前缀:Iron。当年出现了IronPython、IronRuby、IronScheme等项目。然而,这个项目没有被维护了。或许Iron是因为这个名字起得比较晦气,都“打铁”了。

核心特性

每种语言/开发平台都有自己的看家本领:语言特性(面向对象 vs 函数式、强类型 vs 动态类型、并行计算等等)、生态圈(开放、大量的第三方库/扩展支持)等等。

.NET的运行时Common Language Runtime(CLR)是.NET的核心,负责程序的解释和运行。.NET程序启动的时候,会经过多达50步才正式开始跑你写的第一行代码,中间是各种元数据的查找、分析等。如果程序是第一次执行,CLR会把要执行的代码路径进行JIT(即时编译),这个过程会有各种优化,举个例子:冷代码(如异常处理逻辑)会相对热代码(正常逻辑)执行较慢,这就是为什么如果过度使用异常来做控制,会有性能瓶颈。

如果你想对CLR进入深入的了解,可以参考传奇开发人员Jeffrey Richter编写的《CLR via C#》,他是经典开发书籍《Windows via C/C++ 》的作者。

.NET大量封装Win 32 API,这叫InterOperability(InterOp)。如果你需要调用第三方甚至自己编写的Windows 32,可以通过这个实现。

还记得DLL地狱吗?.NET的程序集经过SN(强命名)签名后,可以通过gacutil注册到Global Assembly Cache(GAC),这样任何一个程序可以直接调用。因为它通过程序集名称(assembly name)来区分每个程序集的唯一性,每个版本存放在不同的目录下,所以不会出现不同版本的程序集互相覆盖的问题。

C/C++,没有第三方的库,你需要手工控制内存的调用和回收,好处是按需调用,省内存,高效,然而对开发人员有较高要求,所以一般使用第三方的解决方案。Java和.NET,都有自己的Garbage Collection (GC)。.NET GC分3个阶段,不同阶段针对对象的不同生命周期。如果你希望深入研究GC,可以参考下面的”高性能”部分。

不同于现在各种基于Google Chromium二次打包的浏览器壳,除了完整版,.NET还包括多个不同的兄弟框架,譬如.NET Execution Environment (DNX)、Compact Framework (CF)用于移动设备、Microsoft Framework (MF)用于嵌入式设备。

开发

Visual Studio是最受微软技术开发人员欢迎的IDE,你可以通过它使用上述各种语言开发、调试、测试、发布各种应用。或许你不知道,Visual Studio作为通用的IDE,被其它产品借用,譬如微软SQL Server的管理工具SQL Server Management Studio (SSMS)就是基于Visual Studio的,所以大部分快捷键和功能是一致的。

刚开始的时候微软推出的.NET针对自家Windows桌面开发推出了Windows Form(WinForm)这个开发方案。出发点是想把所有界面元素OO化,通过事件驱动,底层还是Win32那套消息机制,GDI+渲染。不过默认的渲染效果有审美疲劳,所以有些应用采用了国内比较流行的皮肤做法,通过owner draw实现自主的渲染,摆脱了单一的UX体验。

不喜欢WinForm的事件模型?不喜欢自己实现双向绑定?不喜欢WinForm太传统的Win32 GUI元素?那么,WPF应该会是你的选择。它使用XAML作为界面语言,DirectX渲染,逻辑代码可以选择C#或者VB.NET。之所以使用XAML(XML格式),是为了把界面描述标准化,这是iOS、Android和Xamarin的标准做法。

.NET的推出是为了应对互联网时代,必不可少的,需要提供网站开发方案。微软把当年的基于ActiveX + VBScript的服务器端开发解决方案ASP(Active Server Pages)升级,成为了ASP.NET。WebForm的设计思想是复制WinForm,但是封装得不好,导致用户被迫强行做各种js和css hack,尤其是它复制WinForm的事件模型,导致各自不必要的Postback,而且页面有着极其臃肿的ViewState来维护当前的状态,所以很多时候页面加载耗时甚长,久等不见内容。当然你可以用UpdatePanel做异步ajax更新提升用户体验。

WebForm设计缺陷包括但不仅限于:
  • 早年的封装没有考虑各个浏览器的兼容性,开发者必须做各种js/css hack
  • 表格postback设计导致不理想的用户体验
  • 使用ViewState做当前页面的状态保持,但这个ViewState是写入到页面的,默认是写入到文件前面部分,但页面数据量多的时候(如使用DataGrid),这个ViewState会相当大,导致页面加载缓慢,虽然有办法把ViewState放到页面后面部分,让加载看起来快点,但是根本问题没有解决。而且ViewState会出现各种损坏的情况导致功能无法使用
  • 容易导致开发人员把界面、业务逻辑和数据存储都放到同一个文件里面,难以维护和做单元测试
  • 慢,慢,慢,重要的事情要说三遍
为了解决在饱受诟病的WebForm中出现的各种问题,微软推出了ASP.NET MVC,这是对当年市场上日渐流行的Web设计方式Model View Controller的回应,这个产品后来开源了。ASP.NET MVC的设计思想是好的,把界面、业务逻辑、数据模型等分离,这样不同角色的人员可以独立进行开发,互不干扰。
ASP.NET MVC自带几种渲染器:
  • ASP.NET WebPages就是ASPNET WebForm (不要用)
  • ASP.NET Razor 就是.cshtml/.vbhtml文件的渲染器 (还是不要用)

你可能会问,那到底用什么做页面渲染?简单来说:不要在服务器端做渲染,因为所有界面渲染都不应该是服务器的事情,现在用户的浏览器渲染能力很强,这种事情完全应该留给客户的机器去做,这样服务器的压力会大减。服务器应该做的事情只是接受请求,根据业务逻辑处理数据、读取/存储数据。

所以,页面渲染,应该选择成熟Web前端MVC方案,譬如AngularJS、React等。

网络开发,除了网站,还有一些不可见的后台服务。Web Services是跟随ASP.NET 1.0推出的,协议基于XML,现在使用这个技术的产品比较少了。后来微软推出了大一统的WCF(Windows Communication Foundation)平台,是相对较新的一套Web服务解决方案,支持多种传输协议和安全机制,但配置繁琐。

ASP.NET Web API是ASP.NET MVC的一个组件,提供构建RESTful API的方案,目前比较多产品使用。

大家还记得Java Applet吗?当年Flash大行其道,但其问题太多,安全问题、CPU占用问题、稳定性等等。为了对抗如日中天的Flash,微软推出了Silverlight。Silverlight的性能不逊色于Flash,而且比隔三差五要打安全补丁的Flash安全很多,但是两者都无法摆脱基于ActiveX插件的问题,即便预先安装,也常有版本兼容问题导致无法在浏览器加载,而且默认那套银灰色的界面确实有审美问题。

Silverlight的著名的应用:
  • 当年奥运会MSNBC的网络直播采用Silverlight解决方案
  • 微软的本地虚拟机管理平台Windows Controller,用的就是Silverlight
  • 微软云平台Azure,早期版本,使用了Silverlight做界面

不过和Flash抵挡不了技术发展的洪流一样,Silverlight也被迫退出了市场。对了,Flash在中国还是奇葩地存在,由某个流氓公司特供中国版,切记不要使用。

一个成熟的开发平台,单纯有好的语言、基础库还是不足够的。当年为了方便开发人员,微软提供了一整套的常用功能框架,叫Enterprise Library,包括功能如读写配置、数据访问、日志、缓存等,而这个项目的前身是Best Practice Application Blocks,就是类似广大开发爱好者常常自己搞的工具库。

大家还记得ActiveX年代的ADODB吗?在.NET世界,我们有升级版:ADO.NET。通过ADO.NET,你可以访问各大数据库系统。大部分数据库系统是支持多线程的,所以需要读写数据的时候:

  • 当你单线程读写数据的时候,已经用了command.Prepare(),甚至在允许表锁定的情况下用了connection.BeginTransaction()还是觉得慢,那么,
  • 可以用多线程,这里可以Parallel下的方法,一般多线程下会快带来几倍的性能提升,如果你还是觉得慢,那么,
  • 使用bulk copy。一般大型数据库系统都提供这个,譬如SQL Server提供SqlBulkCopy(本质上是BULK INSERT),譬如PostgreSQL提供的COPY命令

随着技术的发展,面向对象进入数据存储和访问领域。譬如数据访问,这些解决方案叫O/RM,对象关系映射。在Java领域著名的Hibernate被移植到.NET成了NHibernate,Dapper也是一个不错的轻量级的选择。微软也推出了自己的Entity Framework,后来并开源了。

不过不管是Code First、Model  First还是Database First,这些OO化的O/RM,因为对象化这个过程,性能损耗不可避免,而且,不同的解决方案要么解决不了延迟加载,要么做不好缓存,或者动态生成的SQL效率低下。如果你需要绝对的高性能,还是应该手工写SQL,并且封装到存储过程,这样业务逻辑不需要在每次执行的时候都在客户端/服务器不断传输。想象一下,即便某业务逻辑执行速度很快,但数量巨大,譬如一天100万次,当这个业务逻辑很复杂,譬如100K,那么一天光是这些SQL的网络流量起码是100GB,如果如果是封装成SP,那么,可能就是100MB。

同时,使用这些O/RM,一般会遇到对具体某种RDBMS的特性支持不好的情况,需要使用底层SQL直接调用操作,这样O/RM就无法直接切换到别的数据库系统了。

NoSQL蓬勃发展,在传统关系型数据库系统中被常规化的数据(一条数据会被存储到不同的字段甚至不同的表),现在作为一个json文件(字符串)被存储到各种类型的NoSQL中。NoSQL优势是快速的读写,因为避免了多表关联的可能,一次读取,一次写入。但是真因为这样,绝大部分NoSQL无法做跨表(集合)的关联,因此一般的做法是用定时任务生成目标数据,这种解决方案有2个问题:数据非实时和冗余的空间占用,同时,json文件本身的所有属性是键值对,所以空间占用远逊于RDBMS。

市面上不乏基于.NET的NoSQL,部分还是开源的,笔者觉得最好的一个是开源的STSDb,独创的Waterfall索引比传统的b+树要跟高性能。

大量业务系统都需要用到工作流。WF(Windows Workflow)是微软额外推出的基于.NET的工作流系统,不过这个方案配置起来有点罗嗦。

生态圈

从别的成熟平台中移植著名的项目是业界惯常的做法。一些著名/优秀的项目被移植到.NET,譬如Java世界的hibernate (nhibernate)、junit (nunit)、iText  (iTextSharp)、Quartz (Quartz.net)、Lucence (Lucence.net)、Log4j (log4net)。

一个开放平台的成熟,离不开社区的支持。开源/代码托管网站,早期的有SourceForge.net、CodeProject等,后来微软自己推出了自己的GotDotNet,后来变成了CodePlex.com,然而几个月前这个项目已经停止运转,大部分项目都被作者各自迁移到GitHub。

.NET框架和C#从第一天开始,就作为ECMA标准并使用特定的协议开发了源代码,这为后来的Mono和跨平台打下了坚实的基础。几年前,微软把.NET完全开源了,包括编译器、框架、类库等等。

著名的Linux GUI解决方案GNOME之父Miguel de Icaza,创建了Mono项目,让.NET真正跨平台,在Linux、MacOS下运行。Mono项目同时带来了SharpDevelop这个IDE,后来又被移植到别的平台上成为了MonoDevelop。

Mono项目近年被Ubuntu拥抱,跟随标准发布预装。

今生

.NET的发展脚步没有停下来,它不断进化,现在,.NET已经在各大平台扎根。

最近的15年周年纪念活动,Anders Hejlsberg被Channel 9邀请参与活动,并讲述了他对C#的看法,他表示:“我也没想到C#能如此兴盛。”

如果说.NET平台是心脏,那么,语言就是骨络。目前.NET平台上3大主流开发语言有各自的演进路线。C#作为先锋在新特性上不断快速进化,譬如LINQ/Lambda、async/await并行计算等,当然动态特性也是值得提及的。如果一个东西走起来像鸭子,叫起来像鸭子,它可能不是一只鸭子,而是被鸭子带坏了的鹦鹉。如果你想知道C#的各种技术内幕,可以看Matt Warren的技术博客,他是C#语言委员会的成员之一,这个委员会决定每个版本的新特性。

Roslyn作为新一代的编译工具,使用C#编写,终于实现了.NET的自举,这是一个语言成熟的标志。Mono最近有实验性的项目也在做这个事情,用C#写C#的编译器(感觉怪怪的?)。

开发工具

不仅仅是各种语言跨平台,微软的开发工具也能跨平台。Windows上最佳开发IDE Visual Studio现在不仅仅在Windows上跑,微软推出的兄弟Visual Studio Code还支持Linux和MacOS,还有Visual Studio For Mac。

最近Visual Studio Code的受欢迎程度远超其它开发环境,笔者多次参加技术讲座,不管是使用Windows 手提还是MacBookPro的开发人员,无一例外使用Visual Studio Code进行开发。特别是近年支持了Terminals,还有刚刚推出的对GitHub的整合(譬如可以查看PR等),有助其蓬勃发展。有文章分析,假以时日,Visual Studio Code会超越Visual Studio成为最流行的开发环境,我们拭目以待。

相信做过开发的同学都对各种第三方依赖组件的引入、维护都很烦恼,NPM、webpack、Chocolatey、Maven Repository等都是著名的包管理解决方案,微软效仿之,推出了NuGet。本质上NuGet包和Office系列的文件类似,都是zip文件,里面有一些元信息和实际文件。通过Visual Studio的项目Package菜单你可以直接生成NuGet包。早期的NuGet不允许直接下载包,非常恼人,必须通过客户端如Visual Studio,现在允许了。

如果你想架设自己的NuGet包管理平台,可以使用ProGet。

案例

或许你会想,.NET到底有什么优秀的案例?

如果你做Web开发,相信你听过甚至用过OWIN项目,它包括了SignalR、Nancy、Katana等项目。如果你用过IoC,你应该听过甚至用过Windsor,它是Castle项目的一员,包括了ActiveRecord、MonoRail等。相信你用过stackoverflow?它以及众多兄弟网站,都属于StackExchange,而这些所有网站都是基于ASP.NET的。微软自家一些产品也是完全或者部分使用.NET实现的,譬如BizTalk、Blend等。

如果你想了解更多的优秀.NET解决方案,可以看这个非常详细的列表:https://github.com/Microsoft/dotnet/blob/master/dotnet-developer-projects.md

了解或者开发过云应用吗?业界领先的公有云提供商微软Azure,这个平台大部分技术都是基于.NET的。对了,Bing搜索引擎也是。

Unity是流行的2D/3D游戏开发平台,其脚本系统主要是Mono,它刚刚对外宣布支持最新版版本Mono。另外一个游戏引擎Godot,也是使用Mono作为脚本引擎。

有些技术牛人,利用.NET打造自己的开源的操作系统。譬如比较早期的Cosmos OS ( https://www.gocosmos.org/ ),还有近期的FlingOS( http://www.flingos.co.uk/ )。由此可见.NET作为一个开发平台的能力和潜力。

为了实现跨CPU平台(x86和ARM等),微软为 Windows带来了UWP,开发者可以使用多种开发语言(.NET家族的,甚至HTML/WinJS)开发Windows平台应用,界面语言是XAML,这些应用不仅仅可以在Intel的x86平台下跑,还可以在ARM上跑。大家还记得Windows Phone和Surface吗?

跨平台

之前说过Mono这个跨平台开发解决方案,在支持Linux/MacOS的基础上,它继续进化,衍生出Xamarin项目,实现了对主流手机系统苹果iOS、Google Android、微软WP甚至三星Tizen的支持。

2016年微软收购了Xamarin,整合到Visual Studio里,并且将其开源,创始人Miguel de Icaza成为微软的Distinguished Engineer。

DotNet Anywhere (DNA)是另外一套跨平台解决方案:https://github.com/chrisdunelm/DotNetAnywhere

2016年,微软为了大一统.NET平台标准,推出了.NET Standard,可以把这个看成一个协议,而不是具体实现。具体实现是.NET完整版 4.x、.NET Core 2.x、Xamarin等。

.NET完整版4.x现在统治Windows平台,Xamarin复制移动平台,而.NET Core则主打跨平台,如Linux、MacOS、Docker、嵌入式设备、IoT等,譬如已经有Raspberry Pi等设备在运行.NET Core。或许你不知道,Docker For Windows是用.NET编写的。

.NET Core做法和.NET完整版在API层面基本上一直和兼容,区别在于,.NET完整版是依赖本地GAC安装/本地目录的.NET程序集,而.NET Core是依赖NuGet包,所有基础类库都是NuGet包,而这些包不像老版本的node.js那样都安装到本地目录,而是集中安装到本机的NuGet库里。

和.NET Core匹配的有ASP.NET Core,允许开发人员开发在Linux等平台跑的Web系统。

.NET开发初期,大量借鉴Java这个平台的优点,近年,Java作为平台和作为语言,分别复制了,NET和C#的一些特性。JavaScript的一些新特性直接复制了C#的特性。

高性能

业界做性能测试的时候,一般会用这句话:“不服跑个分!”。网上有各种性能评测文章/比较网站,最近看过一个完整,各种语言互相比较,其中.NET和Java的结果差异不大,11个比较项目中,.NET 6 : 5 Java。

.NET为了提高性能,通过如下几个不同状态下方式:

  • 语言:支持Parallel等并行计算
  • 编译:编译器会做各种优化,譬如代码内联,像常量和枚举等,会直接把实际值复制到调用方
  • JIT:除了根据代码访问路径进行动态即使编译之外,还可以使用更可控的Profile Guided JIT
  • 本地化:可以使用多种方式进行本地化编译,譬如ngen命令行和C# Native
  • LLVM:有一个开源项目,叫SharpLang,使用LLVM作为基础对C#代码进行编译。R大指出还有 https://github.com/dotnet/llilc 这个项目
以上是语言/框架层面的优化,如果做了上述的事情后仍然对性能不满意,那么你可以:
  • 优化算法,有可能带来数十倍的性能提升
  • 重构设计和实现,原来的设计可能是错的,也可能是现在有更好的解决办法,重构/重新实现可以改善性能
  • .NET运行时的调优
    • 如果你使用多线程(包括Parallel),那么你可以修改一下ThreadPool的MinThreads数量
    • 如果你调用HttpClient/HttpWebRequest等网络方法,那么,你可以修改一下ServicePointManager的DefaultConcurrentConnectionLimit,因为微软为了遵循古老的HTTP规则,对同一个网站最多只允许2个并发连接
    • 修改GC为Server模式
如果你还需要更高效的解决方案,可以考虑Map Reduce分布式计算,所谓的分而治之

如果你想深入研究如何编写高性能的.NET程序,可以参考Ben Watson编写的《Writing High-Performance .NET Code》这本书。

如果你还是不满足于性能表现,可以使用GPU加速,目前比较成熟的解决方案是AleaGPU,对C#的支持非常友好。

将来

Web前端开发技术日新月异,但同时也存在各种脏乱差的情况(笔者会另外撰文详细述说)。近来各大浏览器加入了对Web Assembly的支持,Web Assembly允许开发人员用如C++等语言实现逻辑,然后编译成二进制的Web Assembly。

最近,微软宣布ASP.NET项目引入了Blazor项目(取义Browser + Razor),这个项目是基于DotNet Anywhere的,允许开发人员用.NET + Razor实现前端功能。

在Windows平台上(x86和ARM),你可以使用.NET设计UWP应用,但其它平台上,你不能用.NET做带界面的应用。最近对外公布的AvaloniaUI,允许大家使用UWP类似的技术在Linux和MacOS上实现桌面应用,这个项目的名字看出来和当年的Avalon项目的关系了吗?

现在技术界喜欢搞cross play,譬如Windows 10下自带了Linux子系统,SQL Server也可以在Linux上跑,JavaScript可以通过node.js写服务器端代码,.NET也可以写Web Assembly做前端。

.NET发展16年,为业界带来各种新技术的同时,也给人类的发展做出了重大贡献,它会继续和老对手Java等一起齐头并进,互相追赶和促进。

 

后记

键盘侠没有意义,负面心态自己留着自慰。没有东西是完美的,done is better than perfect。

不做事就没人质疑,这种活法,就是咸鱼。跟“当初有机会说不,你不做声,现在大家没有机会的”一样,看见不平就出声。

 

谨以此文纪念我敬重的于2016年9月17日去世的 装配脑袋 逝世两周年。

 

如果你看到这里,那告诉你一个消息:世界那么大,我想去看看。再次上路,去追求心中的理想。除了亲人和梦想,其它任何一切东西都不重要。该放弃的时候都要放弃。

各位再会!

 

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。

爆栈之旅:软件开发人员的分级、职业发展路径等

疑惑

受微软(亚洲)首席研发经理邹欣老师的邀请,为其《构建之法》的学员作业提供一个个人见解,某学员在作业中提出了几个问题:

  • 国内目前对初、中、高级工程师的评价是否有严格标准?比如个人代码行数?代码质量?
  • 关于五个职业态度:临时性的寄托或者工作===>工作===>职业===>投身的事业===>理想的呼唤,
    • (1)五个职业态度的等级是渐进的嘛?是否可以跨越式提升?比如从第三阶段直接跨度到第五阶段?
    • (2)第三阶段即“职业”阶段,所描述的“职业道德”具体指什么?去年著名的阿里用脚本抢月饼时事件中当事人的行为算不算违反了职业道德?

我在这里尝试一下提出我的一点见解。

职业生涯

路径

一般的技术生涯的路径是:

  • 开发人员:初级程序员、中级程序员、高级程序员、小头目(Team Lead/Tech Lead)、首席开发人员(Principle Developer)
  • 架构师:应用架构师(Application Architect),系统架构师(System Architect),企业架构师(Enterprise Architect – EA)
  • 技术管理:研发经理、高级研发经理、技术副总(VPE)、CTO

这些我都在《爆栈之旅》课程里深入讨论过差异、需要多长时间、需要什么才可以逐步升级。

初级程序员

在大学学习的知识,和社会上实际需要的技能,是有一个差距的。所以初出茅庐的开发人员,一般需要恶补一些实战的技巧、知识,譬如去自行修炼、请教高手,或者参加培训班。

我从业10多年,从业初期是互联网刚起步的阶段,身边一些刚毕业的朋友,会参加那种用目前眼光来看是属于“野鸡”的培训班,这些培训班质量参差,其中不乏各种刻板的、一刀切、让学员造假、”浅入没出”的培训老师。

刚出道的开发人员,不管从哪个途径进入市场,开始的2-3年,都会被称为初级开发人员,职称一般不看代码量。关于代码量,有个段子,就是有开发人员,从网上克隆了著名开源项目的整个源代码,然后签入,他的代码量就是过百万了。

这个阶段的程序员应该像海绵那样吸收新知识,到了2-3年后,能单独维护一个模块。

中级程序员

一般要求4-6年经验,这些同学应该可以独当一面,负责设计、开发某个模块。

高级程序员

需要7-9年经验,他们可以设计和开发某个程序,系统里面的大模块、基础架构等。

小头目

9-11年,负责团队的建设、交付和代码质量管理等等,

首席研发人员

12+年,是某个团队最核心的开发人员,遇到技术问题,最后都会找这个人来解决。

具体的分类和路线,可以参考我写的:《爆栈思想 – 究竟怎样才能技术专家》。

态度的转变

我高考报志愿的时候,一些同学报计算机专业,纯粹是因为这个专业开始热,赚钱。所以,一些同学对其的态度,在开始时候,把它作为纯粹的混口饭吃的工具,是可以理解的。

但是,你思考一下:白天绝大部分的时间,你不是在上班,就是在上下班的路上,如果你不喜欢这份工作,you are f***ed!更糟糕的是,国内一些公司还搞996,你周末的时间都被占用了,那多么悲惨啊!

做一行,爱一行。到了老的时候,你回头一看,这辈子,奉献给了不喜欢的事业,那是多悲伤的事情。

软件开发是创造性的工作,需要专注和创意,如果不喜欢,那真的很难会有成就。所以,当你把这份工作当成事业来经营,那会是一个很大的改变:你会热衷于起早摸黑,孜孜不倦地钻研,为了一个解决不了问题/实现不了的功能而不能入眠。

一些不甘于做老油条,推崇“如果人没有梦想,那和咸鱼有什么区别”的同学,可能在某个阶段,为自己干活,创业去了。但是,这就像投资,风险更高。

当然,一些觉悟比较高、能力比较出众的同学,在职业的初期,便下海去了。所以,职业的路线,还是因人而异,没有所谓的“最短路径”,这可不是让你写Dijkstra算法。

更多的职业/职场心得,可以参考我写的:

 

对于有志于参与软件开发事业的同学能从我写的文章中获益,我深感欣慰。我特意写这篇文章,希望能给你们一点火花,激化出更多的学习动力。

其实软件开发这个生涯,是修炼,也是享受,苦与乐同在,失败与成功并存,坚持不懈,继续前行。

 

想知道为什么我这么多年来能掌握那么多种技术,不仅仅是广度,还有深度,达到我所说的“爆栈”吗?

在《爆栈之旅》,我根据大家都实际情况、水平、方向等规划职业路径,手把手带你做实战的项目,用最高效的办法达到你想要的高度。

爆栈之旅

是否想技术水平快速提升?是否希望快速成为公司的技术骨干?

核心价值
  • 把我这10多年来所学到的知识、总结的经验、吸取的教训分享出来
  • 针对不同的学生量身定制规划学习成长路线、1对1个人指导、代码审阅等
  • 解答各种技术问题
  • 为公司提供技术解决方案

请查看本站右边的信息联系我。

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。

爆栈思想 – 怎么样才算是某个领域的专家

我们发现,很多简历充斥着各种“精通”,尽管刚毕业不久,没有多少实际项目经验。

 

究竟怎么样才算是某个领域的专家呢?

 

应该分几方面看:
  • 技术深度
  • 影响力
  • 对社区的反哺/贡献
譬如数据库存储这块,拿SQL Server做例子,应该掌握以下技术的原理、解决办法和最佳实践:
  • 数据类型/对象
    • 各种数据类型的转换优先级、差异
      • 看似简单,举2个例子:
        • SELECT 1 + ‘+’ + 1
        • 4种不同的临时表/表类型差异和最佳实践
  • 访问
    • 各种DDL/DML/DCL/TCL的最佳实践
  • 内核机制
    • 调度器
    • 各种hint
      • 升级、优先级和差异
      • 堵塞
      • 死锁
    • 等待/延迟
    • IO Stall
    • 进程/请求/任务/连接
    • 缓存/缓冲
  • 最大限制与版本差异
    • 各种级别/方面的最大/最小限制
    • 不同版本的差异
    • 不同版本的新特性、失效特性
  • 深入排错
    • 错误的级别和哪些会在客户端触发
    • 排错的多种方式
  • 调优
    • 表、列设计的最佳实践
    • 索引、扫描、各种Lookup、Bookmark
      • 各种类型的索引的差异
      • 性能相差数万倍的设计
      • 索引管理最佳实践
    • 执行计划
      • 如何找到性能瓶颈
      • 编译、损坏与修复
      • 如何强制刷新(多种方法和副作用)
    • 不同方法的性能巨大差异
      • 譬如COALESCE vs FOR XML vs STRING_AGG
    • 利用多核的最佳实践
    • 数据库/日志文件切分、存储的最佳实践
    • 数据库/日志备份/恢复的最佳实践
    • 内存调度最佳实践
    • 内联
    • 各种trace flags
  • 海量数据处理
    • 高效分库分表
      • 各种切分的优缺点
    • 如何实现大量数据的导入和导出
  • 安全和访问控制
    • 如何实现实例、数据库、表、行、列多级访问控制
    • 如何防止注入和入侵
    • 跨库访问的最佳实践
  • 审计和记录
    • 审计的最佳实践
    • 如何高效实现修改操作记录
  • 容灾、高可用最佳实践
    • AlwaysOn / HAG
    • 如何fail over
    • 备份的多种方式、差异和最佳实践
  • 扩展
    • SQL CLR
  • 管理/自动化
    • 任务
    • DMV
    • DBCC
  • BI
    • SSIS
    • SSAS
    • SSRS
如果详细写下来,这会是一本《SQL Server专家》。

 

关于影响力、对社区的反哺和贡献,这主要是看是否参与社区的讨论/问题解决、代码贡献等。

 

 

想知道为什么我这么多年来能掌握那么多种技术,不仅仅是广度,还有深度,达到我所说的“爆栈”吗?

在《爆栈之旅》,我根据大家都实际情况、水平、方向等规划职业路径,手把手带你做实战的项目,用最高效的办法达到你想要的高度。

爆栈之旅

是否想技术水平快速提升?是否希望快速成为公司的技术骨干?

核心价值
  • 把我这10多年来所学到的知识、总结的经验、吸取的教训分享出来
  • 针对不同的学生量身定制规划学习成长路线、1对1个人指导、代码审阅等
  • 解答各种技术问题
  • 为公司提供技术解决方案

请查看本站右边的信息联系我。

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。

爆栈思想 – 怎么样的开发人员才是合格的?

基本要求

地铁上,一个妈妈用手遮着孩子的鞋子,为了不弄脏旁边乘客的衣服。评论者说:“这不是很基本要求的吗?”

是的,这位同学说得没错。但是,究竟做这个的是多数还是少数呢?

很多时候,我们想当然地以为,一些基本的东西,实际上我们都没有做到:

  • 譬如不随地吐痰扔垃圾
  • 譬如给老幼病残孕妇让座
  • 不在公共场合大声喧哗
  • 不要在社交媒体做没脑的喷子
  • 不要为了蝇头小利出卖自己的人性,譬如做5毛

素质与底线

很多时候,我们可以简单粗暴地归纳,上述那些人没素质。同理,很多开发人员并没有基本的素质:

  • 不管代码质量,填满工作时间便可,善于挖坑,“我离职后,哪管洪水滔天!”
  • 懒散,故意拖进度
  • 老油条,得过且过
  • 拿网上有版权等代码据为己有

更有甚者,在犯罪:

  • 大学毕业后第一份工作,一个离职员工,把硬盘格式化,还破坏分区
  • 还是第一份工作,部门经理偷公司的源代码去卖

不奢求每个开发人员都写高质量代码,但是起码的是,代码能被维护,程序跑起来不会随意崩溃,用户体验不会顿卡,等等。

父母从小教导我们,不属于自己的东西不要去贪图,这个包括各种手段,譬如偷、抢等。邀功、推塞责任等都是罪恶。

八荣八耻

  • 以踏实编码为荣 以心浮气躁为耻
  • 以详细注释为荣 以注释残缺为耻
  • 以勤于测试为荣 以懒于测试为耻
  • 以简明文档为荣 以冗余文档为耻
  • 以注重团队为荣 以孤傲自大为耻
  • 以刻苦钻研为荣 以敷衍了事为耻
  • 以善于总结为荣 以不思进取为耻
  • 以质效并进为荣 以单取其一为耻

来自这里

 

  • 以动手实践为荣,以只看不练为耻。
  • 以打印日志为荣,以出错不报为耻。
  • 以局部变量为荣,以全局变量为耻。
  • 以单元测试为荣,以手工测试为耻。
  • 以代码重用为荣,以复制粘贴为耻。
  • 以多态应用为荣,以分支判断为耻。
  • 以定义常量为荣,以魔法数字为耻。
  • 以总结思考为荣,以不求甚解为耻

来自这里

欲望与追求

合格的开发人员,应该有自我提升的想法并且付诸行动,譬如下班后去学习一下新技术,在工作中,遇到不满的代码会尝试改进。人如果没有梦想,那和咸鱼有什么区别?

懂的交流

码农不应该是那种刻板的书呆子不善于交流的形象。技能分两种,软技能和硬技能,前者如人际交流、情感控制等,后者如对某种特定技术的掌握等。

人是群体动物,软件开发是团队协作,一个人难以完成一个系统,所以基本交流技巧必须掌握。

不管产品经理如何虐你千百遍,你还是得待他们如初恋,尽管一般都有比较苦涩的结局。

 

 

想知道为什么我这么多年来能掌握那么多种技术,不仅仅是广度,还有深度,达到我所说的“爆栈”吗?

在《爆栈之旅》,我根据大家都实际情况、水平、方向等规划职业路径,手把手带你做实战的项目,用最高效的办法达到你想要的高度。

爆栈之旅

是否想技术水平快速提升?是否希望快速成为公司的技术骨干?

核心价值
  • 把我这10多年来所学到的知识、总结的经验、吸取的教训分享出来
  • 针对不同的学生量身定制规划学习成长路线、1对1个人指导、代码审阅等
  • 解答各种技术问题
  • 为公司提供技术解决方案

请查看本站右边的信息联系我。

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。

爆栈思想 – 数据库“状态”字段如何设计

前言

之前在文章《学员问答精选 – 1 – 数据库表拆分》中提及过一个数据库的设计问题。今天,微博上的@火丁日记 说:

表里有一个 status 字段,用来表示数据的状态,比如订单的已付款,已关闭等。以前我习惯把它定义为 INT 类型,但是慢慢的,我就记不清楚 1,2,3 到底指的是什么意思了,也想过用 ENUM 类型,但是不方便扩展,最后,我觉得直接用 VARCHAR 类型算了,去它的三范式。

百家争鸣

  • 一些网友赞同使用varchar
  • 一些还是觉得应该enum
  • 一些觉得最原始的int是最好的
  • 一些觉得要用字典表

各种考量

其实,一个字段类型的考量,主要包括:

  • 准确性/精确性:必须能满足业务需求,不能丢数据,溢出等
  • 性能:一般来说,int的运算比varchar要快
  • 空间:尽可能占用最少的空间,一条记录浪费1字节,10亿记录就浪费1GB空间了
  • 辅助性:譬如方便功能上的排序、方便开发人员记忆等

如果要为开发人员着想:

  • 数据库里,表的字段可以添加描述,譬如0: Pending, 1. Paid, 2: Processing, 3: Delivered, 4: Cancelled
  • 如果不满足,那可以用char(1),26个字符足够表达各种状态了吧?不够就char(2),再不行就char(3),主要是省空间。为什么不用varchar(n)而用char(固定数值)?因为varchar(n)要运算做各种trimming,起码在SQL Server里,譬如len()就是后面空格去掉后的长度,和datalength()不一样。这个一般是单词的首字母,记起来比int舒服些。我发现一些公司就是这样做的。

如果要追求节省空间,完全可以用tinyint甚至varbinary,毕竟1个字节有8位,一般订单也就那么几个状态吧?

首先,如果用varchar,那么要考虑:

  • 你这个状态的值,是放英文还是中文?你的产品是否全球化的?
  • 如果是放英文,那你还是需要本地化。
  • 而且,既然要本地化,就没必要放完整的单词,char(1)便可,原因参考上面。

如果使用int,那么要考虑:界面文本显示,开发人员友好。

如果要考虑界面显示如排序等,一般来说,界面需要先根据条件过滤出来某种状态,但是,如果你的业务逻辑就是要同时显示多种状态的数据,这要考虑目标数据只是已经在界面的,还是在数据库的:

  • 界面:那数据库的类型还是最精简的varbinary(1),在界面对值进行解释然后根据解释出来的规则进行排序

当然,有些业务系统会使用字典表,相当于外键,如果返回结果的时候就join,这里会比case xx when 1 then ‘某状态’ 的效率要差些,而且字典表还是需要做语言本地化的。

总结

其实,不管用哪种方案,都没有完美的,还是应该具体业务需求来。

 

爆栈之旅

是否想技术水平快速提升?是否希望快速成为公司的技术骨干?

核心价值
  • 把我这10多年来所学到的知识、总结的经验、吸取的教训分享出来
  • 针对不同的学生量身定制规划学习成长路线、1对1个人指导、代码审阅等
  • 解答各种技术问题
  • 为公司提供技术解决方案

请查看本站右边的信息联系我。

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。

爆栈思想 – 时间都去哪里了?怎么高效使用时间?

苦恼

我的一个学员问我:“我已经入职了,有点苦恼,感觉现在一天没什么时间是自己的,不过公司这边就有安排导师就是带着我,现在在慢慢地熟悉一些东西。我现在还好,没负责什么项目,所以一天还有一些时间可以自己学习一下,可是看周围的人都感觉好忙,可能就没剩什么时间了,老师,您是怎么解决这个问题的?”

存在即合理

周围的人很忙没有时间剩下来?这不是正常吗?老板给钱你来上班就是努力干活啊,哪里有所谓的”me time”。

所以一般人想学新的东西,除非公司上新项目/改造系统,否则只能自己回家慢慢学,譬如跟我学 😉

专注

工作中,多样事情同时发生,譬如你写代码的时候,刚来公司的新人张三来请教你,可能还没有回答完,隔壁老王又来找你讨论产品的修改。

我们做个小游戏:你同时把左手放胸口搓圆型,和右手拍打脑袋,有点别扭,是吧?

同理,很可惜,很少人能同时应付多个任务,毕竟,你不是多核CPU可以并行计算,你顶多可以并发处理,就是跟CPU那样不断做context switch,在不同的项目中来回切换。

但是,这个的效果其实并不好,因为思路很容易打断,而且继续做的时候要思考一下之前做到哪里,接下来怎么做。

如果是你想合理控制时间,你需要把时间集中起来,某个时间段内任何其它东西都不做,只专注一样东西,这样更容易有实际的产出,譬如每天安排:

  • 上班中,多个30分钟,都只做一样事情
  • 下班后,30分钟看看新闻
  • 下班后,30分钟研究你的领域里的新技术
  • 下班后,30分钟做一下你的个人爱好
  • 下班后,30分钟刷一下社交媒体跟进一下好友动态

站在巨人的肩膀上

经过研究后还是不懂就马上问,别浪费时间,合理搜索正确答案和利用第三方解决方案。不要钻牛角尖,掉坑里爬出来可能是几天甚至几周之后的事情。

 

想知道为什么我这么多年来能掌握那么多种技术,不仅仅是广度,还有深度,达到我所说的“爆栈”吗?

在《爆栈之旅》,我根据大家都实际情况、水平、方向等规划职业路径,手把手带你做实战的项目,用最高效的办法达到你想要的高度。

爆栈之旅

是否想技术水平快速提升?是否希望快速成为公司的技术骨干?

核心价值
  • 把我这10多年来所学到的知识、总结的经验、吸取的教训分享出来
  • 针对不同的学生量身定制规划学习成长路线、1对1个人指导、代码审阅等
  • 解答各种技术问题
  • 为公司提供技术解决方案

请查看本站右边的信息联系我。

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。

爆栈思想 – .NET/C# 能力和使用范围

有同学质疑C#的能力和使用范围,我说,C#可以在多个平台跑,包括移动设备(通过Xamarin写iOS/Android)、嵌入式,智能设备、电视、冰箱(如三星Tizen)等。

还有同学说质疑:“说C#能写驱动吗?” 我说:“C#还可以写操作系统 ” (atomixos  和 cosmos)。然后这位同学说:“那java呢,不就更应该建议采用java了”

其实,这种争论,犹如:“飞机可以到处飞,为什么要汽车?” 般没有意义。

你要去探望在小溪的对面的邻居,你会走桥、坐船、开汽车、坐飞机还是乘宇宙飞船过去呢?拿一种技术不擅长或者不能做的事情说事,没有意思。

不同的场景用不同的技术。按照那种“那为什么建议采用xxx技术”的观点,那其它语言都没有存在的价值了,因为每种语言都有优缺点。

而且,我喜欢C#为什么就不能推荐/支持C#了?

我觉得很多技术人对.NET/C#有相当多的偏见,而且这种偏见还是刻舟求剑式的,他们不知道.NET生态开源了,不知道现在C#在多个测试中的性能比Java还好。

微软出的开源的Visual Studio Code,越来越多的在Mac/Linux上做开发的同学用这个了,最近参加几个meetup,做aws/nodejs等等,都用这个演示。

这种偏见,一部分来自对微软的不喜甚至憎恨,譬如最近微软收购了GitHub,有一些用户就马上迁移到GitLab,尽管之前GitLab丢过客户数据。

 

最近,我花了些时间,写了2万多字的《.NET前世、今生和将来》,全面讲解.NET生态圈的历史、作用和潜力,晚点发布。

 

 

 

想知道为什么我这么多年来能掌握那么多种技术,不仅仅是广度,还有深度,达到我所说的“爆栈”吗?

在《爆栈之旅》,我根据大家都实际情况、水平、方向等规划职业路径,手把手带你做实战的项目,用最高效的办法达到你想要的高度。

爆栈之旅

是否想技术水平快速提升?是否希望快速成为公司的技术骨干?

核心价值
  • 把我这10多年来所学到的知识、总结的经验、吸取的教训分享出来
  • 针对不同的学生量身定制规划学习成长路线、1对1个人指导、代码审阅等
  • 解答各种技术问题
  • 为公司提供技术解决方案

请查看本站右边的信息联系我。

版权所有

所有文章内容版权所有,任何形式的转发/使用都必须先征得本站书面同意。本站保留一切追究的权利。