如何提高解决问题的能力?


50

每个人都说相同的话:“一个真正的程序员知道如何处理实际问题。” 但是他们忘记了如何学习这种能力或在哪里学习的:学校没有教授这种能力。

如何提高我处理复杂编程问题的能力?哪些策略对您有用?我应该关注哪些特定领域,例如算法或设计模式?


3
Code Complete中提到的两本有用的书是:James Adams的《概念性大爆炸》和Edward De Bono的《横向思考》
mctylr 2011年

1
啊!当它只有几个答案时,我忘了在这里发帖。
马克C

Answers:


25

一些可能有效或无效的技术:

  • 查看常见问题(例如设计模式)的现有解决方案。也许您发现类似的问题至少部分类似于您的问题。搜索网页。
  • 好像问题已得到解决一样,然后跟踪解决方案。例如,不必为类设计API,只需编写使用该类的代码以及所需的方法调用,然后实现该API。
  • 做其他事情,例如上网冲浪或玩单人纸牌,然后等待灵感发生。
  • 想想您最喜欢的人,并假装想用解决问题的能力打动她。有什么特别令人印象深刻的解决方案?
  • 检查问题中是否存在内在矛盾或需求冲突,并准确说明问题所在和可能做出的妥协。通常,当存在此类冲突但您不知道时,您往往会放弃一个可能的解决方案,因为您不能完全满足所有要求。
  • 如果您已经有可能的解决方案,但是感觉“脏”(复制粘贴,全局变量,意大利面条代码等),请继续使用它,然后再进行改进

最后一点很出色。有时候,解决该问题的方法是让它在大多数情况下都可以正常工作,然后查看需要改进的地方。
JeffO 2011年

4
但是,请注意,至少在我的经验中,“我稍后将修复”变成“我已修复”的数量很少。
Gareth

3
Gareth:是的,但想法不是要在下周,下个月或任何时候使它变得更好,而是要在使其工作后立即改善。这是作为破解坚硬坚果的一种方法。
user281377 2011年

3
我不会上网作为等待灵感发生的一种方式。您需要空闲的大脑周期来激发灵感,上网冲浪是浪费那些空闲的大脑周期的方式。取而代之的是去购物,散步或骑自行车,打扫公寓-做一些不需要太多脑力的事情。在这种情况下,灵感会更快地出现。
肯·布鲁姆

1
怪胎:我知道#4听起来有点自相矛盾,但是有时候,它确实对我有用。尤其是在可能存在不止一种方法且问题是选择其中一种方法的情况下。#6意味着不受我们行业中常见的限制。有时,我们内部化了诸如“避免全局变量”之类的规则,以至于我们不知不觉地拒绝了所有使用这种不赞成使用的技术的解决方案。
user281377 2011年

20

根据需要使用R模式或L模式思维

R-mode是我们通常与潜意识相关联的创造性,非语言方法。L模式是与“内在声音”相关的线性,逻辑,语言方式。

如果问题似乎难以解决,则可能是因为您尝试使用错误的思维方式来解决问题。对于程序员而言,默认的思维模式通常为L模式,因此您可以暂时关闭它并访问R模式。

如何进入R模式思维

有很多方法,但是也许尝试Poincare方法(以著名的数学家的名字命名)。

写下有关该问题的所有知识。立即解决它的所有容易方面(如果有)。从仍然存在的“困难问题”列表中选择一个项目,然后散散步,这样您就不会受到干扰或分心。

不要在行走过程中尝试分析问题,而要让您的思想徘徊并观察可能与问题相关的任何有趣的图像或感觉。让他们合并。如果灵感立即袭来,请停止走走,然后返回并写下您获得的见解。

冲洗并重复直到所有问题都得到洞察。然后开始探索见解。

推荐书

另外阅读实用思维和学习可能会帮助您成为更好的问题解决者。(我最近似乎经常参考这本书...)


4
务实的思维和学习非常出色
Brad Cupit 2011年

参考:drawright.com/theory.htm(R模式和L模式是什么)
mctylr 2011年

17

问别人...

不认真 您最大的资源可以是坐在您旁边的人。甚至不要问他们问题的答案,请他们坐在您旁边,让您解释问题。

通常,当您口头表达出来时,就会解决它。

有时,另一个人会问一个问题或指出一个细节,这将打开精神闸门。

最终,您将学会不用脑袋说话就能说出头脑中的东西,并更快地找出问题中的关键细节。

而且,如果其他所有方法都失败了,那么至少他们可能会向您展示您从未想到使用的技术。


