左耳听风
陈皓
网名“左耳朵耗子”,资深技术专家,骨灰级程序员
立即订阅
40357 人已学习
课程目录
已完结 108 讲
0/6登录后,你可以任选6讲全文学习。
开篇词 | 洞悉技术的本质,享受科技的乐趣
免费
01 | 程序员如何用技术变现(上)
02 | 程序员如何用技术变现(下)
03 | Equifax信息泄露始末
04 | 从Equifax信息泄露看数据安全
05 | 何为技术领导力?
06 | 如何才能拥有技术领导力?
07 | 推荐阅读:每个程序员都该知道的知识
08 | Go语言,Docker和新技术
09 | 答疑解惑:渴望、热情和选择
10 | 如何成为一个大家愿意追随的Leader?
11 | 程序中的错误处理:错误返回码和异常捕捉
12 | 程序中的错误处理:异步编程以及我的最佳实践
13 | 魔数 0x5f3759df
14 | 推荐阅读:机器学习101
15 | 时间管理:同扭曲时间的事儿抗争
16 | 时间管理:如何利用好自己的时间?
17 | 故障处理最佳实践:应对故障
18 | 故障处理最佳实践:故障改进
19 | 答疑解惑:我们应该能够识别的表象和本质
20 | Git协同工作流,你该怎么选?
21 | 分布式系统架构的冰与火
22 | 从亚马逊的实践,谈分布式系统的难点
23 | 分布式系统的技术栈
24 | 分布式系统关键技术:全栈监控
25 | 分布式系统关键技术:服务调度
26 | 分布式系统关键技术:流量与数据调度
27 | 洞悉PaaS平台的本质
28 | 推荐阅读:分布式系统架构经典资料
29 | 推荐阅读:分布式数据调度相关论文
30 | 编程范式游记(1)- 起源
31 | 编程范式游记(2)- 泛型编程
32 | 编程范式游记(3) - 类型系统和泛型的本质
33 | 编程范式游记(4)- 函数式编程
34 | 编程范式游记(5)- 修饰器模式
35 | 编程范式游记(6)- 面向对象编程
36 | 编程范式游记(7)- 基于原型的编程范式
37 | 编程范式游记(8)- Go 语言的委托模式
38 | 编程范式游记(9)- 编程的本质
39 | 编程范式游记(10)- 逻辑编程范式
40 | 编程范式游记(11)- 程序世界里的编程范式
41 | 弹力设计篇之“认识故障和弹力设计”
42 | 弹力设计篇之“隔离设计”
43 | 弹力设计篇之“异步通讯设计”
44 | 弹力设计篇之“幂等性设计”
45 | 弹力设计篇之“服务的状态”
46 | 弹力设计篇之“补偿事务”
47 | 弹力设计篇之“重试设计”
48 | 弹力设计篇之“熔断设计”
49 | 弹力设计篇之“限流设计”
50 | 弹力设计篇之“降级设计”
51 | 弹力设计篇之“弹力设计总结”
52 | 管理设计篇之“分布式锁”
53 | 管理设计篇之“配置中心”
54 | 管理设计篇之“边车模式”
55 | 管理设计篇之“服务网格”
56 | 管理设计篇之“网关模式”
57 | 管理设计篇之“部署升级策略”
58 | 性能设计篇之“缓存”
59 | 性能设计篇之“异步处理”
60 | 性能设计篇之“数据库扩展”
61 | 性能设计篇之“秒杀”
62 | 性能设计篇之“边缘计算”
63 | 区块链技术的本质
64 | 区块链技术细节:哈希算法
65 | 区块链技术细节:加密和挖矿
66 | 区块链技术细节:去中心化的共识机制
67 | 区块链技术细节:智能合约
68 | 区块链技术 - 传统金融和虚拟货币
69 | 程序员练级攻略:开篇词
70 | 程序员练级攻略:零基础启蒙
71 | 程序员练级攻略:正式入门
72 | 程序员练级攻略:程序员修养
73 | 程序员练级攻略:编程语言
74 | 程序员练级攻略:理论学科
75 | 程序员练级攻略:系统知识
76 | 程序员练级攻略:软件设计
77 | 程序员练级攻略:Linux系统、内存和网络
78 | 程序员练级攻略:异步I/O模型和Lock-Free编程
79 | 程序员练级攻略:Java底层知识
80 | 程序员练级攻略:数据库
81 | 程序员练级攻略:分布式架构入门
82 | 程序员练级攻略:分布式架构经典图书和论文
83 | 程序员练级攻略:分布式架构工程设计
84 | 程序员练级攻略:微服务
85 | 程序员练级攻略:容器化和自动化运维
86 | 程序员练级攻略:机器学习和人工智能
87 | 程序员练级攻略:前端基础和底层原理
88 | 程序员练级攻略:前端性能优化和框架
89 | 程序员练级攻略:UI/UX设计
90 | 程序员练级攻略:技术资源集散地
91 | 程序员面试攻略:面试前的准备
92 | 程序员面试攻略:面试中的技巧
93 | 程序员面试攻略:面试风格
94 | 程序员面试攻略:实力才是王中王
95 | 高效学习:端正学习态度
96 | 高效学习:源头、原理和知识地图
97 | 高效学习:深度,归纳和坚持实践
98 | 高效学习:如何学习和阅读代码
99 | 高效学习:面对枯燥和量大的知识
左耳听风
登录|注册

