我有一把新锤子,问题当成钉子看 —— 从实践来谈设计模式

相信大家都知道设计模式,很多人都能背出一些常用的设计模式,但是很少有人知道怎么去使用它。甚至有很多人觉得设计模式没有用,哪怕在很多高水平的程序员之间,面对设计模式到底是不是一种“屠龙术”也有着很激烈的争论。 今天文章主题我们不争论设计模式有没有用,而是通过一次具体问题的实践,来看看我们到底怎么去使用设计模式,怎么让一段代码演变得更有扩展性。 问题的开始我们假设这样一个场景,现在有一台物联人脸识别设

LoT设备分布式一致性处理实践 - 本地消息表

最近工作中我们新增了一批人脸识别设备,该设备支持http commet轮询以及MQTT的方式对接,综合各方面的优劣后,最终我们准备采用MQTT的方式来对接,同时我们也不可避免得遇到了分布式一致性的问题,在此做一次实践纪录。 在系统使用过程中,我们需要根据各自的权限设置,将系统中人员的白名单下发到不同的设备,后台系统通过MQTT将消息下发到设备,设备再通过MQTT将结果反馈到系统。同时因为设备的性能

Postgresql select count性能与Vacuum

最近在开发过程中遇到一个postgresql的问题,某张表大多数时候只有insert及select操作,该表建立了一个非聚集索引,但是通过该索引进行select count操作时,时间长达数十秒。通过查找资料,我们已经定位到了问题所在,这次我们就谈谈Postgresql的元组与vacuum机制。 Dead tuples(死元组)postgresql的表的一行数据通常被称为元组(tuple),由于表

Asp.net core 2 如何设置SnakeCase形式的QueryString参数

我在项目中设计Web Api规范时,决定将QueryString参数命名使用SnakeCase的形式,这就带来一个问题,SnakeCase与C#的通用参数命名格式有所冲突,举个例子: 12345678910111213141516171819202122public class SearchQuery{ public int Value_type { get; set;&#

ASP.NET core 2.1 API 认证与授权(1 - 使用JWT)

最近在为API重构认证与授权机制。之前在做api认证时,使用的是自己定义的Bearer token,不是很规范,因此决定使用JWT进行重构,记录一下相关知识点。 Authentication和Authorization首先,我们需要理清一下认证(Authentication)与授权(Authorization)的关系,否则在理解与查找asp.net core认证授权资料时会非常困惑,下面我会统一使

开发一个dotnet core站点安装器

最近接到一个任务,需要为系统开发一个安装包。我们的项目包含一个pg数据库,两个dotnetcore站点,一个桌面应用程序。大家知道,在windows平台上部署站点时,需要很多繁琐的手动操作,比如开启IIS,部署应用,修改配置,修改环境变量等等。但在给客户部署演示系统时,就显得很低效,需要实施过去帮忙,很多客户都是没有能力独自完成部署,因此就有了傻瓜式安装包的需求。 之前这些工作都是手动操作,虽然我

我为何还没有放弃C#

今天看到知乎的一个推送:我是不是应该放弃C#,看完各种答案有一些感触。 浏览之下发现除了少数几个情绪化的回答,大家的回答还是很客观的,总结一下,大家都不推荐刚毕业的新手去学习,原因主要是两点: 市场的需求量小,同时真正需求的公司发现从业的开发者又少,尤其是靠谱的开发者。 微软长期的政治不正确。 事实上,如果让我给一些新人推荐,我也不会推荐C#,那么我为什么还没有放弃C#,很简单,因为我克服了第

基于cake-build的dotnet自动化发布

最近公司项目开发完成,准备进行给客户部署试用,因此为项目的发布、打包耗费了心神。我们的系统包含三大项目:Restful Api、web管理站点以及一个桌面客户端,那么在发布新版本时,必须手动release三个项目,并且更改3个配置文件,然后复制到某个目录中。操作简单,但是一旦发生频繁的发布,不可避免得会出现疲劳、抗拒等等负面情绪…因此自动化这一工作成了刚需。 由于公司的资源限制以及团队规模较小,没

