Table of Contents

前言

什么是问题规模?

什么是抽象程度?

解决困难问题的共通方法


前言

为什么会有动机写这样一篇文章,是因为在我们每个人每一天的开发工作,学习当中,总是会层出不穷,永无尽头的遇见各种各样的问题,从上学开始面对一道又一道考试题目,到后来工作中面临一个又一个bug或者功能需求,到生活当中需要处理一个又一个的事情。我们不停的解决问题,不停遇到新的问题,甚至可以说,每个人的一生不过都是类似如此的一个循环。

有的问题我们轻而易举就可以解决,有的问题我们努力一点可以解决,有的问题我们拼尽全力才能解决。笔者在自己的观察和对自己的经历的反思当中也渐渐的发现了很多有意思的事情,或者说规律。

  1. 不同的人在面对相同的问题时的解决能力是不一样的,甚至是千差万别的,因此同一个问题有人会说难,有人会说不难,这非常正常。明白这一点的人就不会因为某一件事事情去取笑一个人,或是看不起比他笨的在某些方面不如他的人。
  2. 一个人解决问题的能力主要来自于三个方面:先天智力/体力条件,知识水平(包括分析问题的能力和借助工具帮助的能力),自信心。
  3. 人的自信心会在不停的解决问题,或者说完成事情当中积累,也可能因为一些失败受到影响,自信心是动态的这和马太效应是一脉相承的,不停解决各种问题的人,自信心会逐渐的变得更强,这也反过来帮助他在之后遇到问题时能表现的更加好。
  4. 抛开人的因素不看,从纯粹客观的角度来看的话,那么一个难的问题到底难在哪儿(当然,考虑每个人的个体差异或许才是最客观的,但这里我们只谈问题本身)?主要就是两个方面:一是问题的规模,二是这个问题涉及的抽象程度。这一点可以说放之四海皆准,在任何行业,任何场景都适用。

为什么这么说呢?前面三点很好理解没有太大争议,值得展开的是第四点。

什么是问题规模?

问题规模就是指的问题的大小。举例说明:

一道难的数学题:计算量往往是很大的。注意这里的计算量理解的不应该太死板。数学题答案最后写出来也许几步但是草稿纸必然不止几步,草稿纸用的少,大脑里做的计算也绝对不会少。

一篇很难的英语阅读:句子往往是很长,文章也不可能只有几句话。

一个很难实现的功能:所需要的代码量肯定是不小的,注意直接调用写好的方法不算代码量小。例如java常用的类HashMap仅仅这一个类的代码就超过2000行,这还不算它所用到的依赖的其他地方的代码。

还有一些例子并不是一个具体的问题,而是一个具体的实物。

一台汽车,或者说生产一台汽车:任何一台汽车,组成他的零部件都上万个,不说生产,光是把这些零部件拼在一起,这就是一个巨量的工程。生产其他机器同理,如飞机,电脑等。我们要知道,在古代的皇帝也不过只能坐轿子。

上面这些问题都是非常难的问题,他们的问题规模也都很大。

什么是抽象程度?

抽象在科学里的定义是:从具体事物抽出、概括出它们共同的方面、本质属性与关系等,而将个别的、非本质的方面、属性与关系舍弃,这种思维过程,称为抽象。

在计算机的世界当中,抽象是我们用来简化复杂的现实问题的途径。

所谓抽象程度,笔者的总结是指一个问题抽象之后是否能被我们理解,从另一个角度来说就是当我们要描述这个抽象的问题时,是否容易给别人描述清楚,假设表达能力正常,则越难描述清楚抽象程度越高,越容易描述清楚则抽象程度越低。

这里有一个非常有意思的现象,就是抽象程度是会动态变化的,因为抽象程度本质是一个相对于人的理解的概念,当人们对一个专业的术语或是代号,公式,都公认且应用熟练之后,这个抽象对于他们来说将变得非常容易理解。一个比较常见的例子是,在一个行业的人如果去另外一个行业体验的话,一定会遇到很多这个行业的特定代指某一事物的一些称呼,这些代号在一开始肯定是听不懂的,但是假以时日,我们就能马上get到它的意思了。

再比如未知数这样一个概念,我们在上学时都有学习过设未知数x来解决问题的经历,那么在没有引入未知数这个概念时,我们解决问题的思路都是从已知的出发去算。突然有一天有人告诉你我们可以把不知道的设为x。但是对于一个上小学或者中学的学生来说,他在第一次看到这个x的时候一定是很难理解的,这个x本质上就是对未知数的一个抽象。

但是,我们的生活当中以及后来的学习当中,要求的答案并不都是一个数字,因此那个x所代表的抽象并不都全是数字,x所代表的抽象我们越难以理解,那么我们要求这个x也就越难。现在,我想假设人生的意义为x,然后我的问题是,那么人生的意义是什么呢?