问别人或组成学习小组是学习的极好方法。
加里·罗

我也这样做,只是想从我这里得到想法,这是最好的方法之一。
维斯瓦

这种技术被称为橡胶闪避,关于它的编码恐怖优秀文章codinghorror.com/blog/2012/03/rubber-duck-problem-solving.html和维基也是有帮助的en.wikipedia.org/wiki/Rubber_duck_debugging
口角

9

实际上,我的简短回答是“解决更多问题”。但是重点是:真正专注于问题并且不要放弃。不要在StackOverflow或其他方面寻求帮助。(当然,阅读StackOverflow也是可以的!)努力尝试,直到获得一个几乎可行的解决方案,然后您才几乎达到了目标。继续直到您找到满意的解决方案。

对我来说,解决问题有两件事:

  • 解决问题的策略
  • 持久性和挫败感

在我看来,第2点确实至关重要,因为在您遇到问题的时间越长,它就会迫使您改变思维。它还使您可以花更多的时间解决问题,从而进一步提高自己的技能。;-)

顺便说一句,我建议您阅读爱德华·德·波诺(Edward de Bono)。尽管我主要通过学习物理来解决问题的技能,但他的写作确实很有趣。

好吧,我的问题解决工具包是这样的:

  • 随机尝试
  • 阅读有关我所关注的主题(或紧密相关的主题)的随机文章/博客/帖子
  • 画一个漂亮的图画
  • 将问题分为多个但更简单的问题
  • 做其他事情
  • Google在某种程度上与问题有关
  • 与其他人谈论这个问题
  • 列出待办事项
  • 写下有关问题影响的知识,以便更轻松地找到模式

请注意,大多数这些工具都可以递归应用。

我的算法是这样的:

  1. 目前,我的问题解决工具包中哪个工具最有意义?
  2. 问题没有解决?继续1. ;-)

步骤1.是一个艰难的决定,但是您练习得越多,做出的决定就越好。

哦,我几乎忘记了最重要的成分:

积极思考整个过程。不要以为“我希望XYZ现在能够解决问题。” 而是想:“如果XYZ不起作用,那么我知道YZX不会成为问题源,我将检查ZYX是否起作用。” 有时,解决问题可能会很有趣,特别是如果您发现问题的过程最终变得既优雅又有益。


我在此页面上搜索了“物理”一词,以查看是否有人已经写过它。数学是另一门。
Mark C

我认为,就解决问题的能力而言,学习物理学的价值很难高估。
马克C

+1表示积极思考。如果您发现自己不适应,那么您的问题解决能力就会受到损害。查看问题,因为它可以为您提供知识。
加里·罗

7

也开始研究发现问题的技巧。有时,您必须先识别出问题,然后才能解决它。在学校,他们要求学生回答过多,而提出的问题却不够。

寻找您周围解决问题的人,并询问他们如何解决问题。

准备要犯错。如果将它们全部保留给自己,将不会有所改善,也不会有任何用处。


+1表示“在学校,学生要求太多的答案,而学生提出的问题却不够。” 这是洙真实,需要时间来学习如何提出正确的问题...查看处处有不好的问题这样的例子很多
雷米

4

对软件工程师进行计算机科学教育的主要好处是能够创建和理解抽象。抽象用于将通用功能(例如String类方法)封装到紧密,可重用的程序包中,使我们可以专注于更大的问题。

学习认识和创建抽象

但是最重​​要的是,抽象教我们如何将问题分解为更小,更易于管理的部分。当与科学背景相结合时,这些技能的结合可以创造出能够消除噪声并深入解决问题核心的工程师。

学习使用科学方法解决问题

对存在难以发现问题的生产应用程序进行故障排除时,有时它有助于进一步破坏应用程序(在非生产环境中),以消除多个变量,从而隔离和消除一个变量。

总之,科学方法是从计算机科学学位所需的所有物理选修课和其他科学选修课中学到的,有助于解决这些问题,就好像我们正在对一系列志愿者进行安慰剂和新药试验一样。就像有时为了使事情变得更好而必须使事情变得更糟的科学家一样,有时我们作为工程师也必须这样做。

通常,以这种方式进行科学思维只能来自具有科学背景的经验。有时解决问题不能被视为从A到B的线性路径。

简而言之,学习计算机科学,学习其他科学领域,学习函数式编程。这些将帮助您像科学家一样思考并跳出思维框。


究竟。将大问题分解为小问题。
比尔·米歇尔

3

这完全取决于您要解决的问题类型,但是如果您还没有这样做,则学会逻辑思考是一件好事。