2017年码上那些事

2017年将要过去,截至元旦,最后一位90后也已经成年了,而我,也由一个翩翩少年,逐渐成为更加成熟的青年,就酱。伤感完毕,还得是一年一度的年终总结,行己勤劝须自省。 新的工作今年年初,我以一份新的工作开始新的一年,现在回顾,感觉非常满意。工作内容上,得到了一定的决策权,包括进度管理、项目管理、技术框架的抉择,也通过与其他各部门的工作交流,在沟通能力与技巧上得到了一定的提升。待遇上,老板对我很宽容,

Docker中部署aspnet core应用

准备将asp.net core 2.0应用部署到docker中,将过程予以记录。Docker的介绍和安装不再赘述,我所用平台是Ubuntu 16.04。附安装手册。 准备应用代码首先我们需要准备应用代码及Dockerfile,并且确保dotnet run可运行,示例代码结构为:12345- Myapp - Myapp.Core - Myapp.Api - Myapp.sln

wpf经典空域问题

我们开发WPF应用时,有时不可避免得需要在其中承载WinForm控件。那么这时会出现一些问题,由于WPF与WinForm界面的渲染方式截然不同(我在上一篇文章中有具体阐述),所以呈现方式也必然是分开的,也就造成WinForm控件必然在所有WPF控件上方置顶。假如我们这时使用了诸如flyout、modal、popup之类需要置顶的WPF控件,就会出现一种奇怪的现象,WinForm控件会将这类popu

解决获取WPF控件句柄问题:在WPF中承载WinForm控件

基于需求,我需要获取WPF的某控件的句柄。 搜索过后得到一些关于HwndSource的代码示例,然而通过尝试发现,此类代码获取的只是Window的句柄,而我需要的是UserControl的句柄。事实上,获取WPF UserControl的句柄是根本不可能的。大家应该都知道,要获取WinForm控件的句柄相当简单,是因为WinForm是通过GDI+来渲染界面,每个控件都拥有自己的句柄,但是WPF的界

怎样写好个人博客

相信很多开发者从毕业开始,就曾想维护一个个人博客站,或许是基于兴趣,或许是为了把自己与咸鱼区分开,又或许只是觉得这是一件很酷的事,告诉周围人自己并不是一个修电脑的。但是由于各种各样的原因或者借口,很多人都没有坚持下来。根据和一些小伙伴的交流,相当一部分原因是不知道博客要写些什么,今天就和大家聊一聊怎么去写博客,写些哪些内容,分享一下个人的微薄经验。 技术博客可以写些什么内容技术问题的解决维护博客初

读《白鹿原》之杂言

那段历史,真的不能了解得太过深入,每次触及,尽是深深的无奈。 新文化、新思想的运动,是进步,亦是退步。在教科书上,我们只能看到其带来的正面影响,冲击着不再适应历史的社会形态,带来的正向的社会变革。然而,在煽动人民进行革命的同时,充斥着大量的道德、伦理败坏。革命要靠人民,可怕的是,大部分人民并不具备对新思想的正确理解能力,进而造成许许多多可怕的灾难,人已非人。 无疑,底层群众是易煽动的,也是愚昧的,

GRPC琐碎

记录一些grpc使用过程中的体验、坑及技巧,Server及Client语言都为C#。 体验: 搭建简单,一次尝试即成功。 分布式好伙伴 技巧 server意外掉线后重新上线,client将会自动重连,不需要自己处理。 利用streaming功能,可快速实现推送服务器,即观察者模式。之前有做过利用rabbitmq消息队列中间件实现消息推送,或许可以用grpc streaming替代,无论性能、复杂

开发之短期效率与长期效率

