<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ 软件开发 - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ freeCodeCamp 是一个免费学习编程的开发者社区，涵盖 Python、HTML、CSS、React、Vue、BootStrap、JSON 教程等，还有活跃的技术论坛和丰富的社区活动，在你学习编程和找工作时为你提供建议和帮助。 ]]>
        </description>
        <link>https://www.freecodecamp.org/chinese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ 软件开发 - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/chinese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 06 Oct 2026 06:06:47 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/chinese/news/tag/software-development/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ 软件开发人员是做什么的？软件工程师职业概述 ]]>
                </title>
                <description>
                    <![CDATA[ 如果你正在学习成为一名专业的软件开发人员，你可能想知道软件开发人员每天在工作中做什么。 在本文中，我将讨论软件开发人员的典型一天以及做什么工作。 软件开发人员的主要职责 作为一名软件开发人员，你的主要职责将包括修复代码库中的错误、构建新功能、为应用程序编写测试、编写文档、执行代码审查以及参与团队讨论会议。 非常有经验的开发人员，如软件架构师，将负责软件应用程序的更高级别的技术和架构决策。 让我们更详细地了解每一个职责。 调试代码库和修复错误 当你刚开始作为软件开发人员时，你的主要职责之一是修复小错误并调试代码库中的小错误。 会有一个问题（issue）列表，将工作分解为可管理的部分，其中一些将包含应用程序中的错误。 你将处理一些有助于你学习代码库的小项目。作为初级开发人员，头几个月花在代码库上是很正常的，很多工作对你来说都是新的。 只需确保提出大量问题并尝试与团队中的其他开发人员结对编程即可。与其他开发人员协作将帮助你学习新技术并更快地成长。 我从我的同事那里学到了很多东西，而且大多数时候，他人可以帮助我以不同的方式看待问题。 构建新功能 随着你开始对工作感觉更加自在 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/what-does-a-software-developer-do-software-engineer-career-overview/</link>
                <guid isPermaLink="false">63034f3860480505ded7ae73</guid>
                
                    <category>
                        <![CDATA[ 职业发展 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 软件开发 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Mon, 22 Aug 2022 09:20:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2022/08/desola-lanre-ologun-IgUR1iX0mqM-unsplash.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/what-does-a-software-developer-do-software-engineer-career-overview/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">What Does a Software Developer Do? Software Engineer Career Overview</a>
      </p><p>如果你正在学习成为一名专业的软件开发人员，你可能想知道软件开发人员每天在工作中做什么。</p><p>在本文中，我将讨论软件开发人员的典型一天以及做什么工作。</p><h2 id="-">软件开发人员的主要职责</h2><p>作为一名软件开发人员，你的主要职责将包括修复代码库中的错误、构建新功能、为应用程序编写测试、编写文档、执行代码审查以及参与团队讨论会议。</p><p>非常有经验的开发人员，如软件架构师，将负责软件应用程序的更高级别的技术和架构决策。</p><p>让我们更详细地了解每一个职责。</p><h3 id="--1">调试代码库和修复错误</h3><p>当你刚开始作为软件开发人员时，你的主要职责之一是修复小错误并调试代码库中的小错误。</p><p>会有一个问题（issue）列表，将工作分解为可管理的部分，其中一些将包含应用程序中的错误。</p><p>你将处理一些有助于你学习代码库的小项目。作为初级开发人员，头几个月花在代码库上是很正常的，很多工作对你来说都是新的。</p><p>只需确保提出大量问题并尝试与团队中的其他开发人员结对编程即可。与其他开发人员协作将帮助你学习新技术并更快地成长。</p><p>我从我的同事那里学到了很多东西，而且大多数时候，他人可以帮助我以不同的方式看待问题。</p><h3 id="--2">构建新功能</h3><p>随着你开始对工作感觉更加自在并获得更多经验，你将开始对代码库承担更多责任。你可以开始构建新功能。</p><p>功能是软件产品的基本组成部分。这种类型的工作将比小错误修复花费更长的时间，并让你有机会为项目做出更多贡献。</p><p>这也将为你提供解决更复杂问题并作为开发人员成长的机会。我处理的第一个功能是为公司网站实现一个浅色/深色主题。</p><p>我花时间思考如何为我们现有的代码库实现此功能的最佳方法，然后我开始实施我的解决方案并测试网站。</p><p>最后阶段是通过代码审查并更新网站文档以包含新功能。</p><p>整个经验教会了我如何构建可维护和可扩展的解决方案，这些解决方案可以很好地与现有代码库配合使用。</p><h3 id="--3">为应用程序编写测试</h3><p>软件应用程序的一个重要元素是确保它们以应有的方式工作。这就是测试的用武之地。</p><p>软件开发人员负责编写不同类型的测试，例如单元测试、集成测试、功能测试等等。他们还可能参与手动测试，其中包括开发人员使用一组测试用例检查应用程序，并确保它按预期的方式工作。</p><p>我最初的测试经验之一是冒烟测试和为我们的几个应用程序编写手动测试指南。冒烟测试是开发人员检查应用程序并确保基本功能完好无损。</p><p>编写测试指南涉及开发人员了解应用程序的所有功能并创建测试用例。这些测试用例涉及写下用户应该经历的确切步骤和预期结果。</p><p>我第一次必须编写手动测试指南时，并没有意识到在写出每个步骤时需要多么具体。但是一旦我写了几个测试用例，这个过程就开始变得更有意义，编写这些手动测试用例变得更容易了。</p><p>如果你有兴趣了解有关测试的更多信息，那么我建议你阅读这篇<a href="https://chinese.freecodecamp.org/news/types-of-software-testing/"> freeCodeCamp 文章</a>。</p><h3 id="--4">编写文档</h3><p>文档是任何软件应用程序的重要组成部分。记录应用程序的主要功能以及为开发人员在本地运行它所需的所有步骤非常重要。</p><p>每当你加入一个新项目时，如果你发现文档中有任何令人困惑或遗漏的地方，请务必向团队提出。这将是更新文档的好机会。</p><p>有时，当你正在处理一个项目并且团队忙于按时完成任务时，你们可能会耽误文档更新。当事情稍微平静下来时，请确保重新访问文档并确保它是最新的和准确的。</p><h3 id="--5">执行代码审查</h3><p>构建软件是一项团队活动，团队中的每个人都必须让他们的同事审查他们的代码。对代码库进行更改后，你将创建所谓的“拉取请求 pull request”。</p><p>该拉取请求代表你要添加到代码库的更改。然后，你将请求团队成员进行审核，他们将查看你的代码并提供反馈。</p><p>重视反馈也很重要，因为你的团队只是试图帮助你发现问题并就如何优化你的解决方案提出建议。</p><p>提供建设性的反馈并确保拉取请求中的所有内容都能解决问题或满足新功能的要求也很重要。</p><p>要了解有关代码审查过程的更多信息，请阅读这篇 <a href="https://www.freecodecamp.org/news/proven-code-review-best-practices/">freeCodeCamp 文章</a>。</p><h3 id="--6">参加团队讨论会</h3><p>构建软件产品有很多移动组件。在整个过程中，整个团队能够保持信息对称，这一点很重要。</p><p>这些会议的目的是让每个团队成员与团队分享状态更新，并分享任何阻碍他们推进项目的障碍。如果你是软件开发的新手，你可能会对参加会议感到紧张。</p><p>你可能还会对会议中使用的一些讨论和所有新术语感到不知所措。试着提出问题并记住，理解软件过程的所有细节需要一段时间。</p><p>我的自然倾向是在会议中更加矜持，但我更加努力地直言不讳，并就我不明白的问题提出问题。有时你会发现其他人也有同样的问题，并且很高兴你问了这个问题。</p><p>尽你最大的努力积极参与会议，分享你对项目的意见，并就你需要帮助的问题提出问题。</p><h2 id="--7"><strong>总结</strong></h2><p>如你所见，构建软件产品有很多组件。你的时间不会花在连续 8 小时编写代码上。</p><p>相反，你的时间将被用于会议、结对编程、调试代码、阅读文档、编写文档和测试软件。</p><p>我希望你喜欢这篇文章，并更好地理解成为一名软件开发人员是什么样的。祝你在软件之旅中好运。</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 如何成为一名成功的软件工程师 ]]>
                </title>
                <description>
                    <![CDATA[ 原文：How to be a successful software engineer [https://www.freecodecamp.org/news/how-to-be-a-successful-software-engineer-6f82a5b1a82e/] ，作者：Zhia Chong [https://www.freecodecamp.org/news/author/zhia/] 对于那些刚开始职业生涯的年轻、聪明的软件工程师来说，这里有一些我作为软件工程师读到或收到的最好的建议。 这里的大部分建议都是针对软件工程人群的，但我相信有很多建议是适用于任何职业的。 简而言之，我最好的建议是：  * 少承诺多做事，做的成果大于预期  * 完美是优秀的敌人  * 坚持下去  * 尽早收集反馈意见  * 先自己探索再寻求帮助  * 简化 少承诺多做事,做的成果大于预期 低估完成一项功能所需的工作量，在新手中，甚至在有经验的工程师中，都是极其普遍的错误。 如果你看看那些超出预算和/或延迟交付的项目的数量，你会感到非常惊讶。这是一个疯狂的数字，大约是50% 。 让我们考虑 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/how-to-be-a-successful-software-engineer/</link>
                <guid isPermaLink="false">6261161c99ec7406219e7219</guid>
                
                    <category>
                        <![CDATA[ 软件开发 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ luojiyin ]]>
                </dc:creator>
                <pubDate>Thu, 21 Apr 2022 01:32:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2022/04/danielle-macinnes-IuLgi9PWETU-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>原文：<a href="https://www.freecodecamp.org/news/how-to-be-a-successful-software-engineer-6f82a5b1a82e/">How to be a successful software engineer</a>，作者：<a href="https://www.freecodecamp.org/news/author/zhia/">Zhia Chong</a></p><!--kg-card-begin: markdown--><p>对于那些刚开始职业生涯的年轻、聪明的软件工程师来说，这里有一些我作为软件工程师读到或收到的最好的建议。</p>
<p>这里的大部分建议都是针对软件工程人群的，但我相信有很多建议是适用于任何职业的。</p>
<p>简而言之，我最好的建议是：</p>
<ul>
<li>少承诺多做事，做的成果大于预期</li>
<li>完美是优秀的敌人</li>
<li>坚持下去</li>
<li>尽早收集反馈意见</li>
<li>先自己探索再寻求帮助</li>
<li>简化</li>
</ul>
<h4 id="">少承诺多做事,做的成果大于预期</h4>
<p>低估完成一项功能所需的工作量，在新手中，甚至在有经验的工程师中，都是极其普遍的错误。</p>
<p>如果你看看那些超出预算和/或延迟交付的项目的数量，你会感到非常惊讶。这是一个疯狂的数字，大约是50% 。</p>
<p>让我们考虑一下这个数字。<strong>50%的项目不是超预算就是延迟交付。</strong></p>
<p>这意味着在每1000个项目中，有500个，或其中的一半，是延迟交付或超预算。这让我很困惑。</p>
<p>我清楚地记得在我的第一个技术项目中，我被赋予了领导开发的自主权。这意味着我是一个能写出技术设计文件的人，详细说明开发整个功能需要多少时间，我们需要多少工程师，等等。</p>
<p>作为一个热心的、年轻的工程师，我<strong>严重低估</strong>了完成工作所需的时间。实际完成需要了2-3倍时间的样子。</p>
<p>当时我对自己相当失望。结果是，我和一些同事的关系也很紧张。</p>
<p>后来我的经理让我坐下来，给我一些改变生活的建议。他对我说：<strong>少承诺多做事，做的成果大于预期</strong>。</p>
<p>这意味着你应该保守估计，为你的估计提供足够的缓冲，以应对各种事情出错（因为 <a href="https://en.wikiquote.org/wiki/Murphy%27s_law">任何事情都会可能出错的</a>），并争取提前/低于成本交付你的项目。</p>
<p>好处：</p>
<ol>
<li>给你充足的时间来开发和重构。功能开发总是需要很多的时间，可以回去修复一些你（或你之前的团队）多年来积累的 <a href="https://en.wikipedia.org/wiki/Technical_debt">技术债务</a>。</li>
<li>允许有时间找出<strong>最好的</strong>设计，而不仅仅是一个工作设计。</li>
<li>在功能开发过程中，有很多事情会出错。同事休假、你生病、开会、你的孩子生病、你的车被撞......这样的事情不胜枚举。认识到事情可能出错是很重要的，你要确保你的日程安排中有一个缓冲区。</li>
<li>由于第2点，你能够持续地产生高质量的工作，由于第3点，你能够每次都按时交付，你现在被认为是公司内部的<strong>高绩效者</strong>，知道你在说什么，并且可以被信任。这就是双赢。</li>
</ol>
<p>你可能会说，承诺不足的坏处是，别人会认为你在偷懒，因为你估计了10周的工作，而这些工作本来可以在2周内完成。</p>
<p>说实话，我也曾为此纠结过一段时间。然而，我后来意识到，只要<strong>你在整个过程中与利益相关者开诚布公并保持一致</strong>，你就会没事。</p>
<p>你是负责提供资源的人，因为其他人依赖你的专业知识。他们知道你是对代码库最熟悉的人，他们相信你能提供一个最佳猜测。在功能开发过程中会发生各种事情，<strong>只要你开诚布公</strong>，一切都会好起来的。</p>
<h4 id="">完美是美好的敌人</h4>
<p>作为一名软件工程师，你往往会发现一个项目在交付前缺少这个或需要那个。一个项目可能是一个编码项目，或者只是一个你需要写的技术设计文件。</p>
<p>经常发生的情况是，随着你对项目的深入研究，你开始发现有更多的东西是你没有考虑到的。于是，你卷起袖子，把目光投向了事物的底部。你决定在接下来的几个小时里进行研究，并试图把所有的事情都解决掉。</p>
<p>十个小时过去了，实际上什么也没做，你堆积了比以前更多的工作。</p>
<p>如果这对你来说听起来很熟悉，并不是你一个人这样。</p>
<p>这种情况发生在每个人身上--而且发生在我们最好的人身上。我相信，我们从小就被灌输了一个条件，那就是要做出<strong>完美</strong>或<strong>完整</strong>的作品。</p>
<p>我们生活在一个充满约束的世界里，我们所做的每一个重要决定都是有代价的。</p>
<p>这里的<strong>关键是认识到我们并不了解一切</strong>。你可能没有意识到，但你所做的大多数决定背后都有无数的选择。</p>
<p>例如，作为一个计算机科学专业的学生，大学毕业后的第一份工作应该怎么做？除了为创业公司或大型科技公司工作外，你还可以在海外做自由职业者、开一个Youtube频道、在 Udemy上教计算机科学、开一个博客，或者开自己的公司。选择的清单是无限的，你今天做出的决定将基于几个关键标准。</p>
<p>你最终会做出一个对你来说<strong>最好的</strong>决定，而不一定是客观上最好的，因为每个人都是独特的，没有一刀切的情况。</p>
<p>在这种情况下，我们能做的最好的事情是收集尽可能多的信息，承认我们不知道的东西的风险，并从中做出最佳决定。</p>
<figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-media-1.freecodecamp.org/images/1*haY65XZWvENvnYaLwHQHLQ.png" class="kg-image" alt="失败的概率" width="600" height="400" loading="lazy"><figcaption>失败的概率</figcaption></figure>
<p>我思考的方式是，我为最坏的情况分配一个概率，并将其用于我的决策过程。这是我从一本叫作 <a href="https://amzn.to/2Id7ZV6">Ray Dalio的《原则》</a>的书中学到的，这是一本我强烈推荐的好书。</p>
<p>如果发生可怕错误的概率在统计学上是显著的：</p>
<ol>
<li>寻找一个更好的解决方案</li>
<li>找到减轻风险的方法，使其不再具有统计学意义</li>
</ol>
<p>当做出决定，我就执行它，然后继续前进。</p>
<p>对于我遇到的每一个问题，我都是如此重复。我在解决这些问题的过程中找到了乐趣，在某些方面，生活的乐趣在于解决不同程度和复杂性的问题。</p>
<figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-media-1.freecodecamp.org/images/1*haY65XZWvENvnYaLwHQHLQ.png" class="kg-image" alt="决策框架" width="600" height="400" loading="lazy"><figcaption>决策框架</figcaption></figure>
<h4 id="">坚持下去</h4>
<p>功能变更是一个自然想到的反例。</p>
<p>你一直想要添加更多功能，因为你觉得当前的功能看起来像是从90年代的万维网下载的。你觉得它还没有准备好。你认为没有人愿意使用你的产品。</p>
<p>然而，请注意，所有这些事情都是在<strong>你自己的脑子里进行的。这些都没有得到验证。</strong> 你不知道人们想要什么，直到你把东西放在他们手中。</p>
<p>你的目标应该是在项目开始时设定一个固定的目标，无论如何都要努力实现它。</p>
<p>其好处有两方面：</p>
<ol>
<li><strong>这可以减少功能变更，并迫使你专注于</strong>。关于这一点，很多书都有记载，我不会用具体的细节来烦扰你。无论你在什么位置，保持注意力聚焦是至关重要的。</li>
<li>我们人类<strong>喜欢即时的满足感。</strong> 如果你能在两周内发布一些东西，那就去做吧！提前计划你的项目在2周内应该能够实现的目标，然后把它交到你的用户手中！这是非常令人满意的。这是一种非常令人满意的感觉，即使它真的惨遭失败，至少你坚持了你的目标，你现在已经收集了有价值的反馈来进行迭代。</li>
</ol>
<p>这使我想到了我的下一个观点。</p>
<h4 id="">尽早收集反馈意见</h4>
<p>我个人认为，我们应该始终以尽早发布、经常发布为目标，并尽快收集反馈。</p>
<p>当然，我承认这主要是对软件项目来说是可能的。但请听我说。</p>
<p>经常发布和尽早发布可以让你尽早收集反馈。拥有一个健康的反馈循环是一个非常重要的，甚至是最重要的，你的项目的方面。</p>
<figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-media-1.freecodecamp.org/images/1*D2CuccFu10dqpd3uL8NeFw.png" class="kg-image" alt="产品的反馈" width="600" height="400" loading="lazy"><figcaption>产品的反馈</figcaption></figure>
<p>你应该在产品开发的早期就纳入一个反馈，这样你就知道你是在为正确的人开发正确的产品，有正确的约束。</p>
<p>同样重要的是要注意，<strong>提前发布并不意味着发布一个坏的产品。一个破损的产品对任何人都没有用，这是对用户的不尊重。</strong></p>
<p>你应该想出并提供一个最小可行的产品（MVP），这意味着你的产品应该以最低的方式来满足需求。</p>
<p>有一点需要注意的是，收集反馈并不意味着需要从每个用户那里获得反馈。</p>
<p>考虑对你的用户进行细分。获取一小部分用户，最好是来自不同背景的用户（而不仅仅是朋友和家人）。让你的产品在他们手中，这样，如果你搞砸了，至少你的其他用户还没有意识到，你就有时间来解决这个问题。</p>
<h4 id="">先自己探索再寻求帮助</h4>
<p>很多年轻的工程师倾向于提出问题，而不试图自己去寻找答案。当他们遇到以前没有遇到过的事情时，他们的第一直觉是问高级工程师是怎么做的，如何完成某件事。</p>
<p>在问别人之前，自己先找答案，对你有很大的好处。原因有两个方面：</p>
<ol>
<li>深入探索使你能够探索你以前可能从未探索过的领域。它让你有机会接触并熟悉不同的代码库。</li>
<li>当你升到一个更高的位置时，人们会依赖你的指导。随着时间的推移，你将成为小组中的高级人员。人们向你寻求帮助，无论如何你以后都需要学习这种技能。</li>
</ol>
<p>许多开发人员开玩笑说，他们的大部分时间都花在 Google 和 StackOverflow上。我完全同意这一点，但不是因为你可能认为的原因。</p>
<p>为模棱两可的问题寻找答案的能力是一种非常令人羡慕的技能。随着时间的推移，互联网已经发展成为一个容易获取的信息宝库，你可以在任何时间、任何地点、任何设备上使用。</p>
<p>然而，<strong>提出正确问题的能力</strong>要比回答问题的能力更难获得。</p>
<p>随着你的职业生涯的发展，你会开始意识到，弄清正确的问题将是你需要学习的技能，如果你真的掌握了它，它将为你带来奇迹。</p>
<h4 id="">简化</h4>
<p>在你的工作和生活中努力追求简单。</p>
<p>很多时候，我看到初级开发人员在一个编码项目上工作，他们会使用抽象、继承、接口和一些非常有趣的框架。然而，尽管有这些花哨的东西，他们却在写新的代码，增加了不必要的复杂性。</p>
<p>维护这些代码的人在大多数情况下不会是写代码的人。任何额外增加的复杂性都会使新的工程师更难加入。</p>
<p>当你成为一名成熟的软件工程师时，你会意识到写代码不仅仅是性能优化的问题，也是为人优化的问题。写出别人可以轻松推理的代码也同样重要。</p>
<p>这就是代码可读性和代码组织发挥作用的地方。</p>
<p>除非性能是一个真正的问题，否则总是选择更简单、更干净的方法。</p>
<p>我相信简单性也会延伸到工作以外的生活。保持你的生活不受干扰。减少你生活中不必要的物品的数量。专注于对你重要的事情。优化你的生活，以获得经验而不是财产。这些是你在生活中要牢记的一些事情。</p>
<h4 id="">我读过的书和我喜欢的资源</h4>
<ul>
<li><a href="https://amzn.to/2GMEI6C">Principles by Ray Dalio</a> — ? 这是我一段时间以来读到的最好的书之一。作者谈到了我们在生活和工作中都可以应用的原则。我把他的解决问题的框架纳入我的日常生活中。</li>
<li><a href="https://amzn.to/2Gmb3xq">How to win friends and influence people</a> — 关于建立和管理人际关系的经典书籍？这本书帮助我了解了如何在工作场所管理自己的关系。</li>
<li><a href="https://amzn.to/2pPZUhq">The Senior Software Engineer</a> — ? 这本书很好，有关于如何成熟为一名软件工程师的行动项目。我就是在这里学会了先自己探索再问别人。</li>
<li><a href="https://amzn.to/2GDgxY6">Crucial Conversations</a> — 关于如何在高风险情况下与人打交道的好书。非常适用于生活的不同方面。无论是为获得更高的薪酬进行谈判，还是解决与配偶的沟通问题，这本书都有一些解决这些问题的好建议。</li>
<li><a href="https://amzn.to/2EbBcgt">Lean Startup</a> — 这是一本关于如何在进一步投资之前使用最小可得产品（MVP）来测试一个想法的好书。我过去曾用它来测试几个创业的想法。</li>
<li><a href="https://amzn.to/2InAGi4">Purple Cow</a> —? 很喜欢这本书。我主要用它来测试我心中的不同创业想法。它谈到了如何推销你的创业公司，以及如何使它从其他公司中脱颖而出。</li>
<li><a href="https://www.evernote.com/referral/Registration.action?sig=3dbd8660e92a8ca68faeb24c552fd32a492c1e620fe4c77e45844685fed05492&amp;uid=18085328">Evernote</a> — 这是我用过的最好的记事应用程序。我曾经使用过。强烈推荐它！</li>
<li><a href="https://amzn.to/2IuEiPw">Moleskin notebook</a> — 我真的很喜欢这个人。它的质量非常高。价格略高，但由于我每天都在使用它，我认为这是一项很好的投资。每天拿着一本漂亮的笔记本，让我更有动力去写更多的笔记。</li>
<li><a href="https://amzn.to/2Gwb9qj">Pilot G2 (Black)</a> — 这是我使用过的最好的笔，也是我唯一会使用的笔。我从亚马逊大量购买这些笔，走到哪里都带着它们。我的背包里有一支，办公室里有一支，我的家庭办公室里也有一支，这样我身边总是有一支笔。它写得很好，墨水流动顺畅，我喜欢用它写字的感觉。再加上Moleskin，有时我只想拿起G2在上面随意写写画画，因为这两样东西在一起是如此完美。</li>
</ul>
<p><em>关注我在 <a href="https://twitter.com/zhiachong">Twitter</a>, <a href="https://www.facebook.com/zhiachong.tech">Facebook</a>, 和 <a href="https://www.linkedin.com/in/zhiachong/">LinkedIn</a>。加入 <a href="http://eepurl.com/dnt9Sf">我的邮件列表</a>， 我定期发送技巧、窍门和行业知识。</em></p>
<p><em>如果你喜欢这篇文章，请在下面评论：<strong>你对软件工程师的第一大建议是什么？</strong></em></p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 开发者如何选择编程语言（一） ]]>
                </title>
                <description>
                    <![CDATA[ “PHP是最好的语言！”“人生苦短，我用 Python！”“JavaScript 一统天下”……关于编程语言的讨论和争论时不时就在我们眼前出现。 其实没有一种编程语言在所有领域（操作系统、硬件驱动、办公软件、游戏、Web 服务器、数据库、搜索引擎、大数据处理、高频交易、机器学习、数值计算等等）都是银弹。我们要学会根据应用场景选择最适合的编程语言。 那么我们如何根据应用场景和编程语言的特性来选择适合的编程语言呢？我认为可以考察编程语言的以下特点和特性： 1. 执行方式 1.1. 汇编执行型 汇编语言（assembly）的源文件由汇编器（assembler）转换为 CPU 可直接执行的二进制程序文件。 1.2. 编译、（汇编）、执行型 C / C++ / Fortran / Pascal / Go / Rust 等编程语言的源文件一般由编译器（compiler）先编译为汇编指令，再由汇编器生成 CPU 可直接执行的二进制程序文件。 现在编译器一般不会把编译出来的汇编指令输出到文件，而通常在内存中直接交给内置的汇编器进行处理，所以我们会看到这些编程语言的编译器直接就输出一个可执行的 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/how-to-choose-a-programming-language/</link>
                <guid isPermaLink="false">5f8038aa5f583f0565090a33</guid>
                
                    <category>
                        <![CDATA[ 编程语言 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 编程学习 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 软件开发 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Yuping Wu ]]>
                </dc:creator>
                <pubDate>Fri, 09 Oct 2020 10:25:06 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2020/10/daria-shevtsova-zbWFT4eVopE-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>“PHP是最好的语言！”“人生苦短，我用 Python！”“JavaScript 一统天下”……关于编程语言的讨论和争论时不时就在我们眼前出现。</p><p>其实没有一种编程语言在所有领域（操作系统、硬件驱动、办公软件、游戏、Web 服务器、数据库、搜索引擎、大数据处理、高频交易、机器学习、数值计算等等）都是银弹。我们要学会根据应用场景选择最适合的编程语言。</p><p>那么我们如何根据应用场景和编程语言的特性来选择适合的编程语言呢？我认为可以考察编程语言的以下特点和特性：</p><h2 id="1-">1. 执行方式</h2><h3 id="1-1-">1.1. 汇编执行型</h3><p>汇编语言（assembly）的源文件由汇编器（assembler）转换为 CPU 可直接执行的二进制程序文件。</p><h3 id="1-2-">1.2. 编译、（汇编）、执行型</h3><p>C / C++ / Fortran / Pascal / Go / Rust 等编程语言的源文件一般由编译器（compiler）先编译为汇编指令，再由汇编器生成 CPU 可直接执行的二进制程序文件。</p><p>现在编译器一般不会把编译出来的汇编指令输出到文件，而通常在内存中直接交给内置的汇编器进行处理，所以我们会看到这些编程语言的编译器直接就输出一个可执行的程序文件。</p><p>C / C++ 的编译器 GCC / G++ 和编译器后端 LLVM 都可以把编译出来的汇编指令输出到文件中，供我们查看。</p><figure class="kg-card kg-image-card"><img src="https://chinese.freecodecamp.org/news/content/images/2020/10/ilya-pavlov-OqtafYT5kTw-unsplash.jpg" class="kg-image" alt="ilya-pavlov-OqtafYT5kTw-unsplash" width="2000" height="1335" loading="lazy"></figure><h3 id="1-3-">1.3. 编译、解释执行型</h3><p>Java / Scala 源文件由 Java 编译器编译成二进制的 class 文件，由 Java 虚拟机（Java virtual machine ，简称 JVM）解释执行。C# / <code>VB.net</code> 源文件由编译器编译为二进制的 exe 或 dll 文件，由 .net 运行时（runtime）程序解释执行。</p><h3 id="1-4-">1.4. 解释、执行型</h3><p>解释执行型语言通常又被称为脚本（script）语言。例如 Bash 脚本、Powershell脚本、JavaScript、Python、PHP、Ruby、Matlab 脚本、Mathematica 脚本等。它们的源文件由相应的运行时程序直接读取并解释执行。</p><h3 id="1-5-">1.5. 编译转换、解释执行型语言</h3><p>TypeScript、JSX、CoffeeScript 等语言通常是先由编译转换程序转换为 JavaScript，再由 JavaScript 运行时解释执行。</p><h3 id="1-6-">1.6. 其他类型</h3><p>例如 Kotlin 即可以被编译为 Java 的 class文件由 JVM 解释执行，也可以被编译转换为 JavaScript ，还可以被编译为可执行程序直接被 CPU 执行。</p><h3 id="1-7-">1.7. 不同执行方式的执行效率</h3><p>Java 的 class 文件中和 .net 的二进制文件中的指令都是类似 CPU 指令的代码，各硬件平台上的虚拟机 / 运行时程序只需花很少的代价就可以将其转换成该平台上的 CPU 指令执行，而不需要再对源代码进行词法语法分析。因此这些编译、解释执行型语言的运行效率通常比下面要介绍的解释执行型语言要高。</p><p>但是编译、解释执行型语言又比汇编 / 编译执行型语言多一个将虚拟机指令转换为 CPU 指令的过程，所以它们运行效率通常又比汇编 / 编译执行型语言的低。</p><p>因此，在对执行效率要求高的系统（例如高频交易的系统、核心网络的路由器中的路由程序）中，通常不采用解释执行型语言，而是采用编译执行型语言来开发。</p><h3 id="1-8-">1.8. 在系统级编程方面的适用性</h3><p>由于编译解释型语言或者脚本语言的运行效率不如编译执行型语言，而且需要虚拟机或者解释器才能运行，因此在操作系统或者驱动程序的编程中通常使用的是编译执行型的语言，如 C / C++ / Rust。</p><p>而在与 CPU 架构密切相关的地方，例如操作系统的内存管理模块的设置页表地址的程序，或者需要使用 CPU 的 IO / 中断等指令的时候，基本上只能使用汇编语言。</p><figure class="kg-card kg-image-card"><img src="https://chinese.freecodecamp.org/news/content/images/2020/10/aleksander-vlad-jiVeo0i1EB4-unsplash--1-.jpg" class="kg-image" alt="aleksander-vlad-jiVeo0i1EB4-unsplash--1-" width="2000" height="1333" loading="lazy"></figure><h2 id="2-">2. 内存管理</h2><h3 id="2-1-">2.1. 手动管理内存</h3><p>汇编语言以及 C / C++、Fortran、Pascal 等许多编译执行型语言都需要手动管理内存，由程序员手动回收无用的数据占用的内存。</p><h3 id="2-2-">2.2. 自动管理内存</h3><p>编译执行型语言中的 Go，Java、C#、<code>VB.net</code> 等绝大多数编译、解释执行型语言，还有 JavaScript、Python、PHP 等绝大多数脚本语言都是由运行环境自动管理内存（增加作为对象池的堆的内存、无用对象的垃圾回收等）。</p><p>其中 Go 主要采用标记清除算法做垃圾回收（英文 Garbage Collection，缩写 GC）。而 Java 可以指定标记清除、标记整理、标记复制与标记清除结合的分代 GC 算法等等算法中的一种做垃圾回收。对于其他语言的 GC 算法，我没了解过，读者有兴趣可以自己查阅资料。</p><h3 id="2-3-">2.3. 半自动管理内存</h3><p>Rust 语言中多数情况下，通过对象的所有权机制可以使得对象的内存申请和释放在编译期就可以确定，这些对象的内存管理可以看成是由编译器自动处理的。对于少数不受所有权机制限制的不安全对象，仍需要手动管理内存。</p><h3 id="2-4-">2.4. 自动管理内存的优劣</h3><p><strong>2.4.1. 优点</strong></p><p>把程序员从释放无用内存或者管理内存池等逻辑中解放出来，降低内存泄漏的可能性。</p><p><strong>2.4.2. 缺点</strong></p><p>程序员通常无法控制垃圾回收的时机，而垃圾回收通常需要暂停程序的运行，这会导致无法预料的程序卡顿。</p><figure class="kg-card kg-image-card"><img src="https://chinese.freecodecamp.org/news/content/images/2020/10/goran-ivos-TorAcb4AQRc-unsplash--1--1.jpg" class="kg-image" alt="goran-ivos-TorAcb4AQRc-unsplash--1--1" width="2000" height="1501" loading="lazy"></figure><h2 id="3-vs-">3. 强类型 VS 弱类型</h2><h3 id="3-1-">3.1. 强类型</h3><p>通常在需要编译的语言（如 C / C++ / Java / C# / Kotlin 等语言）中，一个变量 / 对象的属性必须在声明之后才能使用（一个变量必须被声明后才能被读，必须被声明后或者在声明时才能写；一个对象的属性没被定义的话不能被写入），而且一个变量 / 对象的属性 / 函数的入参与返回值的数据类型在声明时就确定下来、不能再改变了。如果违反了这两个约束，那么在编译源代码的时候就会报错。</p><h3 id="3-2-">3.2. 弱类型</h3><p>通常在脚本语言（如 Python、JavaScript、PHP）中，一个对象的属性是可以动态变化的，甚至变量不需要声明就可以使用（读或者写）；一个变量 / 对象的属性 / 函数的入参与返回值的数据类型是不固定的。</p><h3 id="3-3-">3.3. 强弱结合</h3><p>在 TypeScript 和在版本 7 以后的 PHP 等语言之中，既可以使用动态类型，也可以规定某些变量 / 对象的属性 / 函数的返回值的数据类型。如果违反了规定的数据类型，会引起编译转换器 / 解释器报错。</p><h3 id="3-4-">3.4. 不适用</h3><p>在汇编语言中通常没有变量（不考虑预处理器），因此不存在静态类型或者动态类型的问题。</p><h3 id="3-5-">3.5. 弱类型的优劣</h3><p><strong>3.5.1. 优点</strong></p><p>初学者不需理解数据类型就可入门，进行简单的编程。</p><p>程序员不受数据类型的限制，可以采取更灵活的实现方式，例如在某个类的对象中增加一个属性来存储一些额外的数据，而不需要改变类的定义。</p><p>程序变更前后的兼容性比较好。例如一个类增减了成员属性，旧类的实例对象序列化后，反序列化为新类的实例对象时，强类型语言可能会因字段不一致而出错，而弱类型语言则通常不会出错。又例如 JavaScript 中某个函数增加一个默认为空的入参，调用方不需修改即可兼容。</p><p><strong>3.5.2. 缺点</strong></p><p>弱类型语言不能在编译期确定变量的数据类型，从而不能在编译期对一些变量的内存使用进行优化（例如内存页对齐、缓存对齐等）。</p><p>弱类型语言在运行时可能出现由于类型混乱导致的错误。例如错把数字变量比较的规则应用于字符串变量的比较，从而得到 “10” &lt; “2”。</p><p>弱类型语言中，如果一些变量、对象属性、函数的入参或返回值使用的数据类型过多，会降低代码的可读性和可维护性，甚至导致程序代码混乱而出错。</p><figure class="kg-card kg-image-card"><img src="https://chinese.freecodecamp.org/news/content/images/2020/10/maxwell-nelson-taiuG8CPKAQ-unsplash--1-.jpg" class="kg-image" alt="maxwell-nelson-taiuG8CPKAQ-unsplash--1-" width="2000" height="1333" loading="lazy"></figure><h2 id="4-">4. 并行 / 并发模型</h2><p>首先要说明的是，并行和并发并不是一样的概念，它们的区别可以参考这个<a href="https://www.zhihu.com/question/33515481">知乎问题 1</a>。并行的一定是并发的，并发的不一定是并行的。</p><h3 id="4-1-">4.1. 多线程并行</h3><p>汇编语言可以直接调用操作系统的 API 来实现多线程。</p><p>C / C++ 可以通过 pthread 库或者直接调用操作系统的 API 来实现多线程。</p><p>Java 可以调用 Java API 来实现多线程，C# / <code>VB.net</code> 则可以调用 .net 的 API 来实现多线程。</p><p>Python 也可以通过其官方 API 实现多线程。虽然最普遍使用的 Python 运行时 CPython 和 PyPy 目前由于全局解释器锁（GIL）的缘故使不同线程不能在多个 CPU 核心（core）中并行运行，但还是有某些 Python 运行时如 Jython 已去掉了 GIL。</p><p>JavaScript 在支持 worker API 的运行时程序上可以通过创建 worker 来实现多线程，但这些线程之间只能通过消息通讯，不能共享内存。</p><h3 id="4-2-">4.2. 用户态线程 / 协程并发</h3><p>Python 可以通过生成器、asyncio 库或者 async / await 语法来使用协程（coroutine）。</p><p>Go 可以通过 goroutine 来使用协程。Gorotine 是可以并行的，可以充分利用多个 CPU 核心。</p><p>Kotlin 可以通过 kotlinx.coroutine 包提供的 API 来使用协程。</p><h3 id="4-3-io-api-">4.3. 非阻塞 IO API + 内置事件循环并发</h3><p>JavaScript 运行时通过提供非阻塞的 IO API 以及内部实现事件循环的方式，使得 JavaScript 可以在等待 IO 返回数据的同时可以并发地运行其他处理逻辑。</p><h3 id="4-4-">4.4. 多进程并行</h3><p>PHP 目前没有语言上的特性或者自带的 API 可以实现多线程或协程，要实现多线程需要额外安装 pthreads 拓展或者 Swoole 拓展。通常 PHP 的并发是通过多进程来实现的。</p><p>如果使用有 GIL 的 Python 运行时程序、Ruby 运行时程序或者不支持 worker API 的 JavaScript 运行时程序（例如版本 10 以前的 Node.js），如果想要充分利用多个 CPU 核心，也需要通过多进程来实现并行。</p><p>未完待续。</p><p></p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