总而言之,您会讨厌我这么说的,但实践却是完美的。我没有被母亲的子宫所吸引,她不知道该如何成为一个好的问题解决者,没有其他人做过。您需要练习和学习如何自己做事。如果您仍在学校并且没有编程/计算机科学类型的课程,则数学和科学对于培养这些技能也非常有用。


3

我认为您正在寻找的是计算机科学启发法。

当涉及到我们99%的人在战es中所做的事情时,在阳光下真的没有什么新东西。因此,您可能会看到一个问题并将其识别为DP问题,或者将另一个问题识别为可以从记忆中受益的问题等。

您如何获得这些知识?合适的CS学位是一个不错的起点。不是软件工程或信息系统专业,而是大多数本科生抱怨“不切实际”的东西。

您可以自己执行此操作,但可能会更困难。我将从这两个课程开始:

算法简介

理论CS的伟大思想


2

我的答案专门与编码有关,但可以应用于任何东西。

  1. 离开键盘。散步,跑步,和同事喝咖啡聊天
  2. 变老10岁!我的经验极大地帮助了我。
  3. 使用二进制印章。将问题分为两部分,然后缩小问题范围:重复。
  4. 记住福尔摩斯:当你消除了可能性之后,剩下的一切(无论多么奇怪)都是答案
  5. 检查您的测试数据。我真正棘手的问题中有一半以上是由错误数据而不是错误代码或算法引起的。

1

在实践方面,我可以告诉你我做什么。我对应用数学比对编程更感兴趣,但是应用于计算的应用数学是各种编程。我看到了问题和解决方案。在链接到已知解决方案(或现有代码库)之前(或有时在以后,如果说我的工作需要及时的解决方案),我想问自己:“如果这是一个原始问题,即您将找不到罐装解决方案,您将如何进行?” 如果答案很简单,请考虑编写解决方案(解析或计算机程序来解决)。忽略复杂的最终情况,您有兴趣探索方法和算法,而不是重新发明现有的库。如果解决方案需要太多的精力,请不要编写完整的解决方案,但至少要考虑要使用的数据结构和方法。还考虑其他方法。


1

有一个很大的SO问题

我的回答是:

改善的最好方法就是练习!

在以下位置订阅RSS feed:http//www.mensa.org.uk/puzzles/,并花些时间完成它们的发布。