工作中接到需求并着手开发时,我们通常会有两种选择,我将这两种方式分别称为追求短期效率与追求长期效率。 短期效率我们假设这样一个场景,当你接到一个开发任务时,上司会交代:三天内必须完成,更有甚者:今天必须完成。可事实上,所有人都清楚,这个任务根本不可能在本周内完成。需求不明确,按照某某某的样子抄;这个地方逻辑可能会有特殊情况,先不管碰到再说;这部分代码很乱,可能性能还很差,不管了先这样。终于,在你吭

mysql5.6 升级到 mysql5.7遇到的问题

最近从MySql5.6升级到5.7版本,踩到一些坑,在此记录。 sql_mode=ONLY_FULL_GROUP_BY项目中某些sql报错1234ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUPBY clause and contains nonaggregated column 'mydb.t.addres

一次面试风波

10月27日夜,我在溧阳准备第二天的科目二考试,刚吃过晚饭,和其他学员出去溜溜解解闷,谁知接到一个猎头的电话。 “你好,我是xxx公司的猎头xxx,我这里有一个asp.net的工作岗位,不知您最近有考虑换工作吗?”说话的是一位略微带着粤语口音的女性,音调很是好听,不过我是不会受到魅惑的。 “不好意思,最近应该不会换工作,最早可能也要年后才会考虑。”这是我最近面对hr的统一回复用语,假如过几个月还能

水果与价值

今晚回到家,家中正招待客人。其间父亲剥开柚子分给大家吃,然而大家一致觉得这柚太酸,汁也不多,唯一的优点是吃完不粘手,可谓是渣渣中的极品。脑海中的第一念头是不好吃就扔掉,这时代谁还在乎一柚子。却见大家仍然吃得很香,大概是父辈的人都很节约吧。 但转而一想,有次我自己买了几个油桃,口味酸而转苦,还涩。奇怪的是,当时我并没有愤怒得扔掉,反而津津有味。想来平时我并不节约,不喜欢的东西说扔就扔,我为什么会吃下

做一个有灵性的程序员

从业到现在三年多,我的职业生涯可以算是比较顺利的,几乎没有大波折。当然,也有可能是因为当时扛过挫折之后,再回头看已经算不上什么了。 刚毕业时找了一家小公司,沉淀技术。之后面试去了无锡某公司,这是一段令我印象深刻的经历。当时因为面试表现好,hr给我要求的薪资额外加了25%,然而一周后,因为无法适应技术支持岗位申请离职。出乎我意料的是,公司考虑到我这周的表现不错,立即把我调到开发岗。半年之后,由于压力

记一次gitlab webhook使用实践

背景最近我们团队将git服务器全部迁移到gitlab上,出于某些考虑,我们将所有项目的master分支设为受保护状态,小组成员只能对dev或者其他分支推送代码。当需要发布版本时,都需要组长将代码合并到master,这样当频率一高,组长必然会不断得被打断工作,从而影响效率。 刚开始时我想利用git alias或者批处理来解决这件时,然而细想,如果还是需要我来敲一行命令或者打开批处理,仍然没有解决问题

MySql由child找parent

记录sql: 123456SELECT s.*, @code :=(SELECT ParentCode FROM mytableWHERE Code = @code) AS tmpFROM (SELECT @code := 10) varsSTRAIGHT_JOIN mytable sWHERE @code IS NOT NULL;

cs文件推送到git-server中文乱码问题

昨天碰到一个问题,某个cs文件push到git server后,里面的所有中文(包括注释和字符串)全都变成了乱码,猜测是编码问题导致,于是将其编码格式从’uft8’改成了’utf8-bom’,再push上去就正常了。BOM(Byte-Order Mark,字节序标记)是Unicode码点U+FEFF。详情参考典型乱码。 至于怎么改编码格式,如果是用vscode,点击右下角编码格式信息就能切换。如果

Linux命令行利器Tmux

简介Tmux是一个优秀的终端复用软件,即使非正常掉线,也能保证当前的任务运行,这一点对于 远程SSH访问特别有用,网络不好的情况下仍然能保证工作现场不丢失!此外,tmux完全使用键盘 控制窗口,实现窗口的切换功能。 安装1sudo apt-get install tmux 安装完成后用“tmux”命令启动。 配置在~/下建立”.tmuix.conf”文件1234567891011121314151

