编程
文章平均质量分 68
Runyon1982
擅长Java、C++,全栈开发者
展开
-
异常还是错误码,这是一个问题
一个现实的程序离不开错误处理。错误处理使用异常还是错误码,这是一个方法论的问题。方法论的问题都是可以扯皮的。事实上,某个时期这两者之争不亚于语言之争。公说公有理婆说婆有理。现在我只想说说我的几点认识,自认为还是比较中肯的: 1)不用异常可以写出很健壮的程序,c里面没有异常,很多c写的程序十分地健壮。 2)使用异常可以写出很健壮的程序,java基本上都是靠异常来错误处理,很多jav原创 2015-10-10 09:18:27 · 2317 阅读 · 1 评论 -
解决RabbitMQ队列超长QueueingCons…
我们的服务器使用RabbitMQ作为消息中转的容器。某天我怀疑RabbitMQ队列是否都能及时消化。于是用命令查询了下:rabbitmqctllist_vhosts | grep -P ".*\.host" | xargs -i rabbitmqctl list_queues-p {} | grep "queue"。 不查不知道,一查吓一跳:大多数服务器的队列基本上都是空的,但是有些服务器的原创 2015-10-10 09:24:12 · 4419 阅读 · 1 评论 -
并行计算:近来语言发展的趋势和我…
早上收到CSDN的邮件,内容与英特尔的Cilk技术有关。“Cilk 技术让C/C++程序员更容易地编写多线程程序,继而充分利用多核处理器的计算能力,它已被集成到英特尔 Parallel Composer2011(Beta)中。” 可以说近年来并行计算(在本文中就是多线程程序,但不如并行计算来得装13,所以大家常不爱用)一直是计算机界的热点。有的解决方案是诉诸于另一门语言如erlang原创 2015-10-10 09:19:40 · 2126 阅读 · 0 评论 -
如何将同步调用转换成异步调用
同步/非同步本来是IO方面的概念,不过我们可以把函数乃至各种RPC理解成一种IO设备,这样就可以把这两个词扩展到函数调用领域了。同步的函数调用指的是当函数调用返回的时候,需要函数干的事已经完成。而异步调用则没有这个保证,工作可能在函数返回前完成,也可能在之后某个时刻。 同步/异步很容易跟阻塞/非阻塞混淆起来。严格说起来它们是有区别的:阻塞的调用指的是当前提满足的时候干活,不满足的时候等到原创 2015-10-10 09:22:03 · 3641 阅读 · 0 评论 -
代码复用之道:回调机制及c++实现…
首先要严正声明:这里的回调机制不等同于回调函数,而是代表了软件先进生产力的发展要求,代表了先进设计模式的前进方向,代表了广大软件开发人员的最根本利益。 再来说个笑话:古来时常听说回调,我也还记得,可是不甚清楚。我翻开书籍一查,这书籍没有年代,歪歪斜斜的每页上都写着“设计模式”几个字。我横竖睡不着,仔细看了半夜,才从字缝里看出字来,满本都写着两个字是“回调”! 好。言归正传,编程原创 2015-10-10 09:18:58 · 572 阅读 · 0 评论 -
Interface(Java关键字)天然是接…
看到这个题目,会不会觉得我精神错乱了?Interface不就是英文的接口吗?先说明下本文所有的“Interface”指的是Java的关键字interface所代表的概念:对于C++来说就是只包含纯虚函数的抽象类。 最近在JavaEyes看了篇挺好的文章:《关于Java开发不明白的一些问题》。里面包含了对Java一些领域过度包装,过于奇技淫巧的“主流”做法的思考。这不禁让我想起C++狂吹原创 2015-10-10 09:21:42 · 422 阅读 · 0 评论 -
对客户端/服务端开发的随想
从某种意义上来看,可以把所有客户端/服务端程序理解成远程数据同步程序。抛开各不相同的业务逻辑,它们总是把某些数据从客户端同步到服务端,或者从服务端同步到客户端并显示出来。比如你用QQ发了一个群消息。则消息这个数据从客户端同步到服务端,然后同步到该群所有的客户端,最终显示给这些用户查看。所以如果有一个“万能同步机制(同步且只同步需要同步的)”,客户端/服务端程序员的工作就轻松多了(于是这些倒霉蛋都被原创 2015-10-10 09:22:42 · 458 阅读 · 0 评论 -
顺藤摸瓜研究应用程序如何监控文件…
之前写过服务,需要动态加载配置文件。做法是后台启动一个线程,每隔一段时间看下文件是否发生了变化(通过大小+最后修改时间),如果有变化就重新加载。可用是可用,但感觉效率不高也不够及时。最近听闻JavaNIO可以监控文件。Java 7 NIO.2 文件监视服务简介 。 看一下类图: 具体实现有:Windows的版本,Linux的版本,轮询的版本。这就很有趣了,说明Win原创 2015-10-10 09:23:48 · 437 阅读 · 0 评论 -
升级CentOS6.6后Java新建线程抛出O…
原来Java服务运行在CentOS5.4上正常,最近部署到CentOS6.6服务器上。结果运行一段时间后,程序在执行新建线程操作的时候抛出异常:“java.lang.OutOfMemoryError:unable to create new nativethread”。这种情况一般是因为JVM内存不足,通过调整JVM内存参数就能搞定。但是我们的Java服务已经分配了很大的内存,当前实际使用并不原创 2015-10-10 09:24:14 · 625 阅读 · 0 评论 -
多线程设计模式:Future模式
我觉得很多讲Future模式的文章并没有深刻理解Future模式,其实Future模式只是生产者-消费者模型的扩展。经典“生产者-消费者”模型中消息的生产者不关心消费者何时处理完该条消息,也不关心处理结果。Future模式则可以让消息的生产者等待直到消息处理结束,如果需要的话还可以取得处理结果。 但是Futrue模式有个重大缺陷:当消费者工作得不够快的时候,它会阻塞住生产者线程,从而可能原创 2015-10-10 09:20:52 · 642 阅读 · 0 评论 -
如何将异步调用转换成同步调用
上上篇文章演示了如何将异步调用转换为同步调用。本篇文章则演示了反过程。为何我们需要将异步调用转换为同步调用?这往往是为了获得编程的便利性——前文说过异步调用比较反人类。如果底层是异步的,转换为同步一般会损失性能。所以这种做法较少用于服务端,一般用于客户端。 如果是体位2的异步,很简单,反复查询直到OK即可,两次查询间sleep。一般sleep时间设置为可以容忍的延迟时间。sleep时间短原创 2015-10-10 09:22:08 · 4969 阅读 · 0 评论 -
四种很相似的设计模式(State,Str…
以上四种设计模式其实是很相似的。在我看来: 1)State模式和Strategy模式可以视为一样的模式,他们的类图之类都是一模一样的。 2)Bridge模式和Strategy模式摆在一起可能让人觉得诧异,因为前者是结构型设计模式,后者是行为型设计模式。但如果不考虑这点。他们就非常相似了:以书中Bridge模式的例子(我记得不清楚了,只能说个大概),draw接口中的函数,有windo原创 2015-10-10 09:22:16 · 1281 阅读 · 0 评论 -
二路归并算法用于模块间增量更新
归并算法在现实编程中是一个比较重要且常用的算法。why?因为使用它可以简单高效地实现模块间的增量更新。 设想一下,我们有一个会议软件,在界面上有一个人员列表控件显示会议室成员姓名、状态等信息。如果不使用归并算法,当会议成员信息发生变化的时候,我们有两种方式来刷这个列表:1)使用粒度细的通知:XXX进入会议室;XXX更改状态为YYY;XXX更改名字为YYY……,这么做运行效率是高的,但是开原创 2015-10-10 09:22:18 · 260 阅读 · 0 评论 -
DevOp经验谈:服务故障排查的第一…
近来接手了一个比较大型的项目,由于系统内部服务数量较为众多,且没有物理机或者虚拟机的隔离措施。导致系统出现故障的概率大大增加,带给维护很大的压力。最近这段时间也是久病成医,现在总结服务故障排查的一些经验,在此文和大家分享下。 我有些时候会对技术人员提出这样的问题:如果服务出故障了,比如http服务无法返回或者返回很慢,应该要怎么排查? 大多数的人的回答是到服务器上看日志。其实这个答案并不原创 2015-10-10 09:24:05 · 620 阅读 · 0 评论 -
多线程vs多进程(分析、比较和建议…
准备培训教材,想带过这一点,又懒得自己总结,于是跑到网上乱看。发现在这点上存在太多误会。虽然评论中不乏真知灼见,但作者基本都没有说到点上。 误区1:把并发的难度归结到多线程or多进程身上。比如像锁之类问题,如果某个模型很难实现和规避,另一个模型也好不到哪里去。如果某个模型很容易搞定,另一个模型最多复杂一点点。比如某个应用多进程时不需要用锁,那好,多线程程序用TSS,也就多一个锁,能复杂到原创 2015-10-10 09:20:07 · 460 阅读 · 0 评论 -
谈谈网络编程中应用层(基于TCP/UDP…
对于初涉网络编程的开发人员来说,在通信协议的设计上一般会有所困惑。一般的网络编程书籍上也较少涉及这方面的内容。估计是觉得太简单了。这块确实是不难,但如果不了解,又很容易出篓子或者绕弯路。下面我就来谈谈基于TCP/UDP的协议设计。 1、基于TCP的协议设计 TCP是基于流的协议。但大部分网络应用一般会有个更小的处理单元,我们称之为帧(FRAME)。是否分帧 如上原创 2015-10-10 09:23:03 · 691 阅读 · 0 评论 -
关于代码注释的认识更新
对代码注释我的认识有过几次改变。 刚工作的公司对注释有所要求,鼓励大家多写注释,作为新人也就接受了这种观点,可能也写了不少“这个类是用来打印hello,world”的废话注释呵呵。或者“inti = 0; //这个变量用来保存用户年度缴纳金额之和”这种不注重变量/函数命名而是使用注释来说明的错误写法。 后来开发经验渐长,受一些最好的注释就是没有注释的思想影响,倾向于不写原创 2015-10-10 09:23:21 · 463 阅读 · 0 评论 -
MYSQL实践心得:table_open_cache…
MYSQL默认的table_open_cache为64,这个数值是偏小的,如果max_connections较大,则容易引起性能问题。 表现:数据库查询效率慢,showprocesslist 发现比较多的查询正在opening table。 进一步确认,执行以下语句:mysql> show global statuslike 'open%tables%';+--------原创 2015-10-10 09:24:02 · 774 阅读 · 0 评论 -
DevOp经验谈:直接操作线上数据库…
首先声明尽量避免这么干,直接动手修改线上数据库是很没有节操的运维方式。当你这么做的时候,得认识到这不是一个好主意,是否有可能避免?比如很多这种问题是由于同步错误导致的,举个例子:写入mysql的时候,由于ooxx的问题,写入redis缓存失败,最后导致redis里的数据和mysql不一致。这种时候,应该要写一个校正的工具,根据mysql的数据重新生成redis缓存数据。 但有时候,直接修改原创 2015-10-10 09:24:07 · 1731 阅读 · 0 评论 -
Java、IOS、C之间进行RSA密文传输
有了之前三个终端进行AES加解密的经验,实现RSA加解密倒不是太复杂。两个关键点:1)RSA需要密钥文件,且密钥文件的格式很重要;2)padding方式需要一致,比较被广泛支持且被很多RAS实现设置为默认padding方式的是PKCS1PADDING V1.5,建议采用。 我是在linux下用openssl生成公钥、私钥文件的,分三个步骤,命令如下: 1、生成公钥pub原创 2015-10-10 09:23:53 · 954 阅读 · 0 评论 -
"《英雄联盟》支撑最高750万同时在…
今天在CSDN上看到《英雄联盟》支撑最高750万同时在线用户的聊天服务打造 一文。因为这一年多来,自己主要在做一款IM产品,对其他IM产品比较关注,所以在此做做笔记和写下读后感。 1、高性能:“支撑750万并发用户,2700万日活跃用户,每秒钟需要处理的消息上万条,每台服务器每天处理消息达十亿条。”,"每个Chat服务器都可以支撑数百万连接数。"。单服务器能支持的并发连接数和Whats原创 2015-10-10 09:23:35 · 562 阅读 · 0 评论 -
SQLite批量插入和其他一些使用心得
SQLite是我在客户端上使用得最多的数据库,方便易用稳定强大,其支持很多的平台和语言:我分别在Windows(C++、QT)、Android、IOS上开发过使用SQLite来保存客户端本地数据的应用。下面说说对使用SQLite的一些心得。 1、批量插入。很多人发现使用SQLite插入大量数据的时候非常慢。我有印象刚使用SQLite的时候发现插入2000条数据(10列左右)居然要好几原创 2015-10-10 09:23:38 · 1257 阅读 · 0 评论 -
对开发日志的一些心得
开发日志是很能体现一个开发者能力和逻辑思维的项目。写得好的程序,日志有序完备,能够用于跟踪关键路径,方便定位问题,有时还可以帮助进行性能优化。而比较差的代码,要么日志残缺不全,要么絮絮叨叨还把握不了关键路径,无助于定位问题。本文主要讲讲我对开发日志的一些心得。 1、使用不同级别的日志,关注高级别缺陷日志 现在很多开发环境的日志类提供了多级别的日志输出(如果没有日志类或者日原创 2015-10-10 09:23:45 · 3136 阅读 · 0 评论 -
建议编程时不要注释无用代码
工作中,发现很多程序员习惯注释掉旧代码。我是不赞同这种做法的:我建议如果这些代码还有用,就将其提取出来,变成函数/类等会编译的单元,如果没用了就直接删除。不然日子久了,往往代码中充斥着大量旧代码注释。造成额外的维护负担:谁都不记得这些注释的作用了,又不知道能否直接删除。即使知道这些代码的作用,要用的时候反注释后可能也是一堆编译错误,未必比重写好多少。 额外的负担其实还不是主要原因。其实更原创 2015-10-10 09:22:49 · 4621 阅读 · 0 评论 -
程序员应该具备的能力
好的程序员我觉得需要具备以下五方面的能力:1、组织代码的能力 。有能力将代码组织得结构良好没有坏味道(参考《重构》一书)、模块内高内聚、模块间低耦合。2、操作数据结构的能力。实际应用开发一般不要求ACM题做得多好多快,但要能熟练掌握常用数据结构和算法。很多人说使用类库就好了,很多时候确实如此,但如果连名字都不知道怎么找到类库呢?数据结构的原理都不知道怎么对比评判以做出选择呢?而且如果连个二原创 2015-10-10 09:23:33 · 686 阅读 · 0 评论 -
变量和函数是否应该设置为static
面向对象的语言中变量和函数可以设置为static,这样就隶属于类本身而不是类的实例对象。一般来说: 对于普通变量,更倾向于设置为非static,因为static的类变量是全局变量,全局变量的弊端大家应该都了解。常见的一个编程错误就是错误地是用来了static变量,结果几个实例对象相互影响导致错误。 对于常量变量,更倾向于采用static的方式,再加上const、final修饰。因为原创 2015-10-10 09:24:00 · 541 阅读 · 0 评论 -
笔记:哈希ABC(含我对字符串获得64…
经常用hash,但从来没有自己实现过。因为我懒得自己造轮子,或者简单说:懒。 今天想到几个关于hash的问题,通过看源代码的方式解决了,发现自己要实现一个hash也很简单啊。 1)对于整型数据和字符串数据最常用的hash函数是啥? 答:其实就是整数求余,hashcode=key%size。如果key不是整型怎么办?瞎搞成整型呗。(另外即使一开始是整型,也可以瞎搞一下,may原创 2015-10-10 09:17:58 · 520 阅读 · 0 评论 -
《设计模式》旧书重读和总结:创建…
前面一篇文章我开头说,《设计模式》这么书翻来覆去地看,就只看出两个字“回调”。一方面是为了搞笑,但也并不全属信口开河。因为大部分模式都是基于多态,我认为多态其实就是面向对象提供的回调机制。 下文我对照经典书籍《设计模式》,讲讲我对23种设计模式的理解。 按照顺序依次说吧: 1) AbstractFactory(抽象工厂)模式:其实就是用来创建对象的strategy。可以原创 2015-10-10 09:19:00 · 289 阅读 · 0 评论 -
多线程程序中死锁的分析和解决方案
死锁是由于不同线程按照不同顺序进行加锁而造成的。如:线程A:对lock a加锁 => 对lock b加锁 => dosth =>释放lock b =>释放lock a线程B:对lock b加锁 => 对lock a加锁 => dosth =>释放lock a =>释放lock b这样两条线程,就可能发生死锁问题。要避免发生死锁,应该使用同一个顺序进行加锁。这点在对象单向调用的情况下原创 2015-10-10 09:20:04 · 1345 阅读 · 0 评论 -
组合未必优于继承
因为我曾经坚信“组合优于继承”,“只要implement,不要extend”。写这篇文章,某种意义上算是对我曾经有偏见的继承/多继承道个歉,以后我会将它们加入常规武器中。 我和很多面向对象初学者一样,都经历过滥用继承的阶段。我刚开始学习面向对象,使用的是C++,开发时最主要是使用类来划分程序模块。因为用继承来扩展一个类十分方便而直观,所以我和很多面向对象的初学者一样十分喜欢使用继承。但是原创 2015-10-10 09:22:47 · 404 阅读 · 0 评论 -
两种定制行为的方式:使用参数和使…
很多能力相对不足的开发。在被指出重复代码要求修改的时候,常有一个困惑:两段代码的确基本一样,但又略有不同或者有较多不同,这样怎么处理。这时候有两个常规武器:使用参数或者使用多态。 两者之中,使用参数是更常用的方式。其历史很悠久,在C语言时代,大家都是这么提取函数的。缺点是假如要定制的行为比较复杂,会导致要传入一堆的参数,然后代码中各种if-else、switch,降低了代码的可读性,维护原创 2015-10-10 09:22:56 · 322 阅读 · 0 评论 -
遇到技术问题的时候,建议使用如下…
遇到技术问题的时候,建议使用如下的搜索顺序:1、查看官方文档。比较大的sdk,如安卓和QT的文档都十分完备。但比较小的开源软件则不一定;2、使用Google和 StackOverFlow, 分别用英文关键词和中文关键词搜索;3、使用bing, 分别用英文关键词和中文关键词搜索;4、使用baidu,使用中文关键词搜索。另外取决于情况,有时候可以询问周围有相关经验的开发者。很多时候听君一席话原创 2015-10-10 09:23:23 · 2321 阅读 · 0 评论 -
解决Java从MySQL读取大量数据时卡…
今天晚上突然有个服务无法启动。这个服务在启动的时候会从数据库中加载一些数据。查看日志:有开始加载的日志,但没有完成加载的日志,判断问题是在加载数据时卡住。用top查看进程,发现CPU占用为0%。又怀疑可能是因为jvm内存不够,用jstat查看jvm内存使用情况,发现各区内存占用率较低,连younggc都没有出现。再用jstack查看线程栈,发现线程卡在JDBC底层的TCP套接字读取上: --原创 2015-10-10 09:24:10 · 13547 阅读 · 0 评论 -
高性能服务器编程感悟
前些年,程序性能随着硬件升级而提升往往不怎么需要程序员的参与。比如cpu频率从100M上升到500M,原先要执行1min的程序现在可能只要执行10几秒。而需要使用大内存的程序在内存扩容后执行速度也往往可以提高很多。但是现在情况发生了变化,想想吧。主流配置为cpu主频2g+内存2g的时间已经持续了多久?太久了,现在进入了多核的时代,单核-双核-四核。CPU也开始使用狼群战术了。这时候如果想要提升程序原创 2015-10-10 09:18:43 · 254 阅读 · 0 评论 -
多线程设计模式:Guarded Suspensi…
GuardedSuspension模式用一句话可以而总结:锁歪等干通。 解释下,他的基本流程是,锁 —— while循环 —— 若不满足条件等待在条件变量 —— 干活 ——如果有必要调用条件变量的通知。这基本上是条件变量的唯一正确写法。如果你使用条件变量却发现不是走在这条路上,要小心一点。程序员用代码说话,上代码: Java版本,实现一个消息队列:=============原创 2015-10-10 09:20:49 · 328 阅读 · 0 评论 -
教程:多线程编程技术(上)
前天发了好几篇文章,倒不是突然博览百书,而是因为在准备培训教材时有感而发。现在一不做二不休,把培训教材也贴出来。原创 2015-10-10 09:20:54 · 369 阅读 · 0 评论 -
让我印象深刻的IT名言(技术类)
1)Premature optimization is the root of all evil —— DonaldKnuth解释:过早的优化是万恶之源。First do thing right, then do thing fast。例外:你很清楚现在就站在系统的热点上,编程时就应该直接考虑效率。2)有两种生成一个软件设计方案的途径。一个是把它做得如此简单,以致于明显不会有漏洞存在。另原创 2015-10-10 09:21:04 · 898 阅读 · 0 评论 -
对软件架构的一些思考(V2.0)
最近看了一些技术书籍,结合自己的工作体会。对软件架构有了一些新的体会,在这里总结一下。如果说原始的看法是V1.0,那现在的想法就是V2.0吧。 我虽然早就是党国认证的系统架构师,但对软件架构的看法其实是非常偏实用主义的。记得我在某篇博文里说,何为好的架构?就是在整个软件开发过程中都不会后悔的技术决定,小到函数设计,大到模块划分,仅此而已。这种看法是正确的,但也是无用的。毕竟我们做出一个决原创 2015-10-10 09:23:01 · 419 阅读 · 0 评论 -
RabbitMQ使用不当导致的队列堵塞问题及解决办法
本接盘侠接手的一个服务使用RabbitMQ和其他服务进行消息传输。接手后发现:有时候RabbitMQ中明明有元素,但是不会回调DefaultConsumer的handleDelivery函数,于是队列无法消化,越堵越长。通过jstack查看,发现rabbitmq消费者线程堵塞在socketinputstream的socketRead0函数。通过搜索,发现这篇文章:《Queue consumer原创 2015-10-14 21:03:13 · 30004 阅读 · 0 评论