11 | 程序中的错误处理:错误返回码和异常捕捉

陈皓 2017-11-07
今天,我们来讨论一下程序中的错误处理。也许你会觉得这个事没什么意思,处理错误的代码并不难写。但你想过没有,要把错误处理写好,并不是件容易的事情。另外,任何一个稳定的程序中都会有大量的代码在处理错误,所以说,处理错误是程序中一件比较重要的事情。这里,我会用两篇文章来系统地讲一下错误处理的各种方式和相关实践。

传统的错误检查

首先,我们知道,处理错误最直接的方式是通过错误码,这也是传统的方式,在过程式语言中通常都是用这样的方式处理错误的。比如 C 语言,基本上来说,其通过函数的返回值标识是否有错,然后通过全局的errno变量并配合一个 errstr 的数组来告诉你为什么出错。
为什么是这样的设计?道理很简单,除了可以共用一些错误,更重要的是这其实是一种妥协。比如:read(), write(), open() 这些函数的返回值其实是返回有业务逻辑的值。也就是说,这些函数的返回值有两种语义,一种是成功的值,比如 open() 返回的文件句柄指针 FILE* ,或是错误 NULL。这样会导致调用者并不知道是什么原因出错了,需要去检查 errno 来获得出错的原因,从而可以正确地处理错误。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《左耳听风》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(25)

  • 精卫鸟
    隐式异常也不要显示的忽略吧,至少记录一条日志,不然会造成异常黑洞。之前帮同事找一个线上小概率问题,所有的日志和异常检测都抓不到,最后对全部进程一起strace,才发现是他catch了异常,啥都没做就return了...

    我们后来揍了丫的
    2017-11-07
    3
    93
  • 左耳朵
    @ stone扎西华丹,是我给极客时间出难题了,我的好些文章里有好多代码,有的会有好些图片,有的会有好些数学公式,这类文章不但都非常难配上语音,而且可能在手机端的排版都会很有问题,难为极客时间的编辑、产品和技术了,这个还望能理解了(后面的文章这样的事你会看到很多)
    2017-11-21
    23
  • majun
    期望听您对进程、线程、多进程、多线程的讲解,谢谢!
    2017-11-07
    22
  • xfly
    对于上面三种错误的种类来说,程序中的错误,可能用异常捕捉会比较合适;用户的错误,用返回码比较合适;而资源类的错误,要分情况,是用异常捕捉还是用返回值,要看这事是不应该出现的,还是经常出现的。
    ——
    这三种分类和处置方式比较赞同。
    但实际在多人协作项目,或大型项目中多方技术人员要在这个层面理解达成一致不是那么容易的事情。如果依赖于解决架构负债,架构升级来优化,驱动力又似乎不足。
    2017-11-07
    9
  • yun
    >异常捕捉的确是对性能有影响的,那是因为一旦异常被抛出,函数也就跟着 return 了。而程序在执行需要处理函数栈上的上下文,这会导致性能变得很慢,尤其是函数栈比较深的时候

    异常抛出和不抛出,函数栈的深度应该差不多吧?函数栈的上下文会有啥不同?
    2018-03-27
    7
  • 徐超军
    我们大不部分都是定义自己的异常处理类,然后各种异常都定义好错误码,返回给调用者,这样很清晰的就知道什么问题了
    2018-11-06
    4
  • 呆呆
    错误码、异常处理都是在不同场景下的结果,同步可直接获得,异步不能
    2018-11-15
    3
  • stone扎西华丹
    货不对板,我们订的时候,看到的可是一个音频产品。
    2017-11-13
    1
    3
  • 郎哲
    不用的语言不同的方式处理错误。Elang 虽有catch,几乎用不到,直接返回值。假设传进来的一定正确,霸道一点不正确请修改正确再传,错误非常容易定位用了catch反而多余隐藏bug,勿隐藏应今早发现今早解决。Go 返回error嵌套多了确实蛋疼不得多写好多if,Java 离了try catch 活不下去。
    2017-11-07
    3
  • LEI
    不是java的示例哦,java没有指针一说,看是能看明白意思,示例看着有点感觉自己门外汉,像是自己在学英语,然后讲解的人用另一门类似的语言在解释英语的意思一样,买课程只看了目录,作者简介写了骨灰级程序员,我以为是自己熟悉的java的讲解呢,因为自己是个半路出家的程序员,所以对c还是不太了解,今天只是选了这篇学习,不知道其他的文章是不是也都是C代码做示例讲解的哦,如果都是C的话,学起来就别扭了
    2018-12-15
    2
  • meijing0114
    请问所谓对于异常的多态性的catch是指什么呢?是指代码catch Exception对象,实际抛出的可能是ioexception这类吗?
    2018-09-16
    2
  • 皮特尔
    赞!迫不及待要看下一篇了。
    2017-11-07
    2
  • 李帅龙
    还有一种rust的方式
    2017-11-07
    2
  • 卫什么
    1. 通常而言,我们对于在程序中,自己可以预计到自己不期望出现的问题,而且能在问题出现后有替代解决方案的时候,我们就用异常。
    比如当我们处理图片时,我们希望图片的处理是成功的,但是不希望图片处理是失败的。当出现失败时,我们直接在程序中指定重新处理图片的程序,再次运行。

    2. 对于无法修复,无法提供解决方案的问题, 应该使用错误码。 比如用户输入信息的处理,无法修复网络资源的失败
    2019-04-04
    1
  • 恋空
    strtol()函数处理错误的那段代码没看懂是什么意思,能仔细说说吗
    2019-03-02
    1
    1
  • 这些代码例子错漏百出
    2019-01-28
    2
    1
  • 阿仁🇨🇳
    我是个零基础学员,我表示可以看完一遍,但是啥懂不懂 目前就知道以后遇到类似错误纠正的事,那我就再来这里重新查看,寻找答案。哈哈,这算是收获吗?
    2019-01-18
    1
  • weiguozhihui
    抛出异常之所以比较慢,有一部分的原因:异常也是一个对象,当产生一个异常时,需要生成一个异常对象(这个生成的异常对象肯定不是存放在栈上,应该可能是存放在堆上),并且将这个异常对象层层往上传递。并且在异常的产生与传递过程中至少需要一次拷贝构造,所以抛出异常要比返回错误码要低效一些。
    2018-10-02
    1
  • krugle
    之前网上查这方面的资料,这次在这里看到,太实用了
    2018-07-25
    1
  • 周孟
    对于返回错误码的方式是否定义结构体或是类同时包含错误码和错误消息会更好一些,特别是一些业务验证或输入问题上
    2018-06-19
    1
收起评论
25
返回
顶部