如何写好单元测试

我们都知道为模块编写单元测试有很多好处,比如保证软件健壮,建立团队信心,快速定位bug等等,但是许多程序员并不知道怎样写出一个规范的单元测试。事实上,一个无效的单元测试并不能带来如上所属优点。 这里,我想跟大家讨论下怎么写好一个单元测试。我们不扯如何测试,大家可以找一些书看;也不聊具体的测试技术,比如mock和stub,我们只讨论在代码层面上,应该写些什么东西,才能成为一个有效的单元测试。 首先我

知之不如好之:为什么要阅读开源代码

从业软件行业三年,发现身边的很多程序员都讨厌阅读代码,哪怕他们都很喜欢写代码。确实写代码就像画一副作品,是一件愉快有趣的事,而阅读他人的代码,则显得非常艰难、无聊。哪怕是阅读自己几个月前写的代码,都有可能是一种折磨。所以,为什么我们要浪费几个小时、几天、几周来读别人的代码,我们可以用这些时间写一些对我们来说very awesome的代码。 对于我个人,就很喜欢阅读他人的优秀代码。或者说一开始只是为

利用Unity进行AOP编程: 策略注入(三)

前言上一篇文章里,给大家介绍的利用Unity拦截进行编码实战,那么本编文章将给大家演示一些更高级灵活的使用。 策略注入首先我们先展示一段利用策略添加拦截行为的代码,然后我们再来分析。1234567891011121314151617181920212223242526272829303132container.RegisterType<ITenantStore, TenantStore&gt

web api 自定义返回对象的字段