每天拼图的日历(例如http://www.calendars.com/product.asp?PID=1&MGID=-1&IID=46387&cm_mmc=Affiliate_Program--performics--k137666-_-DDI%20Link)很好也有想法,因为它将为您提供固定的,小规模的和各种各样的问题来解决。

尽管这些将始终与您会遇到的问题脱节,但多样性很重要,因为它会迫使您以前所未有的方式思考,这实际上是解决问题的全部。

编辑:也请查看:http : //www.mindtools.com/pages/main/newMN_TMC.htm,以获得良好的问题解决技巧。


1

下棋

下棋是解决编程问题的优秀教练。问题的层和逻辑树之间的关联非常好。它还可以帮助您在进行次优路径和浪费时间之前先进行思考和计划。

国际象棋还需要在左右“思维模式”之间取得平衡。如果您太过分析,您会陷入尝试计算所有事物的困境,这是不可能的。但是,每个创意灵感都需要进行计算检查,以确保适合实际情况。困难的问题就是这样。

国际象棋展示了学习和实践如何以非常线性的方式带来坚实的进步。程序问题解决也是如此。

下棋还可以帮助您很好地掌握要学习的东西。即使您已经编程(或下象棋)已有10年了,但您还不是一位大师。


我发现经常下棋会使我的头脑变得敏锐。
保罗·内森

1

我最近一直在Euler项目中解决问题。这些问题有不同的难度。解决方案通常不需要大量代码,但是您必须考虑许多因素,例如算法的运行时间。您只需输入答案即可使用任何喜欢的语言。关于许多问题的最佳解决方案都有不错的文章,关于每个问题的讨论也很多。每天尝试解决一个问题,您会惊讶于您的问题解决和分析能力提高了多少。为了获得更多荣誉,请尝试使用多种语言(例如过程语言(也许是C ++),脚本语言(例如python)和功能性语言(例如F#))解决相同的问题。


1

我来自科学领域,因此在看问题时,我倾向于使用“ 科学方法”中的策略。我特别喜欢根据假设设置“实验”并使用“控件”,因此我将构建一些东西,然后仅更改/添加一件事,然后查看一次更改/添加的结果,如果我愿意,如果没有得到所需的结果,我将其切换回去并进行其他更改。这对于故障排除/调试代码非常有效。有时候,您会找到想要的答案,但是即使您失败了,也总是会从中学到新的东西。我也喜欢通过还原主义学习-采取已经存在的东西(总是最好从您可能不了解的东西开始,但是您知道有效的东西开始),并且对我来说看起来很复杂,看看我是否可以将其分解为各个组成部分并首先了解它们是如何工作的。有时候,我的大脑更容易处理这样的学习,而不是整体地解决问题,我可以利用这些知识自己构建其他类似的复杂事物。我还建议您阅读有关逻辑和推理的书籍,以选择古典和现代思想家的作品(从亚里斯多德开始,逐步发展)。它们可以为您提供一些基本逻辑的基础,可用于帮助解决计算机中的问题。而且,当然,如果您不能解决问题,并且已经解决了一段时间,则请稍作休息。在问题的特定方面进行裁决有时是有害的。每个人都需要休息:)


0

解决问题最困难的部分是“感知缩小”。

您选择了似乎是问题的内容,然后顽强地继续下去,直到您精疲力竭且没有进展。

做到这一点的方法是确保-绝对确定-您确实了解问题。“解决正确的问题”是解决问题的最重要部分。

有时,他们称其为“框外思考”。“盒子”是一个狭viewpoint的观点,可能不包含真正的根本问题。跳出框框思考是寻找解决的正确问题。

关于避免策略过早缩小针对错误问题的策略的书籍很多。

通常,诀窍是确定真正的结果应该是什么。然后找出阻碍理想结果的因素。


0

老实说,我认为每个人都是不同的,因此每个人成为更好的问题解决者的路线图是不同的。您可以从他人的经验中学到东西,但是最后您必须走自己的路。这本质上是“艰难的方式”学习的东西,但是在这种情况下是有效的。

这就是我开始改善问题解决方案的方式,尽管我还不是一个出色的问题解决者,只是比去年更好。我得到了一个正在工作的新项目,该项目涉及通过添加三个新的管理报表来扩展一个开源时间跟踪软件。该软件是用我从未使用过的语言编写的,但文档记录很差,而且很模糊。我深入研究并进行了大量研究,然后我只是一步一步地研究报告,一旦有了基本功能,便对其进行了改进,最后又添加了更多功能。

因此,换句话说,我建议您找到某种类型的水槽或游泳现实世界项目进行研究。如果您目前是一名程序员,请找到一个项目或向老板要求一个。如果这种情况是不可能的,那就找个工作以外的地方,也许是合同/自由工作之类的东西。我必须尽快很好地解决问题,并且由于项目的强度,我保留了这些知识。如果这对您不起作用,那么请按照此线程上其他所有人的建议进行:)。


0

答案本身就是问题,可以提出不同的解决方案。总是有不止一种解决方案(例如,可以用不同的方式进行排序,例如冒泡排序,选择排序等),您只需要选择一种有效的方法即可(排序)。下一次尝试不同的时间,依此类推.....和用于解决问题的书.....无您无法从书本中学习解决问题的技能,更多的代码将执行您将获得的更多知识。祝好运


0

通过可视化如何使用自己喜欢的编程语言解决问题,程序员可以轻松地从心理上解决问题。就像经典的木匠一样,当他最喜欢的工具是锤子时,会将所有问题视为钉子。

我认为最好的解决问题的练习是在您达到实践水平以上时出现的,只是思考“这是我以最佳方式解决它所需要的”。在某些情况下,您可能必须学习(很多)新知识才能完全应用该解决方案,但是关键是您制定解决方案的能力不应局限于您的历史和现有技术。

对我来说,一个古老的实际示例是,当我意识到自己的问题实际上并不需要抢先线程时,即使我通常会一直走到我的舒适区,将所有这些互斥体都打碎了,我学会了如何实施高效的协作多任务处理。最终似乎总是在某个时候不再感到自在..)。


0

在应用程序开发中,我们面临的许多问题要么是我们自己的发明,要么是我们继承的白痴的发明,这些白痴使代码库陷入困境。解决问题最常归结为寻找根源。通常,一旦我们发现问题的根源,仅需具备能力即可解决问题。

为此:

  1. 了解您的平台。
  2. 学习您的工具。
  3. 了解尚未遇到的平台可用工具。

没有可供大脑使用的信息,世界上所有的大脑训练都是无用的。为了解决问题,您必须首先知道可能性!即使那样,使用良好的信息而不是仅仅描述问题也要快得多。