再举一个编程时的例子,在我们测试我们编写的程序时,或者在工作当中,有时候会遇到一些很难解决的bug,这些bug假如是第一次遇到的话,我们往往会无从下手,原因往往是我们并不能一下子就准确理解这个错误的意思,因此要修复就没那么容易。而当我们通过查阅资料,更改代码,再结合自己的知识解决了问题之后,当下一次遇到这样的问题时,我们就能渐渐的‘猜’出可能是哪里出错了。这个过程可以说就是一个bug的抽象程度在相对我们的理解能力提高而降低的一个过程。

我们可以简单把问题抽象程度理解为这个问题是否容易理解的程度。

解决困难问题的共通方法

认识了一个难得问题难在哪儿,以及难题的规律之后,对我们解决这些问题就会大有裨益。这里要引入程序员最熟悉不过的面向对象,不过这里只谈思想不谈具体编码。同时在这里推荐一本书《面向对象分析与设计》。这本书最重要的内容就是讲了面向对象思想如何帮助我们认识了这个复杂的世界,和本文的主题一脉相承。

首先,面向对象思想的三大特点:封装,继承,多态。在这里博主认为可以加上抽象,但是抽象和封装以及继承都有一些重叠的地方,我们之后再来谈这一点。它们的定义如下:

封装: 在软件世界当中它指的是:把数据和对数据进行的操作封装在一起,数据被保存在内部,程序的其他部分只有通过被授权的操作(成员方法)才能对数据进行操作。事实上我们完全可以跳出软件的范围来看封装的概念。举例说明,在你驾驶汽车的时候,你只需要点火,踩油门,转方向盘等操作,你曾经去关心过汽车内部这些操作是如何实现的吗?一般情况下我们不会这样做,而是直接去进行这些操作,也就是在调用汽车提供的方法,汽车的这些操作,对我们来说就是一个封装好的操作,我们只需要调用即。

再举一例,有一位知名考研数学老师在讲泰勒公式时有一个经典的讲解方法。这个问题不细讲,大致说一下就是在高等数学里有一个等价无穷小公式:当x趋近于0时,x-sinx等价于(x^3)/6,注意这是一个公式。而出题人出题时必然不会直接给一个公式让我们求,他可能会把x换成任何东西,换言之,真正的x可能比这里公式的x看起来复杂。这位老师身经百战,经验丰富,他一下就识破了出题人的意图,于是就把这x当成了一个整体,说出了一个非常有意思的公式:狗-sin狗 等价于 (狗^3)/6.

现在,我们再看看这个讲法,这不就是把’狗‘这个东西来当作了一个对象吗?这个对象代表的就是一个抽象而已。因此,这不也就是面向对象里面的一个对象吗?没有任何区别啊。x不就是一个代指吗,它可能不是一个数,它可能是任何一个对象。这位老师的讲法事实上就是面向对象思想的一个经典应用。并且,这样的思想在数学上甚至在其他任何学科上,都是无处不在也一直在发挥着它得魔力,当然也包括我们现在讲的软件的世界。只是很多人并没有意识到他们用的这种思想本质上到底是一种什么样的思想。而现在,我们应该渐渐明白了。

继承:在软件当中的定义是: 当多个类存在相同的属性和方法时,可以从这些类中抽象出一个父类,在父类中定义这些相同的属性和方法,所有的子类只需要通过extend来声明继承父类就可以获得这些共同属性。事实上面向对象的理论往往第一句话就是:everything is an object. 因此这里虽然表述的是类,但我们同样可以把这个概念应用于生活中的几乎任何场景。还是以汽车为例,丰田卡罗拉的同一型号的不同款式汽车,在生产时,大部分的架构必然是采用同一个生产线,只是有一些不同型号的配置,不同型号的车可以根据自己的特点进行改变或者添加一些特有的配置。

多态:在软件当中多态的概念是:通过同一个指向父类的指针,来调用在不同子类中实现的方法。这个概念貌似只是一个纯软件概念。但是依然来源于生活,还是以驾驶汽车为例,当我们学驾驶技术的时候,也即调用汽车的,转方向盘,踩油门,打灯等方法时,我们学的是通用的方法,并不会因为换了一辆汽车,学的这些驾驶技术就需要重新学

在上面的描述当中,我们已经提到了抽象,正如上文所说,抽象蕴含在了封装,继承,多态当中。将事物的一些特性封装在一起,这就是一个抽象的过程。将类的共同属性和方法提取到父类当中,这也是一个抽象的过程。

因此,我们在看待生活中的事物,以及一些所谓的难题之时,可以按照这样的思路去抽丝剥茧,这样一个再难的问题也会变为可以理解的,可以被实现的。但有一点不得不提的时,随着抽象层次的复杂,问题量的变大,有的东西相对于一个人的脑力来说的确会显得十分复杂,我们也很难去做到面面俱到的了解。例如,一个大型银行的所有业务系统,这就是一个相当复杂的东西。但是,必须指出的是做到面面俱到的了解往往是无意义的。对我们来说,掌握这样的方法和理论,帮助我们构建这样的复杂系统,以及分析其中的问题,才是我们应该去做和值得去做的事情。