由于前端的需求,我们需要自定义返回对象的字段,以减少不必要的网络开销。 假设我们有这样一个类12345678910111213public class Foo{ public string A { get; set; } public int B { get; set; } public bool C { get; se

利用Unity进行AOP编程: 拦截器实战(二)

前言上一篇文章里,我们介绍了Unity拦截器的基本概念,本编文章我们将利用它来进行实战。 在Unity Container中配置默认情况下,Unity Container不支持拦截器,因此我们得显式地将其加入到项目中,当然,首先得通过NuGet安装扩展包。12345using Microsoft.Practices.Unity.InterceptionExtension;...IUnityCont

Debian 8安装可能会出现的问题

apt-get提示磁盘插入apt-get时会出现类似以下错误Media change: please insert the disc labeled 'Debian GNU/Linux 7.3.0 _Wheezy_ - Official i386 DVD Binary-1 20131215-03:40' in the drive '/media/cdrom/' a

我的vim黑科技

用以记录我的vim技巧。 回到屏幕中间NORMAL模式下按zz,可以使当前光标所在行处于屏幕中间。 ctrl-o, zz在INSERT模式下,按ctrl-o将会回到NORMAL模式,此时将可以执行一次NORMAL命令,执行完毕后回到INSERT模式,可与zz配合使用 将外部命令执行结果放到当前文本中来试试1:.!ls1:.!dir 执行python代码在任何格式的文本中,想插入一些数据,只需写一小

个人开发者如何巧用消息队列

提起消息队列,我们很容易就想到redis,rabbitmq等在企业中很常用的消息队列。但是在“个人开发者”这个属性前提下,我们可能根本没有服务器去部署redis或者rabbitmq,即使有个vps/云服务器,也无法保证其稳定性——可能哪天嫌维护麻烦就直接停掉了。当我们开发一些有意思的小工具,并且需要用到消息队列时,往往会操碎了蛋。 今天我就介绍两种方案,寻找身边的资源做消息队列。 云盘前段时间我在

Restful api url设计建议

基本CRUDGET /users - 获取user列表GET /users/12 - 获取id为12的userGET /users/12/address 获取id为12的user的address字段GET /users/12?fields=id,name,address 获取id未12的user,并只返回id,name,address字段POST /users - 创建userPUT /users

利用Unity进行AOP编程: 概念介绍(一)

前言在读这篇文章之前,建议大家要对Unity容器进行依赖注入有一定了解与实践,并且了解一些常用的设计模式。这里我们主要介绍如何利用Unity进行AOP编程。面向 Aspect 的编程(AOP)是一种新的编程技术,它允许程序员对 横切关系(crosscutting concerns)(跨越典型职责界限的行为,例如日志记录)进行模块化。 横切关注点(Crosscutting Concerns)传统的程

利用反射映射数据库对象(二)

在上一篇文章里,我们里用反射,将数据库的查询结果集映射到对象中,以减少代码。现在我们就利用相同的原理来完成更新记录的操作。 更新记录时,我们需要知道表名,主键名,主键值,以及需要更新的字段信息。最初阶段,这些信息我们只要通过参数传递到方法中。1234public int Update(string tableName, string primaryKeyName, object entity)&#

在Docker中部署nodejs应用

介绍 & 安装关于Docker的介绍与安装,这里就不再细写,请利用搜索引擎,或者参考What is docker, 安装手册。为了方便,我直接在DigitalOcrean部署了一个docker环境。 获取应用代码准备一个应用,这里我用了一个简单的express应用,并侦听4000端口。https://github.com/NeilQ/cTemplate。将代码获取到本地目录,并进入。12g

web api 对[serialiable]特性的对象序列化问题

web api 2 中, 假如返回对象加了[serializable]特性,返回的json、xml数据都是包含对象的私有变量,而非公有属性,如:12345678910111213141516171819{ "Total": 1, "Data": [ { "_ticketnumber": "

gitlab 7.13 502 issue

单核服务器在gitlab重启之后常常会出现502错误,是因为”unicorn”启动比较慢,造成延迟引起的。我们可以手动执行以下命令解决:12sudo gitlab-ctl hup unicornsudo gitlab-ctl restart sidekiq

CentOS上安装配置MySql

安装并开启执行命令:12sudo yum install mysql-serversudo /sbin/service mysqld start配置安全信息:1sudo /usr/bin/mysql_secure_installation 设置iptables以启用远程登陆执行命令:12345iptables -A INPUT -p tcp --dport 3306 -m state --stat

web api 2 - 自定义help page的返回类型

当我们用HttpMessageResponse或者IHttpActionResult作为返回api的返回类型时,帮助页面的返回类型相应得也变成了HttpMessageResponse或者IHttpActionResult,而这不是我们所期望的Product、User等实际的返回实体。幸运的是,这是可自定义的, 简单得我都不好意思讲。 方法一(推荐)为方法添加一个属性[ResponseType(ty

利用反射映射数据库对象

12345678910111213141516171819202122232425262728public IEnumerable<User> GetUsers(){ var conn = ""; using (var sqlConnection = new SqlConnection(conn)) { using

如何让测试脱离vs跑自动化测试

为什么要脱离vs跑自动化测试?这本就是个矛盾的问题,负责自动化测试的Test必须要有阅读、审查、修改代码的能力,才能保证测试结果的有效性。但实际情况中测试人员普遍没有这种能力,有代码能力的测试要么在大公司,要么都转开发去了(吐槽)。在这种情况下,让测试去跑自动化,就如同一个不识字的少年捡到一本九阴真经秘籍,却因不识字而毫无用处。那么我们需要做的就是让秘籍变成图谱。 Visual Statio是开发

自动化测试思考

鉴于之前公司的测试经验,在加入新公司头半个月,Manager让我试着对现有业务建立自动化测试机制。于是便有了这篇文章,关于如何去做,如何做好自动化测试的思考。 Life is short, 我们直入主题。 了解系统层级,代码层级作为测试人员,我们首先需要知道系统的层级、架构,或者代码的层级,来规划测试管理方案。举个例子,作为一个web项目,假如说我们的系统分为WebUI,数据接口,DB。 Web

表值参数

表值参数(Table-value parameter)可以将.NET中的DataTable类与SQL Server Table类型进行映射,可以把多行数据作为参数传递到存储过程,进行批量操作。 简单举个例子,假如我们有这样一个表:123456CREATE TABLE [dbo].[People] ( Id INT IDENTITY PRIMARY KEY, Name NVARC

Python Web框架选择小记

前段时间用python flask写了个Markdown blog,初始选择平台及框架的时候,着实纠结了一番。今偶有所感,特此记录。 写这个blog程序初始目的是为了练手,当然,我必然是希望自己的作品能够实际部署的。由于不想折腾不成熟的mono,首先排除了专长技术Asp.net, 另外本人对Python十分喜爱,便把目光瞄向了一些Python的主流web框架:Bottle, Django, Fla

.NET性能之遍历List<T>

最近对.NET项目进行性能优化,在开启编译器优化的前提下,对List对象遍历的不同方式进行了简单的研究和对比,以此记录。首先我们创建两个不同类型的List对象,各自塞了5000000个简单元素:1234567var listInt = new List&lt;int&gt;();var listString = new List&lt;String&gt;();for (var i = 0; i

闲言碎语--回顾毕业设计

不知发了什么疯,今日突然想起1年多前的毕业设计,也许是因为今天遇到了人生中的第一个猎头,有些矫情和感慨。毕业设计课题确定时,我有着美好的愿望,想让自己及大家把知识分享出来,加上平时上完课总是问好多人都不知道课后作业(汗颜),那时的我脑中还没有“信息平台”的概念,于是一个“文件分享系统”的想法便出来了。 于是乎,为了这个美好的想法,我傻傻得调查用户对这一想法的需求,冥思苦想大家怎样能舒适便捷地获得

Use Event-Driven with javascript

Let me recommend using publish-subscribe pattern to refactor JavaScvript codes in Web development, base on Javascript Event Driven. Goal To manage specific JavaScript method\events for web applicatio

为何秋冬露腿比夏天更容易让人眼前一亮

生活中,很多男性朋友(比如婶儿、贱神、海爷、翔书记)都会觉得姑娘在秋冬露腿比夏天更容易吸引人的眼球,那么问题来了,这到底是为什么呢,且听鄙人为您浅析: 物以稀为贵这是在很多领域都存在的定理。秋冬的寒冷会让很多爱美的姑娘望而却步,包裹起丰腴的大腿,在整个晤冬的大势下,露腿的姑娘便是寥寥无几。因此对于很多男性来说,在长久没有过瘾的情况下,突然看见一双白花花的大腿,必然深觉眼前一亮,目不转睛了。不同于

在WCF Uri中使用特殊字符

当我们在iis中部署wcf时,我们会因为各种原因遇到无法在url的schema中使用一些特殊字符:%,&amp;,*,:,&lt;,&gt;,+,#, /, ?,\ 即使通过uri encode, 这些特殊字符仍无法被当作普通的string,如果我们想通过url传递这些特殊字符,需要在web.config中进行如下配置: 12&lt;httpRuntime requestPathInvalidCh

初建博客

很早就有搭建自己的博客的想法,来督促自己学习,记录心得。作为一个程序员,也有着自己的骄傲,希望有自己的博客作为旅途痕迹,同时又不希望将博客搭建在第三方平台上,将自己的知识版权与其共享,尽管只是些不如高人法眼的东西。 因此尝试过云服务器,wordpress, 注册域名。 但由于备案繁琐,不喜欢PHP,前段时间工作变更等种种原因,一直没有搭建起来。最近在偶然情况下,发现 Hexo + Github 的

python在windows中mimetypes初始化失败问题解决

很多人反馈python2.7在windows中经常会出先如下错误信息:12345678910File &quot;C:\Python27\lib\SimpleHTTPServer.py&quot;, line 208, in SimpleHTTPRequestHandler mimetypes.init() # try to read system mime.types File &quo