我可能会推测,直到奶牛回家,为什么有些东西要花太长时间才能执行。但是,如果我说“让我们先获取一些数据”,我可能会看到抛出了很多异常,并且意识到我可以改为使用if语句。在不知道如何收集信息的情况下,不知道在我的平台上,异常会花费大量的开销,并且有一种可以在尝试之前进行检查的方法,这样可以更快地完成任务,我永远也无法解决问题。


0

您的答案分为两部分:

a)解决实际问题的技术

b)使您的大脑天生就“善于”思考和解决问题

关于技术,总是会有一些很棒的答案(假设您知道问题所在等等),因此我将不做过多介绍。至于训练大脑,您可以做一些事情来克服这些突触并建立更多的互连

1)学习一种新的语言,一种真实的语言(例如,法语或中文现在可能是不错的选择)

2)学习弹奏新乐器

3)做一些艺术作品,例如绘画,素描或雕塑

4)玩拼字游戏或填字游戏

5)像你说的那样跳舞。不,我不是在开玩笑。跳舞已被证明会对您的大脑和思维产生影响

6)拓宽您的经验,创新的解决方案来自一种理论在另一领域中的应用,因此研究您发现有趣的不同领域和领域

7)运动,运动是至关重要重要的改进思维过程

最后,我将提供解决难题的最佳秘诀:走很长一段路。我发现它可以奇迹般地清理你的头部,让一个人思考问题



0

我的建议是扔掉那本书!

当然不是。我的意思是,进入一个您经验很少的主题领域,然后在不了解现有解决方案的情况下解决难题。除了您的创造力和批判性思维,甚至是参考手册之外,什么都不需要。

您可以设计图像格式。或Web服务器。或压缩方案。文件系统。核心。人工智能。编程语言。计算机视觉系统。

您发现有趣的东西,相当复杂,而且您从未学过。不要阅读它:直接进入。实验。犯错误。重新发明轮子。

不要寻求帮助。远离教程。远离理论。不要从架子上拿出解决方案。

为什么?

  • 我们从错误中学习得最好。
  • 它使您有机会创造性地练习解决方案,而不必反省和适应旧的解决方案。
  • 您被迫评估自己的想法。您必须对工具,要解决的问题以及要评估的想法有深入的了解,才能对它们进行评估。这将使您对该主题的理解比其他方式要深入。(请随意阅读您正在使用的工具,只是不要阅读您要解决的问题。)

进行一些尝试,一旦您对所取得的成就感到满意,请将其保留几个月。然后重新开始,看看是否可以找到新的视角。之后,是时候开始阅读该问题以及其他人如何解决该问题(或与他人交谈)的时候了。此时,您不会在阅读时对自己说“是的,那是有道理的”,而是说“是的,恰好 ”或“在某种程度上说得很好”,或“哇,那很聪明”。

换句话说,您将对阅读的内容进行更为严格的思考,并且您会发现它更容易理解和记住,因为您已经有了一个庞大的“心理框架”。您会对自己独立发现的事物感到满意,并且会获得大量新知识。

不要试图使您的解决方案完美。只是向自己证明自己可以解决问题。采取“可以做”的态度,如果您对问题感到畏缩,请记住,第一个解决问题的人可能和您一样了解(事实上,他们不知道有解决方案!)。


0

解决问题并不是阅读所能教甚至学到的东西。更好地解决问题的唯一方法就是解决问题。

您可以了解解决问题的不同技术方法,并且可以了解可用于解决特定领域中的问题的工具和技术。除非您不断思考问题,否则尝试提出解决方案(针对每个问题提出多个解决方案并相互评估),然后根据其他人开发的解决方案评估您的解决方案,您将不会在问题上变得更好解决。

我建议您阅读Andy Hunt的《实用思维与学习:重构您的湿软件》。这是一本关于理解您的思考,反应和学习方式的书。它引入了行为理论和其他认知科学的相关理论。它专门针对软件开发人员,但适用于任何知识工作者。


0

对于像我这样的编程新手,我推荐这本书“像程序员一样思考”。在第一章中,它涵盖了解决问题的技术,例如从已知的知识,还原,类比和试验开始,重新定义和划分问题。

然后,还有一些更高级的技术和C ++示例:解决数组,指针和动态内存,类,递归,代码重用的问题。我无法对此部分发表评论,因为这对我来说太难了。


-1

我解决了尽可能多的问题。我也喜欢一些益智的书像这一个。我还尝试解决问题的游戏,例如涉及质数的数学游戏,数独,河内塔等等。只要找到要解决的问题即可。另外,请尽可能将其编码。



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.