(本篇完)

[思考] 难的问题到底难在哪儿相关推荐

  1. 生活之难:生活到底难在哪里

    生活之难:生活到底难在哪里 一.总结 一句话总结:难在天性,难在竞争,难在积累,难在追求,难在自己 难在天性 人的天性就是好吃懒做好玩不动脑的,但是生存的压力(食物,房子,配偶)又会迫使你必须工作 难 ...

  2. 嵌入式Linux驱动难?到底难在哪?

    驱动入门难在:如何通过自己的学习能力搭建起环境,并理解一个LED驱动. 深入驱动难在:对内核的理解,对特定协议的认识. 最近看到论坛和群里一些人在说驱动难,个别人提出提供的入门资料还是难以入门.作为嵌 ...

  3. 神回答:编程到底难在哪里?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | https://www.zhihu.com/a ...

  4. 网站想要快速收录到底难不难?4个问题快检查

    网站的收录量越大,网站关键词排名提升几率也会越大,所以优化人员也都非常重视网站的收录量问题,但对于一些收录不高的网站想要提升收录速度到底难不难呢?其实并不难,接下来就带大家一起了解一下6个快速提升网站 ...

  5. 新手前端练手网站_编程到底难不难学?新手入门选择哪种语言好?

    以下内容适合的读者:想要学习编程的小白 一.编程到底难不难学? 对于这个问题我的回答是不知道,学会了编程的人会说好学,中途就放弃的人会说很难,任何知识想要掌握好都不是一件容易的事情.所以我决定用自己的 ...

  6. 专升本c语言名词解释题_专升本到底难不难?

    专科院校可以专升本的专业有很多,但是我作为一名法学生我要跟大家分享的肯定就是法学了. "法学"它是一个专业属于政法系 没错在专科的时候也是政法系,在这个社会发展一步步加快的时代下法 ...

  7. 什么都不懂的学java难不难_零基础转行学java到底难不难

    不少零基础的新手想要转行学习java可是不知道难度,南京学码思下面就给大家详细的说一说转行java的难度,希望能帮助到各位想要了解java的同学. 零基础转行学java到底难不难 新手转行学java到 ...

  8. 计算机html二级难度,计算机二级考试越来越难的实锤!真实数据告诉你到底难在哪里?...

    原标题:计算机二级考试越来越难的实锤!真实数据告诉你到底难在哪里? 相信参加过3月考试的小伙伴都有这样的感觉,选择题新考点虽然没有增加很多,但是操作题就一言难尽,不仅新增了4套新题,而且原题也进行了更 ...

  9. 都说C++难,那么它到底难在了哪里?

    众所周知,Java一直是编程开发的主流语言,学习起来不难,门槛要求也不高,但是高端的和底层的开发还是主要C与C++的天下.比如开发驱动程序,系统服务,高效的网络通信程序(比如大型网游),甚至开发象SQ ...

最新文章

  1. Matplotlib可视化散点图、配置X轴为对数坐标、并使用线条(line)连接散点图中的数据点(Simple Line Plot with Data points in Matplotlib)
  2. 向Lucene增加中文分词功能
  3. ROS-Rtabmap:linux shell运行多个shell(运行多个程序)
  4. 死磕java_死磕JavaScript-垃圾收集机制
  5. 新建网站的长尾词应该如何去做优化
  6. 21天学通C语言-学习笔记(1)
  7. Mac M1运行matlab卡,解决办法
  8. 主动轮廓模型:Snake模型的python实现
  9. RXTX for java在arm上的使用
  10. 网络应用程序体系结构
  11. 惠普omen测试软件,性能测试:高品质体验主流游戏
  12. 【京东电商网站主界面仿写——HTML第二部分】
  13. canvas快速实现视频的一键截图功能
  14. SQL Server decimal 和 numeric 区别
  15. 无法kill掉的僵尸进程
  16. 去掉底部 Powered by PageAdmin CMS 方法
  17. 【原创】Wiki报错:“该文件的加载时间比平时要长。请稍等片刻……”
  18. Defensive Programming in PHP(PHP中的防御性编程)
  19. ‎平面設計師需要瞭解的8個印刷知識‎
  20. MySQL普通用户无法本地登录的解决方法及MySQL的用户认证算法

热门文章

  1. Arduino从入门到精通全课时教程分享
  2. 格力机器人图解_格力空调拆机图解,这张图看完立马成专家
  3. 学习笔记:Fully Convolutional Networks for Segmantic Segmentation
  4. metrics-server - unable to fully collect metrics
  5. 解决安卓约束wrap_content约束失效问题
  6. MT6762芯片资料,MTK6762原理图分析文档
  7. 插入脚注把脚注标注删掉_CSS中的经典版式效果:脚注
  8. 俊哥的blog的一道题
  9. MYSQL 中round(),floor(),ceiling()函数的用法和区别?
  10. docker开发环境搭建(windows)