<?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[ Miaomiao Ma - 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[ Miaomiao Ma - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/chinese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 15:27:31 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/chinese/news/author/miaomiao/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ 程序员职业发展的 23 种路径 ]]>
                </title>
                <description>
                    <![CDATA[ 过去 5 年中，我在芝加哥的一些编程训练营做过很多次分享。 听到的问题大多千篇一律：接下来我该学什么语言呢？ [https://www.freecodecamp.org/news/what-programming-language-should-i-learn-first-19a33b0a467d/] 如何准备技术面试？ [https://www.freecodecamp.org/news/interviewing-prep-tips-and-tricks/] 你们公司招人吗？诸如此类。 但有一个问题直击我的灵魂深处：如果我不想再当程序员了，该怎么办？ 关于这个问题我后来思考了很久。我带产品和技术团队将近十年了，我意识到自己遇到了新的挑战。所以今年夏天，我开始了自由技术写作 [https://www.karllhughes.com/writing/] 。很快我便意识到，技术写作完全可以作为程序员转型后的职业发展道路之一，而在遇到第一个客户时我甚至还没有意识到这一点。 程序员还能做什么工作？ “除了开发软件外，程序员还能做什么工作？” 意识到技术写作是其中一个选择后，我开始思考 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/alternative-career-paths/</link>
                <guid isPermaLink="false">5f7c48d2027c3105323f59aa</guid>
                
                    <category>
                        <![CDATA[ 职业发展 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 产品经理 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 开发者关系 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miaomiao Ma ]]>
                </dc:creator>
                <pubDate>Tue, 06 Oct 2020 10:47:03 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2020/10/Alternate-Career-Pathways.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>过去 5 年中，我在芝加哥的一些编程训练营做过很多次分享。</p><p>听到的问题大多千篇一律：<a href="https://www.freecodecamp.org/news/what-programming-language-should-i-learn-first-19a33b0a467d/">接下来我该学什么语言呢？</a><a href="https://www.freecodecamp.org/news/interviewing-prep-tips-and-tricks/">如何准备技术面试？</a>你们公司招人吗？诸如此类。</p><p>但有一个问题直击我的灵魂深处：如果我不想再当程序员了，该怎么办？</p><p>关于这个问题我后来思考了很久。我带产品和技术团队将近十年了，我意识到自己遇到了新的挑战。所以今年夏天，我开始了<a href="https://www.karllhughes.com/writing/" rel="nofollow">自由技术写作</a>。很快我便意识到，技术写作完全可以作为程序员转型后的职业发展道路之一，而在遇到第一个客户时我甚至还没有意识到这一点。</p><h2 id="-">程序员还能做什么工作？</h2><p>“除了开发软件外，程序员还能做什么工作？”</p><p>意识到技术写作是其中一个选择后，我开始思考有无其他选择。选项出乎意料地多。</p><p>这篇文章会历数程序员转型后的职业发展路径，尤其是对最近的编程训练营毕业生而言。我会介绍每份工作的内容、如何起步，以及长期规划。</p><p>不管你是因为没有找到程序员的工作还是因为不适合软件开发而开始寻找其他工作，这篇指南会帮你根据自己的技能找到一份适合你自己的工作。</p><figure class="kg-card kg-image-card"><img src="https://chinese.freecodecamp.org/news/content/images/2020/10/image-2.png" class="kg-image" alt="image-2" width="2088" height="1069" loading="lazy"></figure><h2 id="--1">面向客户工作</h2><p>程序员会因人际沟通技能而受益颇多，我之前沟通过的一些编程训练营毕业生也不打算整天坐在电脑面前写代码。如果你想做一份能与人更多互动的工作，下面这些选择可能会比较适合你。</p><h3 id="1-">1. 开发者关系、开发者布道师</h3><p>随着越来越多的公司重视与开发者建立关系（这些开发者可能是公司的客户、用户或者布道师），开发者关系领域正在快速发展。</p><p>开发者关系专家（有些公司称他们为布道师、社区经理或“DevRels”）协助公司围绕软件产品建立社区。</p><p>他们在技术公司中的日常工作是创建演示应用程序、写博客、在会议上演讲，和运营社交媒体账号。许多著名的技术公司（如脸书、谷歌、亚马逊等）都有开发者关系专家团队。</p><p>如果你对这个领域感兴趣，可以看看 <a href="https://www.marythengvall.com/">Mary Thengvall</a> 和 <a href="https://medium.com/@aspleenic">PJ Hagerty</a> 正在做的事情。他们是我在开发者关系领域最喜欢的两位，他们一起推出了 <a href="https://www.communitypulse.io/">Community Pulse 播客</a>。</p><h3 id="2-">2. 开发者营销</h3><p>开发者营销与开发者关系有些重叠，但开发者营销更聚焦外部。</p><p>开发者都不喜欢传统的销售方式，所以面向开发者的营销并不好做，很多在其他市场可行的更加激进的营销策略在这个市场行不通。具有技术背景的人可以顺畅地理解开发者们的思维方式，较传统营销人员更具有优势。</p><p><a href="https://www.slashdata.co/blog/">SlashData</a> 发表了很多关于开发者营销的内容，比如 <a href="https://www.slashdata.co/blog/developer-marketing-guide-selling-softly">2018 年的时候出版了一本相关的书《Developer Marketing Guide: Selling It Softly》</a>。如果你想从事这一领域，学学 SEO、社交媒体、内容营销、影响力营销等在线营销内容。你可以运营自己的博客，练习这些技能，然后再应用到实际工作中。</p><h3 id="3-">3. 销售工程师</h3><p>很多工程师一看到带有“销售”字眼的工作就不感兴趣，但这是因为我们常遇见的销售人员都不合格。</p><p>事实是<a href="https://www.theladders.com/career-advice/everyone-is-in-sales-and-thats-a-good-thing">每一个人都或多或少地会做销售</a>。面试找工作、给工程团队介绍新框架等都属于销售。销售的意思是用合适的解决办法匹配消费者的需求。</p><p>销售工程师具有技术背景，颇有优势。这对于不想整天写代码、但懂软件工程的开发者来说是一个绝佳的选择。</p><p>此外，销售不需要任何专业资格，这是它的另一个好处。你可以<a href="https://blog.hubspot.com/sales/how-to-become-sales-engineer">在 Hubspot 搜索一些入门技能和资源</a>。随着越来越多的公司开始为工程师开发软件工具、提供服务，未来十年，市场对销售工程师的需求将可能日益增多。</p><h3 id="4-">4. 技术招聘人员</h3><p>另一种不受软件工程师待见的职业是技术招聘。</p><p>我遇见过一些诚实的、真诚的技术招聘人员（如我们芝加哥的 <a href="http://www.taylordorsett.com/">Taylor Dorsett</a> 和 <a href="https://www.linkedin.com/in/humanrecruiter/">Matt Hoffman</a>），但我也遇见过一些糟糕的、什么都不懂的招聘人员，只会乱翻简历达成业绩。</p><p>若是有软件开发背景，那你就较很多其他技术招聘人员更具同理心和可信度。正如销售，技术招聘要求招聘人员更加外向、关注人际关系，但技术招聘并不需要专业资格或课程。</p><p>但不幸的是，很多技术招聘入门级工作需求都是一些比较差的公司发布的，所以，在申请之前，务必查看该公司在 <a href="https://www.glassdoor.com/Salaries/technical-recruiter-salary-SRCH_KO0,19.htm">Glassdoor上面的评价</a>。</p><h2 id="--2">产品工作</h2><p>如果你想在产品团队，但不确定自己想不想成为一名程序员，你可以试试其他工作。这些工作跟程序员联系紧密，因此你的编程知识会给你提供帮助，但产品工作也需要其他的专业知识。</p><h3 id="5-qa-">5. 质量保证工程师（QA）或测试工程师</h3><p><a href="https://www.360logica.com/blog/qa-engineer-test-engineer-whats-pick/">质量保证和测试工程师的区别较小</a>，在软件正式使用之前，他们都需要做测试工作。</p><p>如果你关注细节，想要提出一些创造性方式来自动化重复工作，这可能是一个不错的选择。除去一些手动测试工作外，可能也需要写一些代码。</p><p>小型公司会让程序员彼此互相检查代码，大型公司才有专门的测试和质量保证岗位。公司做测试的方式不一，所以一定要问清楚公司使用什么工具做测试，测试自动化达到何种程度，你所应征岗位的手动和自动测试占比各为多少。</p><h3 id="6-">6. 商业分析师</h3><p>产品开发生命周期的另一端是商业分析师，这是商业和技术团队之间的桥梁，可以保证各方理解需求、限制和时间点。在团队结构中，商业分析师还助测试和质量保证一臂之力，所以他们还要具备广泛的产品知识。</p><p>如果你有商业、产品开发，或者设计、编程的背景知识，那么你就具备了商业分析师的基础入门资格。如果没有的话，我建议你学习一些在线课程，了解一下商业分析师及其工作内容。</p><h3 id="7-">7. 项目经理</h3><p>正如商业分析师，项目经理必须理解产品的商业需求和技术限制。</p><p>但商业分析师和项目经理之间的关键差异在于，项目经理需要深入单个项目。项目经理需要为项目团队分配任务和资源，负责追踪项目进度。</p><p>小型公司可能会将商业分析师、项目经理、敏捷专家、产品经理的工作结合在一起，但大型公司可能会具体细分岗位职责。</p><p>一名项目经理要想成功，离不开卓越的组织能力、业务理解和人际关系处理能力。这份工作需要你管理预期，激励可能比你资深或有经验的前辈，所以你得快速建立信任。这份工作需要考虑多个方面，很适合不想再写代码的分析、技术人才。</p><h3 id="8-">8. 敏捷专家</h3><p>在敏捷开发团队中，<a href="https://www.scrum.org/resources/what-is-a-scrum-master">敏捷专家</a>帮助确保每一个人了解并完全相信敏捷理论、最佳实践和规则。</p><p>敏捷专家很像项目经理，但特别强调与其他团队的配合，尤其是在大公司中，分工比较细，就更强调这一点。</p><p>作为一名敏捷专家，管理预期和局限性的能力十分重要，同时也需要了解敏捷最佳实践，因此我建议大家看一些这方面的课程或者书籍。敏捷在各种规模的组织中均有广泛应用，所以在未来十年这个职业的需求可能会继续增长。</p><h3 id="9-">9. 产品经理</h3><figure class="kg-card kg-image-card"><img src="https://chinese.freecodecamp.org/news/content/images/2020/10/image-3.png" class="kg-image" alt="image-3" width="853" height="463" loading="lazy"></figure><p>2019 年，我花了大量时间学习产品管理，以改善我们的产品团队的<a href="https://www.karllhughes.com/posts/product-management-process">交付流程</a>。</p><p>产品经理要全面审视公司的产品，确保这些产品是消费者想要的、有商业意义的并且可以被设计出来。站在这种角度思考的能力并不多见，所以如果你有这种能力，还有些技术背景，你也可以成为一名产品经理。</p><p>入门级产品经理可以从产品的小模块或在某些组织中担任产品经理起步。这可以让你在负责管理自己产品之前明白产品开发，帮助你和所有的相关人员建立关系。</p><h3 id="10-">10. 设计师</h3><p>如果你有设计或艺术背景，再有一些编程基础，那么你可以成为一名优秀的 UI 或 UX 设计师。这些能力可以让你更有效率地和工程师配合设计出互动性的 HTML 或 CSS，而不仅仅是静态图像文件。</p><p>如果你没有太多设计经验，找一个课程学习一下，开始打造作品集。哪怕你没有学历，但只要你有知识和技能，很多公司也愿意聘用你。我经常看到 <a href="https://dribbble.com/">Dribbble</a> 这个作品集平台，当然你也可以使用其他平台。</p><h3 id="11-">11. 零代码或低代码开发者</h3><p>过去几年<a href="https://medium.com/@rrhoover/the-rise-of-no-code-e733d7c0944d">零代码和低代码工具</a>爆火，给没有开发团队但想要快速开发软件的公司带来了机会。使用这些工具，你无需花费数周，在数小时内便可创建一款移动或网页应用。这些工具每年都会进步，所以越来越多的公司正在接受零代码应用。</p><p>可以在 <a href="https://www.makerpad.co/jobs">Makerpad</a> 和 <a href="https://nocodejobs.co/" rel="nofollow">No Code Jobs</a> 这两个平台找相关工作。因为这是一个新兴领域，需要的技能和所给报酬变化范围较广，但编写代码能力无疑是一项非常重要的技能。</p><h2 id="--3">支持工作</h2><p>很多软件工程师没有意识到幕后有很多员工负责维护服务器、网站和运营工作顺利开展。这其中就有些工作要求员工会写自动化脚本或对服务器管理有较深的理解。如果你想在产品开发之外寻找跟技术相关的工作，这类工作也很适合。</p><h3 id="12-devops-">12. 系统管理工程师或 <strong>DevOps </strong>工程师</h3><p>大型软件公司每年都有成百甚至上千的服务器需要修复、升级、轮换。尽管当下广泛应用云计算，上述工作都可以通过 <a href="https://www.terraform.io/">Terraform</a> 和 <a href="https://kubernetes.io/">Kubernetes</a> 之类的软件而不是人工操作来实现，但是相关招聘需求还是很多的。</p><p>一直以来，工程师团队需要系统管理员<a href="https://devops.stackexchange.com/questions/157/what-is-the-difference-between-sysadmin-and-devops-engineer">负责维护和管理服务器</a>。随着组织扩张并逐渐转用云主机，很多团队开始使用“DevOps 工程师”这一称呼，以反映这些工作的自动化程度越来越高。从实践来看，两者的工作内容有很多重叠之处。</p><p>如果想要做这类工作，你需要对操作系统、托管平台、自动化工具、Bash 脚本编程和系统架构有基本了解。在这一领域<a href="https://www.reddit.com/r/devops/comments/hne5q0/getting_into_devops_as_a_beginner_is_tricky_my_50/">找一份入门级工作有些难</a>，因为其对技术知识要求广泛。但如果你喜欢解决问题，不想受面向消费者产品的 UI 和 UX 要求束缚，这类工作也值得尝试。</p><h3 id="13-">13. 数据库管理员</h3><p>有些公司将数据库管理员与系统管理员混为一谈，但其实数据库管理员是一个不同的职务。</p><p>数据库管理员负责低层次数据存储系统的安全、配置、扩展和优化。你需要懂得 SQL 和 NoSQL 数据库、安全最佳实践和一些基础脚本知识，但无需整天写代码，处理的都是类似修复索引和缓存的小优化问题。</p><p>如果你是软件开发的新手，那就开始尽量学习有关数据库的知识吧。你需要知道哪个数据库适合哪个应用，以及如何大规模优化这些数据库。实践起来可能会有些难度。如果你想要找一些工作中使用的大数据集，可以去 <a href="https://www.kaggle.com/datasets" rel="nofollow">Kaggle</a> 看看。</p><h3 id="14-">14. 网站可靠性工程师</h3><p>网站可靠性工程师负责响应并修复产品运行中出现的重要问题，也就是说你需要随时处于待命状态，工作时间会比较特殊。但乐观一点来看，网站工程师将会成为解决各种异常问题、创建自动警示和读服务器日志的一把好手。</p><p>由于网站可靠性工程师总是需要人处于随时待命状态，有经验的软件工程师不太可能长时间地一直呆在这个岗位。然而，从另一个角度看，如果你正在寻找你的第一份软件开发工作，但又不知如何是好，网站可靠性工程师可能是一个不错的入门选择。我认识的两个训练营的毕业生在正式从事软件开发工作之前，就是从网站可靠性工程师过渡的。或许在这份工作中，你会发现自己喜欢快节奏解决问题所带来的挑战和激情。</p><h3 id="15-">15. 技术支持或客户支持</h3><p>一些工程师害怕与客户交流，但也有些工程师认为帮助人们解决问题非常鼓舞人心。在需要技术人员解答问题和提出修复建议的软件公司，如果你有写代码的经验，那么你就是客户支持岗位的理想人选。</p><p>然而，不好的一面在于，在支持岗位工作，意味着不得不跟处在最糟状态下的用户打交道。如果用户不满意或者感到沮丧，他们很可能不会心平气和地与技术支持团队沟通。所以这份工作需要你耐心十足，且厚脸皮。</p><h2 id="--4">教学和写作工作</h2><p>我一直都对教学怀有热忱，所以如果工程师角色能够让我从事教学相关工作，会对我有莫大的吸引力。如果你喜欢将复杂问题掰开揉碎分析，并把这些展示给其他工程师，那你可以考虑一下下面的几种职业选择。</p><h3 id="16-">16. 技术写作者</h3><p>读大学时，我的第三份实习是在一家大公司担任技术写作者，工作内容就是纯粹写作。我很喜欢，因为每天都能学到新东西。</p><p>自那以后，我发现技术写作不仅仅意味着文档写作，还包括<a href="https://www.karllhughes.com/posts/start-freelance-blogging" rel="nofollow">技术博客</a>、文案写作、内部或外部文档、示例程序和指导手册。对写作者而言，技术写作收入可观，值得考虑。</p><p>如果你决定走这条路线，那么你需要擅长写作（很明显）、组织复杂观点和学习新东西。自我编辑能力越强，产出的作品越有价值，所以要投资那些能帮你变得更好、更高效的工具。</p><p>刚开始写作时，你可以给<a href="https://github.com/malgamves/CommunityWriterPrograms">一些有偿社区写作项目</a>投稿，在你建立起人际网络和作品集之后，你可以借助这段经历找到一份全职工作。</p><h3 id="17-">17. 老师</h3><p>有多种方式可以从软件开发中跳出来成为一名老师，比如去训练营任教、去大学或高中任教，可以加入类似 <a href="http://egghead.io/" rel="nofollow">egghead.io</a> 之类的平台，或者可以在 Teachable 或 Educative 创办自己的课程网站。</p><p>无论在何种情况下，老师们都需要快速学习新知识，并需要将知识转变成易于学生理解的形式。想要成为一名成功的老师，你需要考虑学生的水平，并与学生建立信任。老师的收入可能比不上软件开发，但这份工作带来的成就感十足。</p><h3 id="18-">18. 培训师</h3><p>企业培训是教学的另一种形式，也值得考虑。在大公司里，培训师可能是独立的咨询师或者员工，会前往客户的办公地点提供专门的软件实践培训。</p><p>一般来讲，培训师具有丰富的技术知识，但也有些培训师是具备一定的技术知识，然后沟通能力比较出色。企业培训的收入比教学要好，但企业培训的销售导向也会更强。培训师经常在大会上发言，办社区工作坊，或参加各种沙龙。</p><p>如果你喜欢站在舞台上，展示各种技术概念，那么这份工作也是理想的选择。</p><h2 id="--5">分析工作</h2><p>技术公司的大量工作都对分析技能做了要求，有些领域需要专门的教育背景，如果你想从软件开发转行，这些分析岗位也是备选项。分析工作与专注产品的工程师工作的节奏非常不同，类似上面提及的支持工作，分析工作需要与业务的其他部门互动对接。</p><h3 id="19-">19. 数据科学家或工程师</h3><p>这两种职务（一些公司会将这两者混为一谈）都涉及到使用大量数据集帮助业务部门或他们的客户做出更好的决策。</p><p>数据工程师通常负责数据获取和组织管道，数据科学家则负责设计实验和算法，以使得数据形成有用结果。<a href="https://en.wikipedia.org/wiki/Data_science" rel="nofollow">数据科学（人工智能、机器学习等）是一个大的领域</a>，扎根于数学、软件工程和统计学。</p><p>有许多课程、训练营和大学学位与数据科学和工程相关，但如果你数学背景强大，你也有能力自学一些这方面的基础课程。如果你没有数学背景，可以首先考虑进修数值分析、矩阵代数和统计学。</p><p>学习这些知识要花大量时间，当前也对数据科学家有大量需求，因此这份工作收入不菲，也不太可能短时间内就消失。</p><h3 id="20-">20. 安全分析师</h3><p>从事信息安全工作的人一般都很低调，除非出了什么岔子。虽然每个开发者应该都能觉察到安全漏洞和风险，但安全分析师就是专门雇来发现、记录安全问题并提出修复方案的。</p><p>有些安全分析师是独立的咨询师，但在大一点的公司，可能会有一个内部安全分析团队。这个岗位很有趣，因为它需要结合技术、沟通、业务和风险评估技能。</p><p><a href="https://www.csoonline.com/article/3153707/top-cybersecurity-facts-figures-and-statistics.html">安全岗位比较难招聘到合适的人</a>，所以这个工作的稳定性比较高。信息安全是一个很广阔的领域，如果你对这个领域感兴趣，不妨<a href="https://medium.com/bugbountywriteup/jobs-in-information-security-infosec-93a5efc12ca2">看看这些你可以选择的路径</a>。</p><h3 id="21-">21. 研发</h3><p>对有软件开发技能的人而言，在研发部门工作是一份不可多得的经历。谷歌和亚马逊这类大公司把一部分利润点放在了高风险，但同时也具有高回报潜力的实验上，由研发团队负责实施。这些跨学科团队可能包括软件开发人员、数据科学家、商业分析师和项目经理。</p><p>加入一个好的研发团队很难，这些工作岗位竞争力十足，对知识的专业性要求很高，而这基本不可能在编程训练营中习得。也就是说，一些公司会雇佣<a href="https://www.simplilearn.com/roles-of-ethical-hacker-article">道德黑客</a>、创始人或<a href="https://levelup.gitconnected.com/how-to-become-a-polyglot-programmer-fff48562e708?gi=7e625563d43e">通晓多种语言的人</a>来整顿团队，提出一些创造性思维。</p><h2 id="--6">独立和灵活性</h2><p>尽管在技术领域工作，我们可以远程办公，有时也有<a href="https://blog.hubspot.com/marketing/sabbatical">学术休假</a>，但你可能在生活中想要更多的灵活性。如果你有驱动力，想要自己创业，那你可能每周只工作 4 小时，每年出差 6 个月，或者花费一半的工作时间在开源项目上。这并不容易。但作为一名软件开发人员，相比大多数人，你已经具有很大的优势。</p><h3 id="22-">22. 自由职业者或咨询师</h3><p>想要获得更多自由，其中一个方法是辞掉朝九晚五的工作成为一名自由职业者，这样你便可以自己雇佣自己，为一位或多位按时支付薪酬的客户写代码。公司通常也会雇佣自由职业者来负责具体的短期项目、清理技术负债或顶替休假的正式员工。</p><p>咨询师是高级的自由职业者，可以为客户解决具体问题。他们可能写代码，但客户更看重的是他们的专业知识或特殊背景。自由职业者与咨询师之间的界限非常模糊，所以不要在两者之间过于纠结。</p><p>自由职业者或咨询师起步时期最为艰难。如果你没有强大的人脉积累，你很可能需要依赖 <a href="https://www.upwork.com/" rel="nofollow">Upwork</a> 或 <a href="http://toptal.com/" rel="nofollow">Toptal</a> 等平台来寻找客户。这些平台会从你的收入中收取一笔不小的佣金，而且你要与平台上世界各地的自由职业者直接竞争。</p><p>在你不断积累起名声、积攒起客户后，就可以通过转介绍获得更多客户。转介绍非常有效，因为客户与你一开始就建立起了信任关系，而不再是互联网的匿名陌生状态。如果你的自由职业或咨询做得非常不错，你可以提高收费，在接手项目之间也可以适时休息。</p><h3 id="23-">23. 创业公司创始人</h3><p>互联网上有着各种软件工程师创业的故事（<a href="https://medium.com/@a13n/software-engineer-to-saas-founder-c16154013e12" rel="nofollow">1</a>, <a href="https://medium.com/@dvassallo/only-intrinsic-motivation-lasts-92c0497cf97c" rel="nofollow">2</a>, <a href="https://www.indiehackers.com/podcast/096-ben-orenstein-of-tuple" rel="nofollow">3</a>），这可能给你留下了“创业很简单”或“创业是个好主意”的印象。</p><p>但真相是，创业有成有败。</p><p>创业公司获得收入要花很长时间，所以很有可能在创业的前数个月甚至数年你都没有工资收入。换句话说，如果你想成立自己的软件公司，发展是个未知数。</p><p>你也可能在自己的工作时间之外成立一家公司，但是这很难，也可能<a href="https://www.entrepreneur.com/article/251931">有些法律风险</a>。如果你能找到一两个合伙人一起承担创业贷款，那成功的几率会高一点。</p><h2 id="--7">最后的一些想法</h2><p>软件工程是一个充满乐趣的领域，但并非所有人都适合从事这方面的工作。即便你离开了，决定去做一些别的事情，你在这个领域积累的知识也并不会浪费。</p><p>许多训练营毕业生惧怕在软件开发领域之外找工作，但我鼓励你们沿着自己的路径去发展。平衡好实用性（赚的钱要保证自己生活）和自身兴趣，找到一条并不像是“工作”的职业发展道路还是很有希望的。</p><p>我想听到你们的想法。如果你走过的路不同寻常，或者你转行了，我都希望能在<a href="https://twitter.com/karllhughes">推特</a>上了解你的所思所想。</p><p>原文：<a href="https://www.freecodecamp.org/news/alternative-career-paths/">23 Alternative Career Paths that Software Developers Can Grow Into</a>，作者：Karl Hughes</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 如何提高编程能力？这里有项目开发创意 ]]>
                </title>
                <description>
                    <![CDATA[ 你是否曾经想开发一些东西但苦于无从下手？就像文学创作者会遭遇写作瓶颈，开发人员也不例外。 我跟我的朋友吉姆 Jim [https://twitter.com/jd_medlock]一起，创作了一个collection of application ideas [https://github.com/florinpop17/app-ideas]【应用创意想法集锦】，旨在一劳永逸地解决这个问题。 这些应用可以：  * 很好地提升你的编程技能  * 很好地接触新技术  * 成为你简历里打动下任老板或客户的经历  * 成为辅导材料（文章或者视频形式）里面的例子  * 很快完成，新性能扩展也十分容易 这不仅仅是一个项目的简单罗列。这份集锦详细地描述了每个项目，足够你从零开始。 每份项目规格包含：  1. 一个清晰描述对象  2. 需执行的用户需求清单（这些用户需求更像是一个行为准则而非必做事项。如果你有需要的话也可以根据自己的需要添加）  3. 追加选项清单。这个不仅可以改良基础项目，同时你的编程技巧也会有所提高  4. 所有能帮你发现完成项目所需物料的资源和链接 项目综述 根据完 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/here-are-some-app-ideas-you-can-build-to-level-up-your-coding-skills/</link>
                <guid isPermaLink="false">5f5f301ccd07b005bfb5b234</guid>
                
                    <category>
                        <![CDATA[ 项目 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 编程学习 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 自我提升 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miaomiao Ma ]]>
                </dc:creator>
                <pubDate>Mon, 14 Sep 2020 07:20:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2020/09/0_v3qXmKe1LTiiW_3H.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>你是否曾经想开发一些东西但苦于无从下手？就像文学创作者会遭遇写作瓶颈，开发人员也不例外。</p><p>我跟我的朋友吉姆 <a href="https://twitter.com/jd_medlock" rel="nofollow">Jim</a>一起，创作了一个<a href="https://github.com/florinpop17/app-ideas">collection of application ideas</a>【应用创意想法集锦】，旨在一劳永逸地解决这个问题。</p><p>这些应用可以：</p><ul><li>很好地提升你的编程技能</li><li>很好地接触新技术</li><li>成为你简历里打动下任老板或客户的经历</li><li>成为辅导材料（文章或者视频形式）里面的例子</li><li>很快完成，新性能扩展也十分容易</li></ul><p>这不仅仅是一个项目的简单罗列。这份集锦详细地描述了每个项目，足够你从零开始。</p><p>每份项目规格包含：</p><ol><li>一个清晰描述对象</li><li>需执行的用户需求清单（这些用户需求更像是一个行为准则而非必做事项。如果你有需要的话也可以根据自己的需要添加）</li><li>追加选项清单。这个不仅可以改良基础项目，同时你的编程技巧也会有所提高</li><li>所有能帮你发现完成项目所需物料的资源和链接</li></ol><h3 id="-">项目综述</h3><p>根据完成项目所需的知识储备和经验，所有的项目分为三个层级：</p><ol><li><strong>初级</strong> 针对的是刚刚起步的开发人员，特别是专注于开发面向用户应用的人员。</li><li><strong>中级</strong> 针对的是已经有学习和开发经验的老学员。他们在案例法过程中对用户界面和用户体验较为熟悉，会使用开发工具，会开发使用应用编程接口服务的应用。</li><li><strong>高级</strong> 针对的开发人员包含初级和中级提到的所有特点。他们还会额外学习高级技术，例如执行后端应用和数据库服务。</li></ol><p>接下来，每个层级中都会包含五个项目，总共十五个项目。但在我写文章时，在<a href="https://github.com/florinpop17/app-ideas">这个 Github 仓库</a>中共有三十多个项目。一定要确保你把这些项目都烂熟于心，因为未来我们计划增加更多的项目，非常欢迎你出一份力！（更多信息请关注下文的“贡献”部分）</p><h3 id="1-">1. 笔记应用</h3><p><strong>层级:</strong> 1-初级</p><p><strong>任务描述</strong>: 可以按照需求创建和存储笔记</p><h4 id="--1">用户需求</h4><ul><li>用户可以创建笔记</li><li>用户可以编辑笔记</li><li>用户可以删除笔记</li><li>浏览页面关闭时笔记可以自动存储；用户返回页面时，数据可以自行修复。</li></ul><h4 id="--2">追加选项</h4><ul><li>用户可以以Markdown格式创建和编辑笔记，存储以后内容会转换为HTML格式。</li><li>用户可以看见创建笔记的日期</li></ul><h4 id="--3">可以提供帮助的链接和资源</h4><ul><li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage" rel="nofollow">localStorage</a></li><li><a href="https://www.markdownguide.org/basic-syntax/" rel="nofollow">Markdown Guide</a></li><li><a href="https://github.com/markedjs/marked">Marked — A markdown parser</a></li></ul><h3 id="--4">项目示例</h3><figure class="kg-card kg-embed-card"><iframe id="cp_embed_gbyygq" src="https://codepen.io/nickmoreton/embed/preview/gbyygq?height=300&amp;slug-hash=gbyygq&amp;default-tabs=css,result&amp;host=https://codepen.io" title="AngularJS Markdown Notes App" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;" loading="lazy"></iframe></figure><h3 id="2-">2. 圣诞彩灯秀</h3><p><strong>层级:</strong> 1-初级</p><p><strong>任务描述</strong> ：圣诞彩灯秀应用需要利用你的编程开发能力来创造一个光彩炫目的灯光秀。你的任务是连续画出七个彩色光圈，然后根据时间变化每个光圈的亮度有所变化。一个光圈变亮时，前一个变亮的光圈恢复正常亮度。</p><p>在这个应用中，灯光就像涟漪一样一层一层荡漾开，好比圣诞节的灯光秀。</p><h4 id="--5">用户需求</h4><ul><li>用户可以通过按钮控制灯光秀</li><li>用户可以控制灯光秀亮度变化的时间间隔</li></ul><h4 id="--6">追加选项</h4><ul><li>用户可以选择每个光圈的颜色</li><li>用户可以控制光圈亮度</li><li>用户可以改变每个光圈大小</li><li>用户可以在1-7范围内设定灯光秀中的光圈个数</li></ul><h4 id="--7">可以提供帮助的链接资源</h4><ul><li><a href="https://previews.123rf.com/images/whiterabbit/whiterabbit1003/whiterabbit100300020/6582600-seven-color-balls-red-orange-yellow-green-cyan-blue-and-magenta-in-a-row-on-a-white-background.jpg" rel="nofollow">Sample Image</a></li><li><a href="https://cdn-shop.adafruit.com/970x728/1487-02.jpg" rel="nofollow">Adafruit LED Matrix</a></li></ul><h3 id="--8">项目实例</h3><figure class="kg-card kg-embed-card"><iframe id="cp_embed_QjvEex" src="https://codepen.io/tobyj/embed/preview/QjvEex?height=300&amp;slug-hash=QjvEex&amp;default-tabs=css,result&amp;host=https://codepen.io" title="Pure CSS Christmas Lights" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;" loading="lazy"></iframe></figure><h3 id="3-">3. 图片翻转</h3><p><strong>层级:</strong> 1-初级</p><p><strong>任务描述</strong>: 因为大量应用依靠图片来呈现更丰富的用户界面、提供更棒的用户体验，所以对于开发人员来说，理解图片操作的基础非常重要。</p><p>图片翻转应用探索图片操作的一个方向-图片旋转。应用上显示一个方框，一张图片以2*2矩阵形式呈现。用户通过控制图片周围上下左右四个箭头来垂直或水平翻转图片。</p><p>必须使用原生HTML,CSS和Javascript语言来执行此应用。图像包和图像库均不允许使用。</p><h4 id="--9">用户需求</h4><ul><li>用户可以看见一个窗口，里面的单个图片一直以2*2矩阵分布</li><li>通过点击图片旁边的上下左右按钮，用户可以任意垂直或水平翻转任意图片</li></ul><h4 id="--10">追加选项</h4><ul><li>通过统一资源定位器（URL）查找别的图片，用户可以在输入栏更改默认图片</li><li>用户可以点击输入栏旁边的“秀”按钮，展示新图片</li><li>如果在统一资源定位器（URL）中没有找到新图片，用户可以看到错误信息提醒（error message）</li></ul><h4 id="--11">可以提供帮助的链接资源</h4><ul><li><a href="https://www.w3schools.com/howto/howto_css_flip_image.asp" rel="nofollow">How to Flip an Image</a></li><li><a href="https://davidwalsh.name/css-flip" rel="nofollow">Create a CSS Flipping Animation</a></li></ul><h3 id="--12">项目示例</h3><figure class="kg-card kg-embed-card"><iframe id="cp_embed_gvqYQv" src="https://codepen.io/seyedi/embed/preview/gvqYQv?height=300&amp;slug-hash=gvqYQv&amp;default-tabs=html,result&amp;host=https://codepen.io" title="Image Effects" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;" loading="lazy"></iframe></figure><h3 id="4-">4. 问答应用</h3><p><strong>层级:</strong> 1-初级</p><p><strong>任务描述</strong>: 通过在问答应用上回答问题，来训练和测试你的知识存储。</p><p>作为一名开发人员，你可以开发一个能够测试其他开发人员编程知识的问答应用，诸如HTML, CSS, Javascript, Python, PHP知识等等。</p><h4 id="--13">用户需求</h4><ul><li>用点击按钮开始答题</li><li>用户面对的每个问题有四个答案选项</li><li>用户选中一道题的答案后，自动进行到下一题，直到整个问答结束</li><li>问答结束时，用户可以看到以下数据：</li></ul><ol><li>完成问答所耗时间</li><li>答对的问题个数</li><li>是否通过问答</li></ol><h4 id="--14">追加选项</h4><ul><li>用户可以在社交媒体分享问答结果</li><li>在应用上增加多份问答，用户可以决定做哪个问答</li><li>用户可以创建账户，存储所有得分结果。用户可以多次进行同一个问答</li></ul><h4 id="--15">可以提供帮助的链接资源</h4><ul><li><a href="https://opentdb.com/api_config.php" rel="nofollow">Open Trivia Database</a></li></ul><h3 id="--16">项目示例</h3><figure class="kg-card kg-embed-card"><iframe id="cp_embed_qqYNgW" src="https://codepen.io/FlorinPop17/embed/preview/qqYNgW?height=300&amp;slug-hash=qqYNgW&amp;default-tabs=css,result&amp;host=https://codepen.io" title="Quiz app interface" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;" loading="lazy"></iframe></figure><p><a href="http://tranquil-beyond-43849.herokuapp.com/" rel="nofollow">Quiz app built with React</a> （应用已在 Heroku 上线，可下载）</p><h3 id="5-">5. 罗马-十进制数字转换器</h3><p><strong>层级:</strong> 1-初级</p><p><strong>任务描述</strong>: 罗马数字源于古罗马。直到中世纪后期，罗马数字系统一直是数字书写的主流，至今仍在使用。罗马数字包含七个符号，每个都有确定的整数值。</p><p>下表为罗马符号-整数值对应：</p><ul><li>I — 1</li><li>V — 5</li><li>X — 10</li><li>L — 50</li><li>C — 100</li><li>D — 500</li><li>M — 1000</li></ul><h4 id="--17">用户需求</h4><ul><li>用户可以在输入栏里输入一个罗马数字</li><li>点击按钮，用户可以在输出栏看见之前输入的罗马数字对应的十进制数字</li><li>如果输入罗马符号错误，用户可以看见错误提示</li></ul><h4 id="--18">追加选项</h4><ul><li>用户可以看见转换过程自动完成</li><li>用户可以完成十进制-罗马数字的逆过程转换</li></ul><h4 id="--19">可提供帮助的链接资源</h4><ul><li><a href="https://en.wikipedia.org/wiki/Roman_numerals" rel="nofollow">An explanation of Roman Numbers</a></li></ul><h4 id="--20">项目示例</h4><p><a href="https://www.calculatorsoup.com/calculators/conversions/roman-numeral-converter.php" rel="nofollow">Roman Number Converter</a></p><h3 id="6-">6. 寻书应用</h3><p><strong>层级:</strong> 2-中级</p><p><strong>任务描述</strong>: 创建一个用户可以搜寻书的应用。用户在输入相关书名、作者等信息后，网页上会排列出现所有相关书籍。</p><h4 id="--21">用户需求</h4><ul><li>用户可以在输入栏输入要查询的信息</li><li>用户可以提交查询信息。这就叫做应用编程接口（API），返回结果是与所有输入信息（例如名称，作者，出版日期，图像等）相关联的书籍</li><li>用户可以在页面上看到搜索出来的书籍清单</li></ul><h4 id="--22">追加选项</h4><ul><li>搜索清单上每个书籍条目要增加一个用户可以直达的外部站点链接，以便得到更多关于书的信息。</li><li>执行一个响应设计</li><li>增加预载动画</li></ul><h4 id="--23">可提供帮助的链接资源</h4><p><a href="https://developers.google.com/books/docs/overview" rel="nofollow">Google Books API</a></p><h4 id="--24">项目示例</h4><figure class="kg-card kg-embed-card"><iframe id="cp_embed_wpQBKV" src="https://codepen.io/chasebank/embed/preview/wpQBKV?height=300&amp;slug-hash=wpQBKV&amp;default-tabs=css,result&amp;host=https://codepen.io" title="Vue, Axios and Google Books" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;" loading="lazy"></iframe></figure><p><a href="https://fethica.github.io/BookSearch-React/" rel="nofollow">BookSearch-React</a></p><h3 id="7-">7. 卡片记忆游戏</h3><p><strong>层级:</strong> 2-中级</p><p><strong>任务描述</strong>: 在卡片记忆游戏中，你需要点击一张卡片看是什么图形，然后努力在其余卡片中发现匹配的图形。</p><h4 id="--25">用户需求</h4><ul><li>用户可以看到一个包含有n*n张卡片的方格（n是整数）。所有的卡片一开始都是图形面朝下的状态（隐藏状态）</li><li>用户点击按钮开始游戏，同时计时器开始计时</li><li>用户可以点击任意一张卡片查看图形，这张卡片就处于可见状态，一直持续到用户点击第二张卡片</li></ul><p>用户点击第二张卡片后：</p><ul><li>如果两张卡片图形匹配，这两张卡片就会消失（或是隐藏或是移除，也可以让他俩处于可见状态）</li><li>如果跟第一张卡片图形不匹配，两张卡片就会恢复初始 隐藏状态</li><li>所有匹配结束以后，用户可以看见对话框显示“祝贺”信息，同时也会显示完成游戏所耗费的时间</li></ul><h4 id="--26">追加选项</h4><ul><li>用户可以自己选择游戏难度等级（易中难）。难度增加意味着：完成游戏的规定时间缩短或者图片个数增加</li><li>用户可以看见游戏数据（不是输赢次数，而是每个难度所对应的最好成绩）</li></ul><h4 id="--27">可提供帮助的链接资源</h4><ul><li><a href="https://en.wikipedia.org/wiki/Concentration_(game)" rel="nofollow">Wikipedia</a></li></ul><h4 id="--28">项目示例</h4><p><a href="https://codepen.io/zerospree/full/bNWbvW" rel="nofollow">Flip — card memory game</a></p><p><a href="https://codepen.io/hexagoncircle/full/OXBJxV" rel="nofollow">SMB3 Memory Card Game</a></p><h3 id="8-markdown-">8. Markdown表格生成器</h3><p><strong>层级:</strong> 2-中级</p><p><strong>任务描述</strong>: 创建一个可以将包含用户数据的常规表格（或者不包含，看用户需求）转换成Markdown形式表格的应用</p><h4 id="--29">用户需求</h4><ul><li>用户可以创建包含有特定行数或列数的HTML表格</li><li>用户可以在HTML表格中的每个单元格插入文本</li><li>用户可以生成包含有HTML表格数据的Markdown形式表格</li><li>用户可以预览Markdown形式表格</li></ul><h4 id="--30">追加选项</h4><ul><li>用户可以一键复制Markdown形式表格到剪切板</li><li>用户可以在特定区域插入行或者列</li><li>用户可以彻底删除某行某列</li><li>用户可以将某个单元格、某列、某行向左、向右或者居中对齐。</li></ul><h4 id="--31">可以提供帮助的链接资源</h4><ul><li><a href="https://www.markdownguide.org/" rel="nofollow">Markdown Guide</a></li><li><a href="https://github.com/markedjs/marked">Marked — A markdown parser</a></li><li><a href="https://www.w3schools.com/howto/howto_js_copy_clipboard.asp" rel="nofollow">How to Copy to Clipboard</a></li></ul><h4 id="--32">项目示例</h4><p><a href="https://www.tablesgenerator.com/markdown_tables" rel="nofollow">Tables Generator / Markdown Tables</a></p><h3 id="9-">9. 弦乐艺术</h3><p><strong>层级:</strong> 2-中级</p><p><strong>任务描述</strong>: 弦乐艺术应用的目的在于让开发人员练习，创建简便动画图表，在动画算法中运用几何知识，创造出富有视觉美感的画面。</p><p>弦乐艺术中，会有一条五彩斑斓的线条平稳地移动，直到它的一端碰到封闭窗口的一边。此时，线条就会因为反弹效应改变方向。</p><p>线条移动时，如果可以保留10-20张线条移动时的图形，便会出现涟漪效应。稍早出现的图形会慢慢消失不见。</p><p>不可以使用动画库。只可以使用Vanilla HTML/CSS/Javascript.</p><h4 id="--33">用户需求</h4><ul><li>在封闭窗口界限内的任意位置，用户以画一条五彩斑斓的线开始</li><li>每隔二十毫秒，在别的位置，按照前一条线条的轨迹复制一条-以端点作为标记，距离前一线条要越来越远</li><li>不论线条的哪个端点碰到封闭窗口的边界，都要改变线条的方向，角度随机改变</li><li>慢慢降低起初画的线条的亮度，确保最近画的10-20线条可见，这样才可以呈现动感或者涟漪效应</li></ul><h4 id="--34">追加选项</h4><ul><li>用户可以设定线条的长度和移动速度</li><li>用户可以设定窗口内的线条数量，所有线条可以按照不同轨迹和速度移动</li></ul><h4 id="--35">可以提供帮助的链接资源</h4><ul><li><a href="https://css-tricks.com/using-multi-step-animations-transitions/" rel="nofollow">Using Multistep Animations &amp; Transitions</a></li><li><a href="https://www.khanacademy.org/computing/computer-programming/programming/animation-basics/a/what-are-animations" rel="nofollow">Animation Basics</a></li></ul><h4 id="--36">项目示例</h4><p>这个项目非常封闭，包含一个小窗口，很单一。<a href="https://codepen.io/dgca/pen/dpxreO" rel="nofollow">Daniel Cortes</a></p><h3 id="10-">10. 计划清单应用</h3><p><strong>层级:</strong> 2-中级</p><p><strong>任务描述</strong>: 经典的计划清单应用：用户可以记下所有的待办事项。</p><h4 id="--37">用户需求</h4><ul><li>用户可以看见输入框，从而输入待办事项</li><li>点击“进入”按钮，用户可以提交待办事项，并且看见其已经进入待办事项清单</li><li>用户可以在待办事项上标注“已完成”</li><li>用户可以通过点击按钮取消待办事项，或者是在待办事项条目上直接操作</li></ul><h4 id="--38">追加选项</h4><ul><li>用户可以编辑待办事项</li><li>用户可以看见所有已完成待办事项的清单</li><li>用户可以看见所有自己创立的待办事项清单</li><li>用户可以看见创立待办事项的日期</li><li>关闭浏览窗口时，待办事项可以自动保存；用户返回页面时，数据可自行恢复</li></ul><h4 id="--39">可提供帮助的链接资源</h4><ul><li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage" rel="nofollow">localStorage</a></li></ul><h4 id="--40">项目示例</h4><figure class="kg-card kg-embed-card"><iframe id="cp_embed_eJIuF" src="https://codepen.io/yesilfasulye/embed/preview/eJIuF?height=300&amp;slug-hash=eJIuF&amp;default-tabs=css,result&amp;host=https://codepen.io" title="To Do List" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;" loading="lazy"></iframe></figure><p>计划清单<a href="http://todomvc.com/examples/react/#/" rel="nofollow">Todo App built with React</a></p><h3 id="11-">11. 战舰游戏引擎</h3><p><strong>层级:</strong> 3-高级</p><p><strong>任务描述</strong>: 战舰游戏引擎采用了回合制棋盘游戏的模式，与所有表示层（presentation layer）分离。它属于一种建筑模式类型，因为其允许无数的应用使用同一种服务，这种模式在很多应用上都十分有用。</p><p>战舰游戏引擎本身是一系列函数调用的结果，而非终端用户直接动作产生。从这个方面讲，使用战舰游戏引擎，与使用应用编程接口或者使用网络浏览器公开的一系列线路是相似的。</p><p>这个挑战不仅要求你开发出战舰游戏引擎，还要求你开发出非常精细的、基于文本的表示层，以检测表示层与引擎互不干涉。因此，用户需求包含两套：战舰游戏引擎一套，基于文本的表示层一套</p><p>战舰游戏引擎需要负责维持整个游戏的状态。</p><h4 id="--41">用户需求</h4><h4 id="--42">战舰游戏引擎</h4><ul><li>召集者调用<code>startGame()</code>函数开始单人游戏。此函数可以创立一个8*8的游戏阵地，阵地上有三艘船，他们的尺寸为：</li></ul><ol><li>驱逐舰：一方格宽，两方格长</li><li>巡洋舰：一方格宽，三方格长</li><li>战舰：一方格宽，四方格长</li></ol><p><code>startGame()</code>函数会随机地把这些战船放在阵地的任意方向，随后给出船的部署情况。</p><ul><li>召集者调用<code>shoot()</code>函数可以袭击阵地上的特定行和列构成的方格坐标。<code>shoot()</code>函数还会显示袭击是否成功，剩余战船数量，战船安置排列，以及更新袭击成功或者失败数据。</li></ul><p>某个方格被设为攻击目标后，会有所提示。 <code>O</code>代表方格被瞄准，但此地没有战船；<code>X</code>代表此地有战船。</p><h4 id="--43">基于文本的表示层</h4><ul><li>通过返回<code>startGame()</code>函数，用户可以看见命中或者未命中数值在阵地上以二维字符展示。</li><li>用户可以受鼓舞进入阵地上特定坐标。</li><li>在袭击之后，用户可以看见命中或未命中数值更新。</li><li>袭击结束后，不论命中与否，用户都可以看见信息提示。</li><li>在击中最后一艘战船时，用户可以看见“祝贺”信息</li><li>每局游戏结束后，用户都可以受鼓舞再来一局。拒绝再来一局则会结束游戏。</li></ul><h4 id="--44">追加选项</h4><h4 id="bge-">BGE战舰游戏引擎</h4><ul><li>召集者可以指定阵地上行与列的具体数值，这也是 <code>startGame()</code>函数的参数。</li><li>召集者可以调用<code>gameStats()</code> 函数，返回到Javascript对象，显示最近游戏数据，比如打了几局，命中数等。</li><li>在调用<code>startGame()</code>函数时，召集者可以指定玩家数量。此函数也可以为每个玩家创立阵地，随机安排战舰数量。</li></ul><p><code>shoot()</code>函数会计算做出特定坐标袭击的玩家数量。函数返回的数据针对某个特定玩家。</p><h4 id="--45">基于文本的表示层</h4><ul><li>用户在目标坐标进入<code>stats</code>相位，可以随时查看最近游戏数据。（注意此项操作需要战舰游戏引擎的<code>gameStats()</code>函数）</li><li>用户可以指定两人游戏模式，每个玩家在同一终端会话均可更改比赛回合。（注意此项操作需要战舰游戏引擎追加选项的相应配合）</li><li>用户在每个回合的输入提示中都可以看到玩家数量。</li><li>用户在每个回合结束时可以看见两个玩家的阵地。</li></ul><h4 id="--46">可以提供帮助的链接资源</h4><ul><li><a href="https://en.wikipedia.org/wiki/Battleship_(game)" rel="nofollow">Battleship Game (Wikipedia)</a></li><li><a href="https://www.hasbro.com/common/instruct/battleship.pdf" rel="nofollow">Battleship Game Rules (Hasbro)</a></li></ul><h4 id="--47">项目示例</h4><p>YouTobe上的这个视频展示了基于文本的战舰游戏是怎么玩的。<a href="https://www.youtube.com/watch?v=TKksu3JXTTM" rel="nofollow">Battleship Game</a></p><p>如果你对战舰游戏不熟悉，下面这个例子就是一个范例。记住你要实施一个基于文本的表示层用于测试。<a href="https://codepen.io/CodifyAcademy/pen/ByBEOz" rel="nofollow">Battleship Game by Chris Brody</a></p><h3 id="12-">12. 聊天应用</h3><p><strong>层级:</strong> 3-高级</p><p><strong>任务描述</strong>: 此项任务是创建一个可以支持多名用户互相发送信息的 实时聊天互动界面。 作为一个最小可行化产品，你可以关注聊天界面开发。实时性可作为追加选项稍后添加。</p><h4 id="--48">用户需求</h4><ul><li>用户在浏览聊天应用时根据提示输入用户名，用户名会在应用中保存</li><li>用户可在输入框中输入新信息</li><li>通过点击“进入”或者“发送”按钮，文本会出现在用户名旁边的聊天框中（比如： <code>John Doe: Hello World!</code>）</li></ul><h4 id="--49">追加选项</h4><ul><li>信息对于聊天应用（采用WebSockets）的所有用户可见</li><li>每当有一名新用户加入时，所有老用户都会受到提示信息</li><li>所有信息会存储在一个数据库中</li><li>用户可以发送图片，视频和链接。所有这些会以合适的形式展示</li><li>用户可以挑选，然后发送表情。</li><li>用户可以私聊</li><li>用户可以加入特定话题的频道</li></ul><h4 id="--50">可以提供帮助的链接资源</h4><ul><li><a href="https://socket.io/" rel="nofollow">Socket.io</a></li><li><a href="https://medium.freecodecamp.org/how-to-build-a-react-js-chat-app-in-10-minutes-c9233794642b" rel="nofollow">How to build a React.js chat app in 10 minutes — article</a></li></ul><h4 id="--51">项目示例</h4><figure class="kg-card kg-embed-card"><iframe id="cp_embed_ZWEdZj" src="https://codepen.io/iremlopsum/embed/preview/ZWEdZj?height=300&amp;slug-hash=ZWEdZj&amp;default-tabs=css,result&amp;host=https://codepen.io" title="Simple chat app using firebase" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;" loading="lazy"></iframe></figure><p><a href="https://web-chatty.herokuapp.com/" rel="nofollow">Chatty2</a></p><h3 id="13-github-">13. GitHub时间线</h3><p><strong>层级:</strong> 3-高级</p><p><strong>任务描述</strong>: 应用程序接口和信息图示是当代应用的特点。 GitHub时间线整合这两个特点，力求创造一个用户GitHub活动的可视历史。</p><p>GitHub时间线的目标是，存储GitHub用户的姓名，制作一条时间线，包含每个存储库，像他们的名字，创立的时间，和相关描述。未来可以将时间线分享给老板。时间线需易于阅读，可以有效利用颜色和字体排版。</p><p>只有面向公众的存储库可以展示。</p><h4 id="--52">用户需求</h4><ul><li>用户可以提交GitHub用户名</li><li>用户可以通过点击“生成”按钮创建和展示已命名的用户存储库时间线</li><li>如果用户名在GitHub中无效的话，用户可以看到提示信息。</li></ul><h4 id="--53">追加选项</h4><ul><li>用户可以看见当年创建的存储库数量总结</li></ul><h4 id="--54">可以提供帮助的链接资源</h4><p>GitHub提供了两个你们可能用到的接触存储库数据的应用程序接口。你也可以采用Node包管理器（NPM）接触GitHub应用程序接口。</p><p>GitHub应用程序接口说明可以在以下两个链接中找到：</p><ul><li><a href="https://developer.github.com/v3/">GitHub REST API V3</a></li><li><a href="https://developer.github.com/v4/">GitHub GraphQL API V4</a></li></ul><p>使用GitHub应用程序接口的样本代码如下：</p><p>你可以用CURL命令看V3 REST应用程序接口返回的JSON，这个程序接口就跟你的存储库有关：</p><p><code>curl -u "user-id" https://api.github.com/users/user-id/repos</code></p><h4 id="--55">项目示例</h4><figure class="kg-card kg-embed-card"><iframe id="cp_embed_FemfK" src="https://codepen.io/NilsWe/embed/preview/FemfK?height=300&amp;slug-hash=FemfK&amp;default-tabs=css,result&amp;host=https://codepen.io" title="CSS Timeline" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;" loading="lazy"></iframe></figure><figure class="kg-card kg-embed-card"><iframe id="cp_embed_QNeJgR" src="https://codepen.io/tutsplus/embed/preview/QNeJgR?height=300&amp;slug-hash=QNeJgR&amp;default-tabs=css,result&amp;host=https://codepen.io" title="Building a Vertical Timeline With CSS and a Touch of JavaScript" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;" loading="lazy"></iframe></figure><h3 id="14-">14. 拼读拼写</h3><p><strong>层级:</strong> 3-高级</p><p><strong>任务描述</strong>: 懂得如何拼读拼写拼写是流利掌握每门语言的基础要求。不论你是牙牙学语的孩童或者正在接触一门新语言的个体，练习拼读拼写会强化你的语言技能。</p><p>拼读拼写应用播放单词录音，用户用电脑键盘将单词拼写出来，从而帮助用户锻炼拼读拼写能力</p><h4 id="--56">用户需求</h4><ul><li>用户点击“播放”按钮，听到要拼写的单词录音</li><li>用户在键盘上打完单词后，可以在输入框里看到他们打出的单词</li><li>用户点击“输入”健提交已在输入框里的单词</li><li>如果提交单词正确，用户可以看到确认信息</li><li>如果提交单词错误，应用提示用户再次输入单词</li><li>用户可以看到拼写正确的单词总数，拼写过的单词总数和成功提交的单词占比。</li></ul><h4 id="--57">追加选项</h4><ul><li>单词拼写正确时用户可以听到确认声音</li><li>单词拼写错误时用户可以听到警示声音</li><li>用户可以点击“提示”按钮查看输入框中哪些字母出错</li><li>用户可以敲键盘上的“输入”健或者点击窗口“提交”按钮提交单词</li></ul><h4 id="--58">可以提供帮助的链接资源</h4><ul><li><a href="https://en.wikipedia.org/wiki/Speak_%26_Spell_(toy)" rel="nofollow">Texas Instruments Speak and Spell</a></li><li><a href="https://codepen.io/2kool2/full/RgKeyp" rel="nofollow">Web Audio API</a></li><li><a href="https://codepen.io/shangle/full/Wvqqzq" rel="nofollow">Click and Speak</a></li></ul><h4 id="--59">项目示例</h4><p><a href="https://itunes.apple.com/app/id447312716" rel="nofollow">Word Wizard for iOS</a></p><p><a href="https://play.google.com/store/apps/details?id=au.id.weston.scott.SpeakAndSpell&amp;hl=en_US" rel="nofollow">Speak N Spell on Google Play</a></p><h3 id="15-">15. 调查应用</h3><p><strong>层级:</strong> 3-高级</p><p><strong>任务描述</strong>: 调查应用可谓开发人员工具箱必备。通过这些应用，开发人员可以获得用户的各种反馈，例如对应用满不满意、有没有新要求或者新需求，急需解决的问题是什么，有没有一些变得严重的问题。</p><p>全功能调查应用的开发给你机会让你去学习，看你会不会把自己开发的应用加入工具箱。它也帮助你提升多方面的能力，如如何定义调查；让用户在预先设定的时间内回应；将结果做成表格并且展示。</p><p>应用的用户可以鲜明地分为两组，每组都有不同的要求：</p><ul><li>调查协调组--制定并实施调查。他们有普通用户没有的管理员权限。</li><li>调查受访者--完成调查并查看结果。在应用内部他们没有管理员权限。</li></ul><p>商业调查工具包括分布功能，以此公众会发调查邮件给调查受访者。简单说来，应用网页可以直达对回应开放的调查。</p><h4 id="--60">用户需求</h4><h4 id="--61">综述</h4><ul><li>调查协调组和调查受访组可以在一般网站上制定、实施、查看调查和调查结果。</li><li>调查协调可以登录应用获得管理员权限，比如可以制定调查。</li></ul><h4 id="--62">制定调查</h4><ul><li>调查协调组负责制定调查，其中包含有1-10个多项选择问题。</li><li>调查协调组可以在每个问题下设定1-5个相互排斥的选项。</li><li>调查协调组可以给调查设定题目。</li><li>调查协调组可以点击“撤销”按钮，不保存调查，返回主页。</li><li>调查协调组可以点击“保存”按钮保存调查。</li></ul><h4 id="--63">实施调查</h4><ul><li>调查协调组可以从先前设定好的调查中选择一个调查并打开</li><li>调查协调组可以从已打开的调查中选择一个关闭</li><li>调查受访组可以从已打开的调查中选择一个完成</li><li>调查受访组可以通过点击复选框选择调查问题的回答</li><li>调查受访组可以看见，如果一道题在第二次选择时选择了跟第一次不同的答案，那先前的答案会自动消除</li><li>调查受访组可以点击“撤销”按钮不提交调查，返回主页</li><li>调查受访组可以点击“提交”按钮提交回答</li><li>如果调查未完成就点击“提交”按钮提交，调查受访组会看到提示“错误”信息</li></ul><h4 id="--64">查看调查结果</h4><ul><li>调查协调组和受访组可以从已关闭的调查中选择调查展示</li><li>调查协调组和受访组在表格形式下查看调查结果，表格可以显示每个问题的每个答案有多少人选择</li></ul><h4 id="--65">追加选项</h4><ul><li>调查受访组可以在应用中创立一个独有账户</li><li>调查受访组可以登录应用</li><li>调查受访组每个调查只能做一次</li><li>调查协调组和受访组可以查看以图表形式呈现的调查结果（类似饼状图，条形图等表格）</li></ul><h4 id="--66">可以提供帮助的链接资源</h4><p>制定调查的图书馆资源库： <a href="https://surveyjs.io/Overview/Library/" rel="nofollow">SurveyJS</a></p><p>商业调查服务包括： <a href="https://www.surveymonkey.com/" rel="nofollow">Survey Monkey</a> 和 <a href="https://www.typeform.com/" rel="nofollow">Typeform</a></p><h4 id="--67">项目示例</h4><figure class="kg-card kg-embed-card"><iframe id="cp_embed_oLChg" src="https://codepen.io/amyfu/embed/preview/oLChg?height=300&amp;slug-hash=oLChg&amp;default-tabs=js,result&amp;host=https://codepen.io" title="Javascript Questionnaire" scrolling="no" frameborder="0" height="300" allowtransparency="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;" loading="lazy"></iframe></figure><h3 id="--68">贡献</h3><p>非常欢迎大家在 <a href="https://github.com/florinpop17/app-ideas">GitHub 仓库</a>中为这个项目做出一些贡献！任何形式任何贡献我们都非常欢迎~</p><p>贡献有两种方式：</p><ol><li>你可以创立一个新话题并且告诉我们你的想法。一定要确保你采用了 <strong>新想法</strong>标签；</li><li>将项目拆分，并且提交一份性能要求。在做这个工作之前，要确保你已经读过贡献指南，并且你也是这么做的（在存储库中你可以找到贡献指南）；</li></ol><h4 id="--69">添加你的个人实例项目</h4><p>在你完成项目以后，一也可以把自己做出来的成果添加到项目上。非常鼓励你们这样做，这也向其他人展示了你创造出了多么精彩的应用！</p><h3 id="--70">帮忙扩散我们的文章</h3><p>如果这片文章或者存储库中的信息对你有所帮助，一定要记得给个星星哦，这样其他人才能找到它，从中受益。让我们一起成长，把我们的社区建立得更好。</p><p>你有没有什么建议能帮我们总体提升我们的项目吗？有的话不要谦虚哦，非常期待你的反馈。</p><h4 id="--71">主要作者</h4><p><strong>Florin Pop</strong>: <a href="https://twitter.com/florinpop1705" rel="nofollow">Twitter</a> &amp; <a href="https://florin-pop.com/" rel="nofollow">website</a>.</p><p><strong>Jim Medlock</strong>: <a href="https://twitter.com/jd_medlock" rel="nofollow">Twitter</a> &amp; <a href="https://medium.com/@jdmedlock" rel="nofollow">Medium</a></p><h3 id="--72"><strong>每周编程挑战</strong></h3><p>作为额外福利，<a href="https://www.florin-pop.com/blog/2019/03/weekly-coding-challenge/">这里</a>有一个每周编程挑战，你可以通过实战项目训练切实提升自己的编程技巧。</p><p>原文：<a href="https://www.freecodecamp.org/news/here-are-some-app-ideas-you-can-build-to-level-up-your-coding-skills-39618291f672/">Here are some app ideas you can build to level up your coding skills</a>，作者：Florin Pop</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 自学编程 8 个月后，我拿到谷歌的软件工程师 offer ]]>
                </title>
                <description>
                    <![CDATA[ 找工作期间我曾拿到谷歌、网约车巨头 Lyft、最大的点评网站 Yelp、云计算独角兽 Rubrik、IBM 人工智能部门、摩根大通等公司的 offer。如果你正在找软件工程相关工作---特别是非计算机专业背景的人们——我希望我的故事可以激励你。 简介 你可能会想：怎么可能 8 个月就做到？ 在这篇文章中，我会详细介绍我的决策过程和思考过程，也会提供更多的阅读资料。  首先，我必须承认，很多因素赋予我很大优势：我是个白人，直男，本科就读于美国排名前 20 的高校，旧金山湾区工作的三年也让我积累了自己的人脉。 每个求职者的故事都不太一样，希望我的故事也能对你有所启发。 决定冒险 2018 年 7 月 29 日，我做了一个不理智的决定。 当时我面临着两个选择：一是去一家快速增长的广告技术公司担任办公室主任，二是参加编程训练营。办公室主任的薪水颇丰，发展稳定，似乎还是进入硅谷工作的快速通道，而编程训练营看起来代价又高、风险又大。 6 月 24 日，也就是做决定的 5 周前，我才用 JavaScript 写下了我的第一行代码，但也并没有成为一名工程师的打算。本科时，我读的是经济学专 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/first-line-of-code-to-226k-job-offer-in-8-months/</link>
                <guid isPermaLink="false">5f56f15bcd07b005bfb5aec5</guid>
                
                    <category>
                        <![CDATA[ 自学编程 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 求职 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 面试 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miaomiao Ma ]]>
                </dc:creator>
                <pubDate>Tue, 08 Sep 2020 03:10:57 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2020/09/Love-to-learn_tim-mossholder_unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>找工作期间我曾拿到谷歌、网约车巨头 Lyft、最大的点评网站 Yelp、云计算独角兽 Rubrik、IBM 人工智能部门、摩根大通等公司的 offer。如果你正在找软件工程相关工作---特别是非计算机专业背景的人们——我希望我的故事可以激励你。</p><h2 id="-">简介</h2><p>你可能会想：怎么可能 8 个月就做到？</p><p>在这篇文章中，我会详细介绍我的决策过程和思考过程，也会提供更多的阅读资料。 </p><p>首先，我必须承认，很多因素赋予我很大优势：我是个白人，直男，本科就读于美国排名前 20 的高校，旧金山湾区工作的三年也让我积累了自己的人脉。</p><p>每个求职者的故事都不太一样，希望我的故事也能对你有所启发。</p><h2 id="--1"><strong>决定冒险</strong></h2><p>2018 年 7 月 29 日，我做了一个不理智的决定。</p><p>当时我面临着两个选择：一是去一家快速增长的广告技术公司担任办公室主任，二是参加编程训练营。办公室主任的薪水颇丰，发展稳定，似乎还是进入硅谷工作的快速通道，而编程训练营看起来代价又高、风险又大。</p><p>6 月 24 日，也就是做决定的 5 周前，我才用 JavaScript 写下了我的第一行代码，但也并没有成为一名工程师的打算。本科时，我读的是经济学专业，过去三年在一家非营利机构做非技术管理咨询的工作。在湾区，有些职位要跟工程师一起工作，学代码只是因为我想让自己应聘这些职位时更有竞争力。</p><p>事实上，成为一名工程师像是天方夜谭。尽管我之前听说过许多人用一年时间通过编程训练营自学了编程，但我还是很难相信自己也可以达到同样水平。</p><p>据我了解，大多数工程师本科专业就是计算机科学，他们有着多年的工作经验，还会讲一门外语，我怎么能在这么短的时间内学会这么多东西呢？另外，要是我选择学习编程，我就要换行，为一个不确定的回报冒这么高的风险，值得吗？</p><p>办公室主任一职，则更像是梦想实现了：薪水比预想的要好，而且公司正在筹备不久后的收购计划，我将参与这一计划，几年后我也有望管理自己的部门。</p><p>但是，开始编程后，我就不想停下来。我热爱技术挑战，喜欢迎难而上。我还发现，<a href="https://dilbertblog.typepad.com/the_dilbert_blog/2007/07/career-advice.html">发展第二个专业技能</a>让我做足准备，准备开启一段不平凡的有影响力的职业生涯。</p><p>我内心里也有个声音在问：成为一名工程师会不会既能提升专业度，又能完成个人转型？如果我能学会编程，有什么是我学不会的呢？正是这种学习态度，支撑我坚持走完了整个旅程。</p><p>我选择了线上的编程课，连续三周每周编程时间不低于 40 个小时，之后我向 <a href="https://www.hackreactor.com/onsite-immersive">Hack Reactor</a> （被誉为“编程训练营中的哈佛”）提交申请，想试试看我是否能成为其中的一份子。侥幸通过测试后，同一周，我拿到了办公室主任的工作 offer。</p><p>思考了 72 个小时，我最后再次查看了自己的银行账户，算了算 Hack Reactor 项目结束后，我可以支付三个月的房租和生活开支。我想，三个月时间足够我找到工作了。</p><p>于是，我选择了编程训练营。</p><p>我给广告技术公司打电话拒绝了他们的 offer。挂断电话后我的情绪很复杂，一方面我很害怕：我可是为一个疯狂的决定放弃了一生仅一次的工作机会！另一方面我又激情满满：为了不让自己后悔，冒险前进吧！</p><p>没过多久，我的激情就消耗殆尽了。不过再没有回头路了：我已经踏上了冒险旅程。</p><h2 id="--2"><strong>学习编程</strong></h2><blockquote><strong>“你不必一开始就优秀，但你要开始变得优秀。”— Zig Ziglar，国际知名演说家、作家</strong></blockquote><p>Hack Reactor 和其他一些编程训练营都力求在三个月内完成传统大学计算机科学专业需要四年才能完成的教学任务，以让学员具备竞争一线软件工程工作的能力。</p><p>目标很宏大，所以得分秒必争。三个月的课程安排中，一周 6 天，一天上 12-14 小时的课，时间很紧，所以我们每天都要做大量任务。</p><p>每次收到任务时，我都会心里一惊：这根本不可能在截止期限内完成！我连从哪儿下手都没有头绪。但很神奇，每次到截止期限时，我总是能想出来或基本想出来一个解决方案。</p><p>经历足够的震惊与不可能之后，我开始感到一丝丝的激动：挑战看起来有多不可能，找到解决方案的时候就有多心满意足。</p><p>Hack Reactor 不仅仅教授编程知识，它还会教给我们<a href="https://en.wikipedia.org/wiki/Grit_(personality_trait)">咬紧牙关坚持的精神</a>，以及<a href="https://www.mindsetworks.com/science/">成长型思维</a>，过程十分令人激动。</p><p>我仍然怀疑自己是否能在存款用完之前找到工作，于是我养成了最好的学习和生活习惯。</p><p>充足的睡眠才能保证<a href="https://news.berkeley.edu/2011/03/08/sleep-brainwaves/">学习效率</a>，所以我规定了严格的睡眠时间。</p><p>为了缓解经常性压力，每隔一天我都会锻炼身体<a href="https://www.fastcompany.com/3025957/what-happens-to-our-brains-when-we-exercise-and-how-it-makes-us-happier">促进健康</a>、<a href="http://www.educationalneuroscience.org.uk/resources/neuromyth-or-neurofact/exercise-enhances-learning/">支持学习</a>。</p><p>为了提升记忆力，让每一天的学习都比前一天有进步，几乎每天晚上我都会复习核心课程，思考哪些事情做得比较好，哪些还不够好。</p><p>最重要的是，为了在一个如此紧张的安排中保持基本健康水平，每天早上上课之前我都会花一个小时来做<a href="https://ggia.berkeley.edu/practice/body_scan_meditation">禅修</a>和<a href="https://jackkornfield.com/meditation-lovingkindness/">慈爱冥想</a>。</p><p>有的人可能会对最后一个习惯感到惊讶，但是有充足的<a href="https://nccih.nih.gov/health/meditation/overview.htm">证据</a>表明“冥想能改善健康”，尤其是<a href="https://www.psychologytoday.com/us/blog/feeling-it/201409/18-science-backed-reasons-try-loving-kindness-meditation">慈爱冥想</a>。它帮助我保持对编程学习的好奇和愉悦，缓解了我面对编程学习挑战和工作的不确定性时的忧虑，对我来说十分有价值。</p><p>因为交通问题，我没有选择面对面授课。所以尽管我离校园步行只需十分钟，我仍然选择了网课。因为我上课无需通勤，吃饭方便，公寓环境十分安静，所以，我每天多出了 90 分钟不被打扰的<a href="https://medium.com/@dsilvestre/deep-work-by-cal-newport-lessons-305a375c41b8">深入学习时间</a>。</p><p>刚开始的 6 周，有两天是在未完成代码库的基础上，进行结对编程冲刺。两天时间里，我们重写了JavaScript <a href="https://underscorejs.org/">Undercore 库</a>，从零开始建立了基础数据结构，学习了面向对象编程和函数式编程，计算了时间和空间复杂度，构建了一个包含从客户端到服务器端到数据库的全栈应用。我们组有 24 人，每天视频会议时间不下 10 小时，逐渐成为朋友，可以互相开开玩笑。</p><p>学习了三周以后，我担心我可能不会通过中期考评，所以我<a href="https://www.creativityatwork.com/2003/01/10/art-of-possibility-ben-zander/">给未来的自己写了一封信</a>，告诉自己要想通过考评需要如何做。</p><p>我提到了我现有的生活和学习习惯，又增加了一些新的习惯，比如，如果没有能力在脑海里给一个虚构的小女孩（<a href="https://fs.blog/2012/04/feynman-technique/">费曼学习法</a>）解释核心代码，那就要复习这些我没有完全理解的代码，直到有能力给她解释为止。</p><p>3 周以后，在 24 小时内，我从零建立起了自己的第一个全栈应用，出色地通过了考评。大学教育十分重要，但这里的教育是另一种体验。</p><p>第二个 6 周里，有更多的自由形式小组项目。我从正向偏差中汲取灵感，追随着训练营营友的步伐，跟他们进行了交流。这些营友找的工作都十分成功。根据他们的指导建议，我设定了严格的 deadline 以应对巨大的技术挑战，在求职市场上挑选出最受欢迎的职业技能，例如能使用 Docker 和微服务系统工作，在不同的项目中扮演不同的角色。我还请一个营友对我进行了一次辅导，我用两天时间成功运行一项新性能，这位营友刚开始却花费了数周时间。</p><p>Hack Reactor 会从每支队伍的毕业营员中雇佣一些作为短期兼职助教，来支持全职员工的工作。毕业以后，我在这里担任了 6 周的助教，每周工作 35 个小时。工作内容包括：帮助制定课程安排、进行独立调研、基于调研结果帮助在找工作的营员、面试前来应聘的候选人等。</p><p>我跟训练营负责人商量只做 6 周的助教，而不是通常的 12 周。助教工作让我接触到了新的课程，同时也让我兼顾找工作和全职学习两件事，没有太多耽搁。非常感激能在助教工作中学习，助教工作确实进一步<a href="https://medium.com/accelerated-intelligence/memory-learning-breakthrough-it-turns-out-that-the-ancients-were-right-7bbd3090d9cc">加深了我自己的学习</a>，开出的薪水也足够我两个多月的开支，极大地缓解了我的压力。</p><h2 id="--3"><strong>求职旅程</strong></h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chinese.freecodecamp.org/news/content/images/2020/09/image.png" class="kg-image" alt="image" width="1024" height="287" loading="lazy"><figcaption>给我工作 offer 的公司</figcaption></figure><p>12 月 7 日，距离我写下第一行代码已经过去了 165 天，我的 Hack Reactor 训练营也结束了，剩下的存款还够我承担 4 个月的房租和生活开支。训练营告诉学员要预留 6 个月的时间来找工作。倒计时正式开始！</p><p>即使困难重重，我还是想要放手试一试，所以我给自己制定了以下目标：</p><ul><li>拿到的薪酬在训练营排名要在前 25%，目标是年薪超过 12 万美金</li><li>工作尽可能具备最刺激的学习体验，希望职位既能让我充分发挥主观能动性，也有机会接触到行业大牛</li><li>工作团队和公司的文化以技术为重，同时要以人为本</li><li>工作要有趣也有意义</li><li>要做后端开发工作，至少要是全栈开发（大多数训练营毕业生都是从事前端开发工作）</li></ul><p>我从未设想过我的目标能全部实现。我知道找工作一定会像过山车一般跌宕起伏。</p><p>通过在 Hack Reactor 这段短时间的学习，我的基础并不扎实，但是在去一流公司面试之前，我还有几周时间可以全心学习。</p><p>而且，我可能会面对数不清的拒绝。尽管有调查显示，在面试中，<a href="https://triplebyte.com/blog/bootcamps-vs-college">训练营学员跟四年计算机专业科班出身的学生表现一样优秀</a>，大部分公司仍然不愿意聘用从编程训练营毕业的学员。软件工程面试中牵扯到的话题范围特别广泛，这也让我根本没办法面面俱到地准备。</p><p>等到求职之旅终于尘埃落定时，我总共申请了 44 家公司，其中 41 家是熟人帮忙介绍的，遇见了 14 次或编程挑战或技术电话面试，其中有 8 次进入了现场面试。截至 2019 年 2 月 15 日，我共收到了 7 个 offer。这距离我写下第一行代码，已经过去了 245 天。</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://chinese.freecodecamp.org/news/content/images/2020/09/image-1.png" class="kg-image" alt="image-1" width="1014" height="1024" loading="lazy"><figcaption>有 16% 的工作 offer 都是在我第一次写下代码 8 个月后拿到的</figcaption></figure><h2 id="--4">开始找工作，从失败中汲取教训</h2><blockquote><strong>“学习不是偶然获得的，必须保持热情，勤于钻研”—— </strong>Abigail Adams，美国第一夫人</blockquote><p>刚开始找工作的几周是最艰难的。12 月一整月，我只获得了几个编程测试机会，只拿到了 IBM 人工智能业务部的面试机会。</p><p>前两个编程测试的反馈就不如人意，我做的时候超时了，还被告知我的代码“准确性不够，性能也不够高”。</p><p>第三个编程测试有几个小时的时间，但我仍然心跳加速。我在时间结束前几秒完成了测试，却没来得及点击提交！</p><p>我告诉自己量变才能引起质变，现在我需要积累。每天早上一个小时的慈爱冥想结束后，我都会花一分钟提醒自己两件事：</p><ul><li>第一，目标确实给人方向。但如果只关注目标，在面对自己当前的水平和想要达到的目标之间的巨大差距时，我就会十分不满和沮丧。我要养成<a href="https://fs.blog/2017/06/habits-vs-goals/">不被目标束缚的习惯</a>。</li><li>第二，我认为，不管面试的是什么工作，经历的真正价值在于个人提升而非专业提升。我很幸运，能用几个月的时间全职学习如何学习，我现在也完全沉迷于此。</li></ul><p>我知道失败是成功之母，但前提是得认真对待失败。每次编程测试或者面试失败后，我都会反省，然后在我的文本编辑器里再次开始解决问题，直到完全解决。面试时的一个需要在 20 分钟内完成的任务，我在 3 天内花了 9 个小时来解决！</p><p>每解决一个问题，我都会记录下新概念和灵光一现的时刻，把它们看成是宝贵的<a href="https://fs.blog/mental-models/">思维模型</a>。我希望在面试时匹配到相应的模型。我会按照<a href="https://artofmemory.com/wiki/Spaced_Repetition_and_Recall">记忆重复间隔</a>定期回顾它们，以便形成长期记忆。</p><p>如果问题涉及新的编程句法结构，我会把问题按照时间紧急程度重做一遍，这样才能保证，面试再次碰到这些问题时轻松应对。</p><p>这些习惯不仅仅是增强了我的记忆力，还帮我建立了自信。我不知道在积蓄花完之前能否找到一份工作，但我知道哪怕是最令人失望的经历也在帮助我变得更好，这种感觉让我知足。</p><p>我的每日规划十分平稳，一周不少于 5 天，每天 8 小时：学习或者面试，总结失败或者成功经验，思考，重复。 面试中我可能会遇到诸如数据结构、算法、前端 DOM 操作、系统设计等等。按照这些可能，我不断地调整自己的学习计划以便面试时呈现最佳状态。之后我会预估接下来的面试遇到各种类型考题的可能性有多大，评估自己的面试表现，决定下一步的学习任务。</p><p>为了确保用到最好的学习资源，我按照主题分门别类，整理了其他学习者们推荐的各种资源，列成清单。需要学习这个主题时，我会再去谷歌快速搜索一下，看看有没有什么新的资源可以更新到清单上，然后找出最好的一到两个资源进行深入学习。前一天我会做好各项事件优先级排序，第二天就能确保，清晨冥想之后，进行 2-3 个小时的不被打扰的深入学习。</p><p>每天我还会花 2-3 个小时寻找目标公司，找出重点目标，然后投递简历。每次投递简历花费的时间比我预想的要多，而且可供我选择的一流公司的数量有限，因此，我尽所能通过以下方式提升我从投递简历到拿到面试机会的概率：</p><ul><li>简历中<a href="https://resumegenius.com/how-to-write-a-resume/accomplishments-on-resume-quantify-achievements">强调自己工作取得的成果或者采取的行动</a></li><li>研究邮件和领英哪个渠道和信息流能最快给我推荐相关公司</li><li>整个流程写在电子表格上随时回顾</li><li>跟进所有正在进行的沟通</li></ul><p>我几乎把所有投递简历的过程当做实验，希望投入时间带来的回报能不断提高。我的好习惯也帮了我很多——把已投递简历的公司写入表格意味着，在我被拒绝之后，我可以立即寻找下一个机会。</p><p>我也尽可能地安排好时间，首先面试一些不那么想去的公司，缓慢推进意愿度高的公司的面试进程，比如谷歌。 </p><p>IBM 的面试（包括一次电话面试和三次现场面试）是我坎坷求职之路上的转折点，给我上了一堂课，教会我如何处理不确定性。。</p><p>每次面试一开始，我都会经历那种现在无比熟悉的感觉，默默对自己说：我不知道怎么做。 但我每次都会深呼吸，提醒自己：在家里，从不知所措到想出解决方案都如此有趣，所以，在这里——挑战更大，工作触手可及——想出解决方案的那种感觉该会有多美妙！</p><p>前两次面试之后，我猜想也许我的热情和学习导向的态度是具有感染力的。面试官当然知道我并没有一开始就找到答案，但他们似乎很享受我在接近解决方案时话语间体现出的活力。</p><p>面试结束离开 IBM 的时候，我给自己加油打气：就算没有拿下这份工作，我也很享受压力下的思维提升。我坚信这种信念会帮助我找到工作。</p><p>幸运的是，12 月的失败浇灌了 1 月的成功之花。</p><h2 id="--5">良好势头和早期成果</h2><blockquote><strong>“最艰难的日子过后就是你人生的高光时刻，继续前进吧。” —— <strong>Roy T. Bennet</strong></strong></blockquote><p>在 1 月的第一周，IBM 打电话通知我被录用了，具体的正式录用细节会之后另行通知。“我可以利用一下这个 offer 吗？” 我问自己。随后我跟谷歌招聘人员分享了我拿到 IBM offer 的消息，他回复说让我跳过电话面试直接现场面试。</p><p>突然我就引起了招聘人员的关注。我立即跟所有我正在联系的公司说我已经拿到 IBM offer 的消息。新年伊始，整个找工作的节奏就这样被调动起来了。</p><p>第二周，去参加摩根大通的四场现场技术面试时，我第一次信心满满，甚至还提前完成了任务。12 月的辛苦付出终于有了收获，我欣喜若狂。</p><p>几天以后是谷歌面试，难度令人咋舌。第二场面试涉及到异步 JavaScript promise，我发挥得很差。</p><p>午饭休息时间，我在休息室里花了一点时间稍作休整，判断了一下形势觉得自己无望拿到 offer，我决定把目标调整成尽可能地从失败中多学经验。 我知道晚上回家后我要做个事后总结。但同时我也想挑战一下，看自己在如此高压环境下能保持几分镇定与平静。毕竟，面试谷歌多么令人激动。</p><p>这样的想法把我从慌乱状态中解救出来，下午的表现可圈可点。离开的时候，我甚至抱有一丝希望，觉得谷歌会给我 offer。</p><p>根据事后总结的习惯，回到家后我找到关于 JavaScript promise 的线上资源从零学起。第二天我又参加了三次电话面试，表现一般。</p><p>面试一家安全创业公司时，我表现很好；但面试一家小型能源创业公司时，我表现很差。电话面试 Rubrik——一家云存储独角兽公司——又给了我极大的信心。</p><p>Rubrik 的面试问题也是关于 promise，比前一天谷歌面试的还要难。但因为我前一天晚上的总结，现场创新，在面试结束之前刚刚完成。</p><p>面试官说我是他们面试的第一个编程训练营出身的人——他们之前只从名校招人——并且他们一点都不相信我从去年夏天才开始写代码。我开心得甚至在房间里跳了几步舞。</p><p>过了一周，摩根大通打电话给我，说要录用我，年薪 11 万美金，不包含股票和奖金。但我觉得我不太适应摩根大通的企业文化，而且这个薪资距离我 12 万年薪的目标还有差距。但因为这是我的第一个正式 offer，我还是特别激动，终于有人雇我写代码了！</p><p>我开始接到好多来自面试官、招聘人员和各个顾问的电话，结果仍然是有好有坏。谷歌打电话说面试结果仍不明朗，可以去招聘委员会询问；Uber 给了我面试机会；我觉得电话面试亚马逊时表现很好，但没有拿到面试机会；我觉得我搞砸了 Yelp 的电话面试，但却拿到了面试机会。</p><p>在一场场的面试中，我非常注意我面对招聘人员时的措辞。那家安全创业公司说他们担心没有办法给出像 IBM 和摩根大通一样的薪水，问我拿到的 offer 开出的薪水是多少。</p><p>我几乎都要上钩了，但我停下来想了想之前 Hack Reactor 训练营指导过的关于薪水问题的回答方式，于是我说，“其实我觉得不如这样，你告诉我打算开多少薪资，我看看在不在我的理想范围之内”，“当然可以，我们的薪资起薪是 12.5 万。”</p><p>12.5 万美元！这个数字超出了我的目标！</p><p>我望向别处来掩盖自己激动的心情，装作正在思考。然后我扭过头，镇定地说：“如果这样的话，我想我们可以进一步谈谈。”招聘人员说：“那好，只要还能谈我就放心了。”我也是，我在心里默默想到。</p><p>几天后我拿到正式 offer：年薪 12.5 万美元，外加每年当年市值的 6000 美元的股票期权。但是这些钱根本不重要，我特别中意公司的企业文化，职位也是非常有吸引力的后端开发，还有绝佳的指导机会。团队中 40 个工程师至少都有两年的工作经验，大部分都来自像麻省理工、斯坦福或者伯克利之类的顶尖名校。这些跟我憧憬的工作都十分契合！</p><p>但这一切，才刚刚开始。</p><h2 id="--6">跟公司谈判，做出最后决定</h2><blockquote><strong>“高效的谈判者会回顾对方所说的话，并挖掘对方深层的动机……他们拥有无穷的好奇心。”—— </strong>Chris Voss<strong>，</strong>国际危机谈判专家</blockquote><p>两天后 Rubrik 给我回了电话，我无比惊讶。我也将会是他们聘用的第一个从编程训练营毕业的员工。Rubrik 市值早已达到 33 亿美元，现在是一家炙手可热的新型独角兽公司。我可以和经验丰富的软件工程师共事，工作环境也让人心动。我回复招聘人员说要考虑一下，其实心里早已乐开了花：这么有竞争力的公司也想要我！挂断电话以后我仍然十分激动，差点忘记自己漏接了谷歌的电话。</p><p>我深呼吸几下，把电话回拨了过去。招聘人员倒是开门见山：“根据招聘委员会的通知，很开心地通知你被谷歌录用了，我们开出的薪酬是---”</p><p>我完全控制不住自己的尖叫声，蹦蹦跳跳进了厨房！天哪！谷歌！那家软件工程行业的标杆公司！他们的面试官是我整个面试经历中我遇见过的最严厉的！他们决定要我了！之后招聘人员告诉了我公司开出的薪酬，事情变得更加不真实了。年薪 16.3 万美元，包括：基础工资 12 万，奖金最低 1.8 万，每年公司股票 2.5 万，总共 16.3 万美元。</p><p>我心里想：你们疯了吗？毕竟我最近的报税单上的年薪只有 7.7 万美元。</p><p>我给自己放了一下午的假，想着应该没人看到，便在房子周围抑制不住兴奋地跳来跳去。我也给家人打了电话分享这个天大的好消息。</p><p>第二天上午，我又回归到辛苦学习当中。只不过这次不是学习算法，而是学习如何谈判。一夜之间，那些在面试过程中指导我的面试官成为了我在谈判中的对手。我觉得自己就像在狼群中求生存的一只羔羊——周围都是专家，几分钟的谈话之间就可能决定我的薪酬能不能多几千美元。</p><p>刚开始我很害怕，担心这样做会让自己显得比较贪婪，但 Hack Reactor 的教练态度特别坚定。她说这特别正常，谈判不仅仅是为了更高的薪酬。在谈判过程中，一个人有没有认真思考、是否自信都可以在谈判过程中得到显现。同时也会让老板对你刚进入公司时的工作有所期待。</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://camo.githubusercontent.com/887472c9bbceb40319125d002f26ebbba9ad2960/68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f67543641667977356a66356342366b346777467732317a6769596f4d362d48713636703734617545627045366f555a4a666e585554595434655f577465574b6f456663574450354c6239736e434e37794c595863676d5f4f32453139544c5f62586b2d4c4136434b38676c4b5a5f2d5466566e4765627658576d696268364d335939494167523046" class="kg-image" alt="68747470733a2f2f6c68332e676f6f676c6575736572636f6e74656e742e636f6d2f67543641667977356a66356342366b346777467732317a6769596f4d362d48713636703734617545627045366f555a4a666e585554595434655f577465574b6f456663574450354c6239736e434e37794c595863676d5f4f32453139544c5f62586b2d4c4136434b38676c4b5a5f2d5466566e4765627658576d696268364d335939494167523046" width="600" height="400" loading="lazy"><figcaption>我发现基本 90 %的工资上涨都是因为有我第一份工作开出薪酬的比较</figcaption></figure><p>接下来的几天，我都在跟招聘人员和顾问的电话沟通中度过，不断学习为谈判做准备，也在谈判后及时复盘吸取经验。我把希望在谈判中呈现出的内容写在了一页纸上，每次谈判过后也会反思哪部分进行得好，哪部分有待提升，就像我之前复盘面试失败教训一样。</p><p>我学着去爱上这个过程。每次谈判都会出现不同的令人着迷同时也令人困惑的问题，涉及层面多样，例如高水平策略方面——有关我分享信息的时间和方式，例如当下策略方面——我应该用什么样的语气沟通。能解决这么多的问题非常有趣。有时我能在一天中跟多个招聘人员聊天，每次电话沟通既能让我练习新学到的谈判技巧，同时也能让我重新积累教训。</p><p>读大学时我就读完了哈佛大学谈判项目的两部分：<em><em>Getting to the Yes</em> </em>和 <em><em>Getting Past the No</em></em>，对最佳替代方案（BATNA）和双赢解决方案之类的概念非常熟悉。但我还是从<em> </em>Chris Voss 的<em>《<em>Never Split the Difference</em>》</em>书中获得最多的灵感<em>。</em>拿到谷歌的 offer 以后我又把这本书读了一遍。 另外，我还阅读了 <a href="https://haseebq.com/farewell-app-academy-hello-airbnb-part-ii/">Haseeb Qureshi</a> 写的所有博客，他也是编程训练营出身，把赚来的钱捐给慈善事业。我也会时常跟训练营的职业教练沟通，在我之前，她有着成百上千的谈判指导经验。</p><p>Rubrik 刚开始薪酬报价是 16.3 万美元，跟谷歌不相上下。之后，Yelp 打电话过来，上演了剧情大逆转。他们把我申请的职位提升到一个非初级岗，然后给我开出了 16 万美元的年薪，另外还有 2 万美元的入职奖金——第一年总共 18 万美元。</p><p>18 万美元和非初级岗，怎么样？</p><p>我在 Yelp 面试中表现出了自己的最佳水平——在给定时间内完成了所有任务，为满足新的需求重新调整了代码使之无缝衔接，通过粗略计算评估了系统架构。面试官甚至都因此感到吃惊。但这些并不能改变我没有任何工作经验的事实。谷歌和 Rubrik 马上就回复说他们会调整薪水。</p><p>最终，找工作的最激动人心的部分来了。</p><p>Lyft 发邮件说要电话沟通。迄今为止，我的面试最好体验就来自 Lyft，但我觉得我的面试表现不能让我拿到他们的 offer。面试时我几乎是立马就想出了解决方案，但写的代码却始终没有运行出来。后来我又想出一个改进办法，但超时了没有提交成功。每天车轮般的谈判让我身心俱疲，所以我回复给 Lyft 的邮件如下：</p><p><em>“我现在在和好几家公司沟通。你介不介意用邮件直接通知我结果呢？我大概猜到我应该没有通过面试，但即便这样，我还是想从每次面试中获得一两句评价反馈，麻烦你了。非常感谢你百忙之中抽出空来对我进行指导。”</em></p><p>Lyft 的回复只有一行：“你通过面试了。”</p><p>什么？我通过面试了？我简直不敢相信，我以为已经没有希望的最中意的选择竟然兜兜转转回来了！第二天，我们谈定了薪酬：各项加起来总计年薪 21 万美元。</p><p>21 万美元！</p><p>想一想，这可是 Lyft！这是我朝思暮想可以工作的公司，工资什么的一点都不重要。几个在 Lyft 工作的朋友是我最喜欢的其中一部分人——很难说是因为他们善良还是聪明——我的面试官们似乎也如出一辙。</p><p>和 Lyft 确定薪酬后，我告知了每个正在沟通的公司，并且告诉他们我有最后一周的考虑时间，想鼓励他们给出最终确定薪酬。持续不断的谈判让我身心俱疲，我认为有截止期限在，可以大大减少每个公司在我身上投入的时间。Voss 也建议说，截止期限可以作为杀手锏使出。</p><p>谷歌给出了 18.9 万美元的薪酬，高于 Yelp 的报价，并且表示会根据 Lyft 的报价重新作出调整。Rubrik 同意电话沟通。Yelp 和那家安全创业公司表示不会继续沟通。我也不打算继续跟进摩根大通和 IBM。Uber，虽然给了我面试机会，却并没有给我发 offer。</p><p>Lyft 团队邀我共进午餐，我受宠若惊。不管是谷歌、Yelp 还是安全创业公司的团队都让人特别舒服，但是 Lyft 团队来了九个人跟我一起吃午饭，气氛十分融洽，饭桌上大家谈笑风生，好像我早就已经是团队中的一份子。他们说招我进公司是 2019 年公司的头等大事。一名高级工程师表示他十分乐意做我的导师。此时距离 Lyft 首次公开募股的日期，已经没有几个月了。</p><p>在 Lyft，我什么都有了：导师指导、快速成长的环境、以人为本的企业文化、令人激动的工作以及现在如此之高的薪酬。</p><p>Rubrik 没有及时给出薪酬报价。谷歌最后的报价是 23.3 万美元，如果算上 401K 养老保险制度和慈善机构项目就是 21.6万美元。因为我的目标就是想拿更高的薪酬，同时也能捐赠更多，并且这一年我将会捐出我税前收入的 25%，所以我觉得这一报价还可以。我也很赞同谷歌的企业文化，并且谷歌把中级工程师培养成一流天才专家的能力依然一流。</p><p>我在谷歌和 Lyft 之间摇摆不定，纠结了几天。慢慢地，我越来越觉得，抛开薪酬不谈，Lyft 绝对是我不能错过的机会。经过最后谈判，Lyft 的薪酬定在了 22.6 万美元，包括 13.5 万美元的基本工资，IPO 之前估价 7.1 万的股票，和 2 万美元的入职奖金。2 月 25 号，是周四，那时距离我写下我的第一行代码已经过去了 245 天，我接受了 Lyft 的 offer，为这一段求职旅程划上句点。</p><p>在 Lyft 工作的 6 个月，是我最开心的工作时光：团队互相扶持，工作内容吸引人，薪酬待遇也好。但是，就成为一名工程师而言，宝贵之处在于，我爱上了学习。既然我已经为学习痴迷，我就不打算与它分离。</p><h2 id="--7">找到一份软件工程师工作</h2><p>我把之前用来准备面试的资源列成了清单分享给有需要的人。同时我也会为求职者提供求职指导课程，参加课程的学员需要把自己未来收入的 10% 或者更多投入到高影响力的公益事业。</p><p><strong>点击<a href="http://www.swejobsearch.com/resources/">这里</a>获得资源清单和求职指导课程</strong>。</p><p>注意：希望我的私人生活可以跟作为求职教练的生活有所分割，因此我使用了笔名。</p><p>在这篇文章中，我给到了详尽的薪酬数目，有两个原因：一，我希望这些信息对于非科班出身的求职者有所帮助，因为他们之中大部分人对此了解甚少；二，详尽的<a href="https://www.nytimes.com/2018/08/31/smarter-living/pay-secrecy-national-labor-rights-act.html">薪酬数目</a>也有助于消除薪酬不平等现象，让每个人都能得到公平对待，尤其是<a href="https://leanin.org/equal-pay-data-about-the-gender-pay-gap">少数群体</a>。</p><p>反对薪酬不平等现象是 Lyft 一直以来的使命，同时也符合 Lyft 的企业文化。Lyft 在反对这一不平等方面投入了很多努力，每年都会进行三方薪酬股权审计。就在去年，Lyft 官方调查显示“<a href="https://www.forbes.com/sites/maggiemcgrath/2019/07/31/lyfts-2019-pay-equity-audit-has-a-surprising-result-its-male-and-female-employees-earn-the-same-thing/#56e6e0357a8d">不存在系统性薪酬差距</a>”，这家公司便成为了一家独特的独角兽公司。准确的薪酬信息在很多网站都可以找到，例如 <a href="https://www.paysa.com/salaries/software-engineer--t">paysa</a>，<a href="https://www.levels.fyi/">levels</a> 和 <a href="https://www.teamblind.com/search/software%20engineer%20lyft">blind</a>，我在文中分享的信息在这些平台都可以找到。</p><p>最后，很感谢在这段旅程中一直有很多人给予我支持，特别是求职教练兼谈判顾问 Lena Johnson 和技术导师 Robin Kim。再次衷心感谢大家！</p><p>原文：<a href="https://www.freecodecamp.org/news/first-line-of-code-to-226k-job-offer-in-8-months/">How I Went from Writing My First Line of Code to a $226K Job Offer in Just 8 Months</a>，作者：Jason Zedde</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Python学习：从小白到大神 ]]>
                </title>
                <description>
                    <![CDATA[ 第一个问题：Python是什么？创始人吉多*范苏罗姆认为，Python是一种“高级编程语言，其核心设计哲学强调代码的可读性和句法，因此几行代码就能够表达程序员的想法。”  为什么我要学Python呢？一个原因在于，Python非常美妙，Python语言可以相当自然流畅地表达我的想法。 另一个原因就是，Python编程在很多方面都大有可为，包括但不限于数据科学、网站开发、机器学习。Quora， Pinterest和Spotify的后端网站开发都在使用Python。因此，让我们一同来学习Python吧。 基础知识 1. 变量 很简单，你可以把变量理解成储存值的代码。 在Python中，定义一个变量、给变量赋值十分简单。例如：给变量"one"赋值1，代码如下： one = 1 这样就可以把1赋值给变量"one"了，很简单吧。 two = 2 some_number = 10000 你可以把任意数值赋值给你想要的任意变量。如上述代码，整数2赋值给了变量"two"，整数10000赋值给了变量"some_number"。 除了整数，布尔值（True / False）、字符串、浮 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/learning-python-from-zero-to-hero/</link>
                <guid isPermaLink="false">5ee1f9a6db4be8080eb70ddf</guid>
                
                <dc:creator>
                    <![CDATA[ Miaomiao Ma ]]>
                </dc:creator>
                <pubDate>Thu, 11 Jun 2020 15:03:50 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2020/06/1_ueWmI48uuShON-hX7LwI0w.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>第一个问题：Python是什么？创始人吉多*范苏罗姆认为，Python是一种“高级编程语言，其核心设计哲学强调代码的可读性和句法，因此几行代码就能够表达程序员的想法。” </p><p>为什么我要学Python呢？一个原因在于，Python非常美妙，Python语言可以相当自然流畅地表达我的想法。 另一个原因就是，Python编程在很多方面都大有可为，包括但不限于数据科学、网站开发、机器学习。Quora， Pinterest和Spotify的后端网站开发都在使用Python。因此，让我们一同来学习Python吧。</p><h3 id="-">基础知识</h3><h4 id="1-">1. 变量</h4><p>很简单，你可以把变量理解成储存值的代码。</p><p>在Python中，定义一个变量、给变量赋值十分简单。例如：给变量"one"赋值1，代码如下：</p><pre><code class="language-python">one = 1
</code></pre><p>这样就可以把1赋值给变量"one"了，很简单吧。</p><pre><code class="language-python">two = 2
some_number = 10000
</code></pre><p>你可以把任意数值赋值给你想要的任意变量。如上述代码，整数2赋值给了变量"two"，整数10000赋值给了变量"some_number"。</p><p>除了整数，布尔值（True / False）、字符串、浮点数和其他数据类型也可以赋值给变量。</p><pre><code class="language-python"># booleans
true_boolean = True
false_boolean = False

# string
my_name = "Leandro Tk"
</code></pre><h4 id="2-">2. 控制语句：条件判断</h4><p>"If"条件语句检验条件真假。如果条件为真，执行if后面的条件。举个例子：</p><pre><code class="language-python">if True:
  print("Hello Python If")
</code></pre><p>2比1大，条件为真，所以执行print后面的程序。</p><p>如果if后面的条件语句为假，则执行else后面的语句。</p><pre><code class="language-python">if 1 &gt; 2:
  print("1 is greater than 2")
else:
  print("1 is not greater than 2")
</code></pre><p>1小于2，条件为假，所以执行else后面的语句。</p><p>也可以使用elif语句：</p><pre><code class="language-python">if 1 &gt; 2:
  print("1 is greater than 2")
elif 2 &gt; 1:
  print("1 is not greater than 2")
else:
  print("1 is equal to 2")
</code></pre><h4 id="3-">3. 循环/迭代</h4><p>Python有很多不同的循环/迭代模式。今天说两个：while循环和for循环。</p><p>while循环：当条件为真，while模块语句执行。我们可以用while循环来输出1-10这几个数字。</p><pre><code class="language-python">num = 1
</code></pre><p>while循环需要循环条件。如果循环条件为真，循环继续。上述代码表明，num值为11时，循环条件为假，循环停止。</p><p>另外一种代码形式可以更好的理解循环条件：</p><pre><code class="language-python">loop_condition = True
</code></pre><p>循环条件为真，循环继续，直到循环条件为假。</p><p>for循环：模块语句运用"num"变量时，for循环迭代变量。for循环代码可以跟while循环一样输出数字1-10。</p><pre><code class="language-python">for i in range(1, 11):
  print(i)
</code></pre><p>看见了吧，就是这么简单。整数数列range()循环从1开始，直到第十一个元素停止循环（输出元素截止到第十个）。</p><h3 id="-list-collection-array-data-structure-">列表（List）：集合（Collection）|数组（Array）|数据结构（Data Structure）</h3><p>设想一下你需要把整数1储存在一个变量中。但现在可能你想储存2，甚至储存3,4,5……</p><p>是否有一种方式可以避免将我所想要的所有的整数存在不计其数的变量当中？——确实有。</p><p>列表（List）这种集合就可以用来储存一系列的数值，例如上述你想要的整数集合。</p><pre><code class="language-python">my_integers = [1, 2, 3, 4, 5]
</code></pre><p>很简单——我们创建了一个数组（Array），并把它存在了<strong>my_integer</strong>当中。</p><p>现在你可能要问了：怎样才可以从数组中取一个数值呢？</p><p>问得好。列表中有个概念，叫index。列表中的第一个元素为index 0，第二个是index 1，依次类推。</p><p>更简单来说，我们可以用index来指代数组中的每个元素。</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/8a27349588041ec08d23adc6a577514631ebbc0d/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f312a52654d6b364e6767684c4949323076504436754e45412e6a706567" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f312a52654d6b364e6767684c4949323076504436754e45412e6a706567" width="600" height="400" loading="lazy"></figure><p>Python句法比较容易理解：</p><pre><code class="language-python">my_integers = [5, 7, 1, 3, 4]
print(my_integers[0]) # 5
print(my_integers[1]) # 7
print(my_integers[4]) # 4
</code></pre><p>如果不需要储存整数，而是要储存字符串，比如亲戚的名字，我家的亲戚名字如下：</p><pre><code class="language-python">relatives_names = [
  "Toshiaki",
  "Juliana",
  "Yuji",
  "Bruno",
  "Kaio"
]
</code></pre><p>跟储存整数句法一致。</p><p>我们刚学习了列表中的各个元素如何工作。但我还需要告诉你们如何向列表中添加元素（向列表添加一个事项）。</p><p>最常见的方法是运用append函数。我们一起来看看如何运用。</p><pre><code class="language-python">bookshelf = []
bookshelf.append("The Effective Engineer")
bookshelf.append("The 4 Hour Work Week")
print(bookshelf[0]) # The Effective Engineer
print(bookshelf[1]) # The 4 Hour Work Week
</code></pre><p>append函数特别简单，只需要将元素添加为append的参数（正如"The Effective Engineer"）。</p><p>有关列表的知识就说到这里。我们一起来看看另外一个数据结构。</p><h3 id="-dictioary-key-value-">字典（Dictioary）：键-值(Key-Value)数据结构</h3><p>现在我们知道列表用整数来索引。但是，如果我们不想用整数来索引，那我们可以使用其他的数据结构，例如数值、字符串等来进行索引。</p><p>我们一起来学习一下字典(Dictionary)数据结构。字典使用键-值(key-value)存储。具体使用方法如下：</p><pre><code class="language-python">dictionary_example = {
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}
</code></pre><p>元素key指向value。那运用key，就可以得到字典中的value。让我们试一下：</p><pre><code class="language-python">dictionary_tk = {
  "name": "Leandro",
  "nickname": "Tk",
  "nationality": "Brazilian"
}
</code></pre><p>我创建了一个关于我自己的一个字典，包括有我的名字、绰号和国籍。这些属性就是字典中的key。</p><p>我们刚已经学过了如何运用索引得到列表中的值，那我们也可以运用索引（即字典中的key）来得到字典中value的存放位置。</p><p>例子当中，我用存储在字典中的value输出了一个关于我的短语。很简单吧~</p><p>字典还有一个很酷的属性，就是value的值可变。在我创建的字典中，我想要增加我的年龄"age"作为一个key，并且存入我年龄的整数值。</p><pre><code class="language-python">dictionary_tk = {
  "name": "Leandro",
  "nickname": "Tk",
  "nationality": "Brazilian",
  "age": 24
}
</code></pre><p>现在key-value当中，key是字符串，value是整数。</p><p>跟列表一样，现在我们要学习如何向字典中添加元素。key指向value是字典的一大组成。向字典中添加元素时也是如此。</p><pre><code class="language-python">dictionary_tk = {
  "name": "Leandro",
  "nickname": "Tk",
  "nationality": "Brazilian"
}
dictionary_tk['age'] = 24
</code></pre><p>一点都不复杂：我们只需要在字典中设定一个value，并且对应一个key就可以了。</p><h3 id="--1">迭代：数据结构中的循环</h3><p>正如我们在Python基础<a href="https://medium.com/the-renaissance-developer/python-101-the-basics-441136fb7cc3">1</a>中学到的内容，列表迭代非常简单。我们这些用Python开发的程序员通常使用for循环。一起来做：</p><pre><code class="language-python">bookshelf = [
  "The Effective Engineer",
  "The 4-hour Workweek",
  "Zero to One",
  "Lean Startup",
  "Hooked"
]
</code></pre><p>所以我们输出了书架上的每一本书（但我们能做的远不止于此）。这就是Python——简单且直观。</p><p>对于哈希数据结构而言，我们也可以使用for循环，但同时我们应该用到key：</p><pre><code class="language-python">dictionary = { "some_key": "some_value" }
for key in dictionary:
    print("%s --&gt; %s" %(key, dictionary[key]))
</code></pre><p>这个例子就解释了如何在for循环中使用key。我们可以输出字典中的每个key以及其对应的value。</p><p>还可以使用iteritems方法。</p><pre><code class="language-python">dictionary = { "some_key": "some_value" }
for key, value in dictionary.items():
    print("%s --&gt; %s" %(key, value))
</code></pre><p>我们将这两个参数命名为key和value，但这不是必须。我们也可以有其他命名。比如说：</p><pre><code class="language-python">dictionary_tk = {
  "name": "Leandro",
  "nickname": "Tk",
  "nationality": "Brazilian",
  "age": 24
}
for attribute, value in dictionary_tk.items():
    print("My %s is %s" %(attribute, value))
</code></pre><p>可以看到，例子中我们用attribute替代了key，代码同样运行流畅。真棒！</p><h3 id="--2">类和对象</h3><h4 id="--3">理论先导：</h4><p>对象(object)代表了真实世界当中的实体，例如汽车、狗狗、自行车等。这些对象有两个主要特点：数据(data)和行为(behavior)。</p><p>汽车包含有数据，比如轮胎数量、车门数量、座位数量。汽车也有一定行为，例如他们可以加速，可以停下，可以显示燃油剩余量等等。</p><p>在面向对象的程序设计中，我们将数据看做属性(attribute)，将行为看做方法(method)。</p><p>数据→属性&amp;行为→方法</p><p>类从对象中抽象而来。真实世界当中，一种类型下有很多物体，比如汽车。所有汽车的制作过程基本一致，设计模型也相差无几，都有引擎、轮胎等等。每辆汽车都是同一批设计图纸的产物，有着相同的零部件。</p><h4 id="python-on">Python面向对象的程序设计模式：ON</h4><p>面向对象的程序设计语言——Python，有类和对象这两个概念。</p><p>类是对象的模板，是对对象的抽象。</p><p>所以，类就是一种模型，一种定义属性和行为的方式（正如理论部分所讲）。举个例子，车辆这种类就有它自己的属性，属性能够定义什么对象是车辆。轮胎数量、油箱类型、座位数量、最高时速等等，都是车辆的属性。</p><p>有了这些前提，我们一起来看看Python中类的表达句法：</p><pre><code class="language-python">class Vehicle:
    pass
</code></pre><p>我们用类语句来定义类。</p><p>对象是类的实体，是类的表现形式。通过命名类，我们可以创建实体。</p><pre><code class="language-python">car = Vehicle()
print(car) # &lt;main.Vehicle instance at 0x7fb1de6c2638&gt;
</code></pre><p>这里的car就是Vehicle类中的一个对象。</p><p>记住，我们的Vehicle类中有四个属性：车轮数量、邮箱类型、座位数量和最高时速。创建一种车辆对象时我们便设置好这些属性。所以这里，一开始我们就定义类来接收数据。</p><pre><code class="language-python">class Vehicle:
    def init(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
        self.number_of_wheels = number_of_wheels
        self.type_of_tank = type_of_tank
        self.seating_capacity = seating_capacity
        self.maximum_velocity = maximum_velocity
</code></pre><p><strong>我们运用了'init'这种构造方法。所以创建车辆对象时，我们可以便定义这些属性。设想，我们喜欢</strong>Tesla Model S,**，自然而然我们便想创建这样一种对象。这个对象有四个车轮，由电力驱动，有四个车座，最高时速可达250km，合每小时155英里。那我们就来创建这个对象：</p><pre><code class="language-python">tesla_model_s = Vehicle(4, 'electric', 5, 250)
</code></pre><p>属性包括四个车轮、用电驱动、五个车座、250km的最高时速。</p><p>所有属性都已经设置完毕。但是我们怎么获得这些属性的值呢？这就需要“向对象发送一条信息询问”，我们把这一过程称为“方法”(method)，也就是“对象的行为”。我们来做一下：</p><pre><code class="language-py">class Vehicle:
    def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
        self.number_of_wheels = number_of_wheels
        self.type_of_tank = type_of_tank
        self.seating_capacity = seating_capacity
        self.maximum_velocity = maximum_velocity

    def number_of_wheels(self):
        return self.number_of_wheels

    def set_number_of_wheels(self, number):
        self.number_of_wheels = number</code></pre><p><em>这个跟定义“方法”不太一样。这种情况下，“方法”作为参数运转。举个例子，设定车轮数量时，我们不是把“2”作为参数，而是把“2”赋值给“车轮数量”这一属性。而这也是写pythonic，getter和setter代码的一种方法。</em></p><p><em>当然“方法”也有其他用途，以"<strong>make_noise</strong>"方法为例：</em></p><pre><code class="language-py">class Vehicle:
    def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
        self.number_of_wheels = number_of_wheels
        self.type_of_tank = type_of_tank
        self.seating_capacity = seating_capacity
        self.maximum_velocity = maximum_velocity

    def make_noise(self):
        print('VRUUUUUUUM')</code></pre><h3 id="--4"><em>封装：隐藏信息</em></h3><p><em>封装机制限制对象数据和方法的直接访问。但同时，封装有利于数据（对象的方法）层面的操作。</em></p><p>_维基百科上说：“封装可以用来隐藏数据成员和成员函数。封装意味着对象<a>2的内部实现通常被隐藏，并由定义替代。”</a></p><p>对象的内部实现都被隐藏，只有对象本身可以和内部数据互动。</p><p>首先，我们需要理解公共(public)和非公共(non-public)实例变量以及方法是如何工作。</p><h4 id="--5">公共实例变量</h4><p>对于Python当中的类而言，我们在构造方法中预置一个公共实例变量，如下：</p><p>在构造方法内部：</p><pre><code class="language-python">class Person:
    def init(self, first_name):
        self.first_name = first_name
</code></pre><p>我们将"first_name"的值赋给公共实例变量。</p><pre><code class="language-python">tk = Person('TK')
print(tk.first_name) # =&gt; TK
</code></pre><p>在类当中，如果我们直接给first_name赋值：</p><pre><code class="language-python">class Person:
    first_name = 'TK'
</code></pre><p>那我们就不需要再给变量赋值，因为所有的实例对象都会有初始化的类属性——"TK".</p><pre><code class="language-python">tk = Person()
print(tk.first_name) # =&gt; TK
</code></pre><p>现在我们已经学过了如何使用公共实例变量和类属性。公共实例变量还有一个特点，就是可变。什么意思呢？就是我们的对象可以通过"Get"和"Set"变量值来管理自身变量值。</p><p>脑子里想象一个"Person"类，我们想要给这个类当中的"first_name"变量设定一个值：</p><pre><code class="language-python">tk = Person('TK')
tk.first_name = 'Kaio'
print(tk.first_name) # =&gt; Kaio
</code></pre><p>我们将"Kaio"赋值给"first_name"这个实例变量，实例变量随之更新。原因就在于，这是一个公共变量。</p><h4 id="--6">非公共实例变量</h4><p>We don’t use the term “private” here, since no attribute is really private in Python (without a generally unnecessary amount of work). — &nbsp;<a href="https://www.python.org/dev/peps/pep-0008/#designing-for-inheritance">PEP 8</a>因为Python（没有一大堆不必要的工作时）当中没有一个变量完全私有不公开，所以我们这里使用了非公共(non-public)这个词，而没用使用私有(private)这个词。<a href="https://www.python.org/dev/peps/pep-0008/#designing-for-inheritance">PEP 8</a></p><p>跟公共实例变量无异，我们也可以在构造方法和类当中定义非公共实例变量。句法差异在于：对于非公共实例变量而言，需要在变量名字前使用"<em>".</em></p><p><em>根据Python软体基金会<a href="https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references">4</a>，“Python中不存在“私有”(private)实例变量，除了在对象内部，否则不能得到私有实例变量。然而，Python中大多数代码都遵循一条惯例：无论是函数、方法或者数据成员，只有其名字前有一条下划线（例如"<em>spam</em>"_），它就可以被视为API（应用编程接口）的非公共部分。”</em></p><p><em>例子如下：</em></p><p><strong><code>class Person: def __init</code></strong><code>(self, first_name, email): self.first_name = first_name self._email = email_</code></p><p>看见"email"变量了吧，这就是定义非公共变量的方式。</p><p><em><code>tk = Person('TK', 'tk@mail.com') print(tk._email) # [[tk@mail.com][20]][5]_</code></em></p><p>我们可以获得并且更新非公共变量。非公共变量只是一种约定俗成，不应被当做API的非公共部分。</p><p>所以我们采用一种方法，可以让我们在类的定义中将非公共变量当做非公共部分。两个方法("email" &amp; "update_email")可帮助理解：</p><pre><code class="language-py">class Person:
    def __init__(self, first_name, email):
        self.first_name = first_name
        self._email = email

    def update_email(self, new_email):
        self._email = new_email

    def email(self):
        return self._email</code></pre><p>现在我们可以用那些方法更新并访问 <code>non-public variables</code>，如下：</p><pre><code class="language-py">tk = Person('TK', 'tk@mail.com')
print(tk.email()) # =&gt; tk@mail.com
# tk._email = 'new_tk@mail.com' -- treat as a non-public part of the class API
print(tk.email()) # =&gt; tk@mail.com
tk.update_email('new_tk@mail.com')
print(tk.email()) # =&gt; new_tk@mail.com</code></pre><ol><li><em>我们引入了一个新对象，包括"first_name"和"email"<a>tk@mail.com</a>。</em></li><li><em>我们用一种方法得到了非公共变量，输出了"email"。</em></li><li><em>我们试图在类之外设置一个新的"email"。</em></li><li><em>我们需要将非公共变量视作API的非公共部分。</em></li><li><em>运用实例方法更新了非公共变量。</em></li><li><em>大功告成！可运用助手方法(the helper method)在类中更新。</em></li></ol><h4 id="--7"><em>公共方法</em></h4><p><em>公共方法也可以在类之外使用。</em></p><pre><code class="language-py">class Person:
    def __init__(self, first_name, age):
        self.first_name = first_name
        self._age = age

    def show_age(self):
        return self._age</code></pre><p>棒极了！这样用没有任何问题。</p><h4 id="--8">非公共方法</h4><p>非公共方法无法在类之外使用。我们要用到同一个"Person"类，用下划线表示添加非公共方法"show_age"。</p><pre><code class="language-py">class Person:
    def __init__(self, first_name, age):
        self.first_name = first_name
        self._age = age

    def _show_age(self):
        return self._age</code></pre><p><em>我们可以得到并且更新非公共方法。这一方法是一个惯例，应该被视为API中的非公共部分。</em></p><p><em>下面的例子显示了非公共方法的使用过程：</em></p><pre><code class="language-py">class Person:
    def __init__(self, first_name, age):
        self.first_name = first_name
        self._age = age

    def show_age(self):
        return self._get_age()

    def _get_age(self):
        return self._age

tk = Person('TK', 25)
print(tk.show_age()) # =&gt; 25</code></pre><p><strong>这里我们既有非公共方法"<em>get_age</em>"，也有公共方法"show_age"。"show_age"可以在类之外由我们的对象使用，但是"<em>get_age</em>"只能在类定义（"show_age"方法之内）之内使用。需再次强调，非公共方法是一种约定俗成。</strong></p><h4 id="--9"><strong>封装总结</strong></h4><p><strong>封装可以确保对象的内部实现被隐藏。</strong></p><h3 id="--10"><strong>继承：行为和特点</strong></h3><p><strong>特定对象的共同点在于他们的行为和特点。</strong></p><p><strong>比如说，我继承了我父亲的一些特点和行为。特点方面，我有跟父亲一样的大眼睛和头发；行为方面，我跟父亲一样缺乏耐心，性格内向。</strong></p><p><strong>在面向对象的程序设计中，类可以从其他的类中继承共同的特点（即数据）和行为（即方法）。</strong></p><p><strong>下面这个例子可以用在Python中。</strong></p><p><strong>想象有一辆汽车。汽车的属性包括车轮数量、车座数量和最高时速。那“电动汽车”类就可以从常规“汽车”类继承一些共有属性。</strong></p><p><strong>__<code>class Car: def __init</code></strong><code>(self, number_of_wheels, seating_capacity, maximum_velocity): self.number_of_wheels = number_of_wheels self.seating_capacity = seating_capacity self.maximum_velocity = maximum_velocity</code>_</p><p>我们的“汽车”类就可以直接使用这些属性：</p><p><em><code>my_car = Car(4, 5, 250) print(my_car.number_of_wheels) print(my_car.seating_capacity) print(my_car.maximum_velocity)</code></em></p><p>开始后，我们就可以使用所有创建好的“实例变量”。</p><p>Python中，我们将父类(parent class)作为参数应用到子类(child class)中，好比“电动汽车”类可以从“车类”继承行为和特点。</p><p><em><code>class ElectricCar(Car): def **init**(self, number_of_wheels, seating_capacity, maximum_velocity): Car.**init**(self, number_of_wheels, seating_capacity, maximum_velocity)</code></em></p><p>不难吧。因为从“车”类继承过来的方法，我们无需再使用其他任何方法。验证一下：</p><p><em><code>my_electric_car = ElectricCar(4, 5, 250) print(my_electric_car.number_of_wheels) # =&gt; 4 print(my_electric_car.seating_capacity) # =&gt; 5 print(my_electric_car.maximum_velocity) # =&gt; 250</code></em></p><p>一个字：爽！</p><h3 id="--11">大概就这么多。</h3><p>总结一下我们学习的Python基础知识：</p><ul><li>变量如何工作</li><li>条件语句</li><li>while循环 &amp; for循环</li><li>列表：集合|数组</li><li>字典键-值集合</li><li>数据结构如何迭代</li><li>对象和类</li><li>属性作为对象数据</li><li>方法作为对象行为</li><li>如何运用Python中的getters setters和property decorator</li><li>封装：隐藏信息</li><li>继承：行为和特点</li></ul><p>祝贺你！你已经完成这一部分的Python学习！</p><p>如果你想学习完整的Python课程，学习更多的编程技巧，学习如何搭建项目，试着点击[<strong>One Month Python Bootcamp_</strong>]。期待看见你的身影☺~</p><p>想具体了解我的编程学习历程，可以关注我的网站<a href="https://medium.com/the-renaissance-developer"><strong>The Renaissance Developer</strong></a>。</p><p>希望你笑口常开，终身学习，坚持编程。</p><p>原文：<a href="https://www.freecodecamp.org/news/learning-python-from-zero-to-hero-120ea540b567/">Learning Python: From Zero to Hero</a>，作者：TK</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 优秀开发者应该具备的思维习惯 ]]>
                </title>
                <description>
                    <![CDATA[ “即使是做这些小变更也挺麻烦的” “变更之后，软件功能出问题了” “刚修复了这个 bug，却冒出来个新的” “写的是冗余代码” “代码过于复杂，不可能在这基础上添加新特性了” “把这些代码扔掉重写” 上面这些话，你觉得熟悉吗？ 每时每刻，在这个世界的各个角落，开发者们要么正说着这些话，要么正在思考这些问题，有的人甚至烦到想哭。这是为什么呢？ 这些都是开发者经常谈到的话题，也是每个开发团队都会经历的阶段。 很多微不足道的小问题慢慢地、逐渐地威胁到开发者的项目。它们并没有在一开始就张牙舞爪，造成毁灭性的后果，绝大多数都是长期潜伏造成危害，可能一年甚至几年你都不会看到危害。所以，当有人提到他们时，大部分情况下听起来都是无害的。甚至当你运行它们的时候，一切看起来也很正常。但随着时间推移，尤其是小问题越积越多，项目的复杂性与日俱增，终有一天你会成为下一个人人皆知的“事故”的主角。 如果你想避免事故发生，那就应该深入学习软件的基本准则，逐渐养成开发者应具备的思维基础。这可以帮助你在日常编程工作中更好地决策，让你开发的软件尽可能保持简洁，易于维护。 一个优秀开发者的思维模式包括 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/learn-the-fundamentals-of-a-good-developer-mindset/</link>
                <guid isPermaLink="false">5d9718ebfbfdee429dc5fef8</guid>
                
                <dc:creator>
                    <![CDATA[ Miaomiao Ma ]]>
                </dc:creator>
                <pubDate>Tue, 05 May 2020 10:11:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2019/10/123.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>“即使是做这些小变更也挺麻烦的”</p><p>“变更之后，软件功能出问题了”</p><p>“刚修复了这个 bug，却冒出来个新的”</p><p>“写的是冗余代码”</p><p>“代码过于复杂，不可能在这基础上添加新特性了”</p><p>“把这些代码扔掉重写”</p><p>上面这些话，你觉得熟悉吗？</p><p>每时每刻，在这个世界的各个角落，开发者们要么正说着这些话，要么正在思考这些问题，有的人甚至烦到想哭。这是为什么呢？</p><p>这些都是开发者经常谈到的话题，也是每个开发团队都会经历的阶段。</p><p>很多微不足道的小问题慢慢地、逐渐地威胁到开发者的项目。它们并没有在一开始就张牙舞爪，造成毁灭性的后果，绝大多数都是长期潜伏造成危害，可能一年甚至几年你都不会看到危害。所以，当有人提到他们时，大部分情况下听起来都是无害的。甚至当你运行它们的时候，一切看起来也很正常。但随着时间推移，尤其是小问题越积越多，项目的复杂性与日俱增，终有一天你会成为下一个人人皆知的“事故”的主角。</p><p>如果你想避免事故发生，那就应该深入学习软件的基本准则，逐渐养成开发者应具备的思维基础。这可以帮助你在日常编程工作中更好地决策，让你开发的软件尽可能保持简洁，易于维护。</p><p>一个优秀开发者的思维模式包括这些关键点：</p><h3 id="1-">1. 认真思考开发软件的目的</h3><p>首先，你应该明确开发软件的目的。事实上，所有的软件都只有一个目的：<strong>帮助人们</strong>。</p><blockquote>永远牢记：开发软件的目的不是为了展示你有多聪明。——<a href="https://link.zhihu.com/?target=https%3A//www.amazon.com/Code-Simplicity-Fundamentals-Max-Kanat-Alexander-ebook/dp/B007NZU848" rel="nofollow noreferrer">卡纳特-亚历山大《简约之美：软件之道》</a></blockquote><p>如果开发者不认真构思软件开发的目的，他们只能写出低级软件。何为低级软件？就是既无法给人们提供很多帮助，又很复杂的系统。</p><p>当你开发软件需要决策时，你应该牢牢记住这条准则——我们怎样才能提供帮助？你也这样来区分性能要求的优先级。</p><h3 id="2-">2. 明确软件设计的目标</h3><p><strong>每个程序员都是设计师。</strong></p><p>如果一个软件开发或者修改起来很难，那么开发者仅仅为了让软件能运行起来就得花费大量时间，也就没办法关注如何帮助用户。软件设计目的是让开发者的工作尽可能简单，这样他们才可以关注真正重要的事情。你将开发出帮助用户的软件，并且你的软件会长时间地给用户提供帮助。</p><p>但是，如果你设计出糟糕的系统，软件的使用寿命将会极短。 这就是软件设计目标的重中之重：</p><blockquote>设计出来的软件系统应该能让开发者快速完成开发并维护，这样软件系统才能——而且能——持续为用户提供帮助。——<a href="https://link.zhihu.com/?target=https%3A//www.amazon.com/Code-Simplicity-Fundamentals-Max-Kanat-Alexander-ebook/dp/B007NZU848" rel="nofollow noreferrer">卡纳特-亚历山大《简约之美：软件之道》</a></blockquote><p>两个关键点：设计需简洁，同时也要能给用户提供帮助。</p><h3 id="3-">3. 正确理解工作</h3><p>如果开发者不能充分理解他们的工作，他们大概率会开发出复杂的系统，然后就陷入恶性循环：错误理解导致软件系统复杂，复杂又导致更多的误解，循环往复。</p><p>事实上，提升设计技能最好的方式之一就是确保完全了解软件系统，了解开发过程中用到的工具。</p><blockquote>理解能力是区分优秀程序员和低级程序员的核心。——<a href="https://link.zhihu.com/?target=https%3A//www.amazon.com/Code-Simplicity-Fundamentals-Max-Kanat-Alexander-ebook/dp/B007NZU848" rel="nofollow noreferrer">卡纳特-亚历山大《简约之美：软件之道》</a></blockquote><p>低级程序员不理解他们正在做的工作，但是优秀程序员理解，事实就这么简单。</p><h3 id="4-">4. 保持简洁</h3><blockquote>至繁归于至简。——莱昂纳多·达·芬奇</blockquote><p>编程把复杂过程简单化。低级的开发者没能做到简单化，而优秀的开发者则竭尽全力让其他程序员看到尽可能简洁的代码。</p><p>优秀开发者做出的软件易于理解，所以改 bug 的时候也容易。</p><p>现在的情况是，开发者大都比较聪明，他们不想让别人觉得自己是傻子。比较讽刺的是，这种想法让他们有时会开发出不够简洁的软件。</p><p>他们会这样想：别的开发人员都懂我做出的东西，那我应该写一些难一点、不好理解的代码，这样才能显得我非常聪明。</p><p>这就是思维方式有问题造成的错误——不一定是编程技能不够。编程过程中大多数失败都是因为这种想法。</p><p>炫耀你的聪明才智并不能帮助他人。</p><p>其他开发者刚看到你的代码的时候都不能理解，他们得花时间去理解。</p><p>所以，你应该这样问自己：我是想让大家理解我的代码，让他们高兴，还是想看他们疑惑不解、垂头丧气的样子？</p><p>事实是，如果你的代码对其他开发者来说易于理解，这说明你做得非常好。</p><blockquote>大道至简。</blockquote><p>问题是：“得做到多简洁才算简洁？”</p><p>答案是：<strong>令人发指的简洁</strong>。</p><h3 id="5-">5. 控制复杂度</h3><blockquote>控制复杂程度是计算机编程的本质。——布莱恩·柯林汉</blockquote><p>很多软件失败的根源就是太复杂。起初，你要做的这个项目很简单，一个月就能完成。然后你提升了复杂度，项目周期增长到三个月。再然后你因为想实现其他目标而增加了特性。事情变得非常复杂，因为你无缘无故地增加了软件要实现的目的。这些追加任务需要六个月来完成。</p><p>但这还没有结束。</p><p>然后你把每个现有的功能变得更加复杂。这又需要九个月。然后，因为代码复杂，出现了很多 bug，那你就改 bug，但改的时候你没有考虑到这些改动会对其他部分造成什么样的影响。最后，哪怕是微小的变更也变得举步维艰。搞定一个 bug，却又出现新 bug。然后，你就成为了那些人们津津乐道的编程事故中的主角，不得不重写代码。</p><p>那么，你是怎样一步一步成为事故的受害者的？没人关心这个。你应该这样问：我怎样做才能避免成为编程事故的受害者？</p><p>很简单——首先，你应该确切地知道你开发的软件要实现什么样的功能以及软件的定义。其次，你写的每一部分代码都应该尽可能简洁。最后，讨论软件新增功能或变更需求时，你应该在现有的软件目的的基础上对新需求进行评估，并且提出问题。</p><p>作为一名开发者，对于不是必须的改变，你的首要反应应该是拒绝，这样你才能避免添加不必要的代码。但如果你被说服，软件确实需要变更，这时候你可以作出变更。</p><p>增加软件开发项目复杂度的因素有很多，上面列举的是最常见的。无论如何，你只需要遵循一条准则：</p><p><strong>你的首要目标是把控复杂，而不是创造复杂。</strong></p><h3 id="6-">6. 软件维护</h3><p>软件开发过程中，维护十分重要。不幸的是，开发者通常都忽略了维护的重要程度。快速编程和产品快速成型看起来都比代码维护重要。而这也是他们犯错误的地方：忽略了日后的代码维护。 软件总要做出一些变更，你不仅需要实现这些变更，还需要长时间地维护。作为一名开发者，考虑日后的变更维护工作也是你的主要工作职责之一。</p><p>所有变更都需要维护。</p><p>简洁度和复杂度关乎代码维护工作量。软件的每部分代码有多简洁，那么维护起来就有多轻松。反之，每部分代码有多复杂，维护起来相应地就涉及到更多工作量。</p><p>关于代码维护你应该遵循的准则是：</p><blockquote>减少维护代码的工作量比减少运行代码的工作量更重要。——<a href="https://link.zhihu.com/?target=https%3A//www.amazon.com/Code-Simplicity-Fundamentals-Max-Kanat-Alexander-ebook/dp/B007NZU848" rel="nofollow noreferrer">卡纳特-亚历山大《简约之美：软件之道》</a></blockquote><h3 id="7-">7. 保持一致</h3><p>保持一致是保持简洁的重要部分。如果你在某个地方以某种方式做一件事情，那你在每个地方都要这么做。举个例子，如果你命名一个变量为 “thisIsVariable”，那你所有的变量都要这样命名（otherVariable，anAnotherVariable 等等这些都不可以）。</p><p>代码不一致，就会给理解增加难度。不要逼着其他开发者在看你的软件代码每一个部分的时候，都得重新学习一遍你的代码规范。</p><p>在任何团队运动中，最好的团队的队员之间总是保持一致，并且能碰撞出火花。——罗杰·斯陶巴</p><h3 id="8-">8. 优先级评测</h3><p>开发软件需要做决策时，你怎么做的？</p><p>当你面对很多个有可能的方向，你怎么判断哪个方向最好？需要关注的是什么？你应该编写哪些特性？</p><p>以下三个要素会帮助你更好地决策，回答上面的问题。<a href="https://link.zhihu.com/?target=https%3A//www.amazon.com/Code-Simplicity-Fundamentals-Max-Kanat-Alexander-ebook/dp/B007NZU848" rel="nofollow noreferrer">《简约之美：软件之道》</a>这本书对这三个要素构成的等式有很好的解释：</p><ul><li><strong>做出变更的意愿度（D）</strong>：你有多想做出变更？</li><li><strong>变更的价值（V）</strong>：这个变更会带来多少价值或者对你的用户有多少帮助？</li><li><strong>做出变更需投入的精力（E）</strong>：变更需要额外付出多少？</li></ul><p>等式很简单：D=V/E</p><p>做出任何变更的意愿程度跟变更所能带来的价值成正相关，跟变更所需要的努力成负相关。</p><p>当你在区分工作的优先级时，你应该遵循这个准则：</p><p>选择那些”工作量小而价值高“的变更，而不是那些”工作量大而价值低“的变更。</p><h3 id="9-">9. 解决问题</h3><p>第一步是理解。一定要知道问题是什么。很多问题之所以难，是因为你不理解它们。把你的问题写下来，并且尝试向别人解释。</p><blockquote>如果你不能简洁地解释某些东西，那你就是不理解。——理查德·费曼</blockquote><p>第二步是计划。先不要采取行动，行动可以先放放，给大脑留些时间来分析问题、处理信息，但也不要在计划上耗费太长时间。</p><p><strong>三思而后行。</strong></p><p>第三步是分解问题。不要试图一次性解决一个大问题，否则你会被一个庞大的问题给吓倒。把问题分解成一个个小问题，而后逐个击破，每解决一个小问题，你就完成了大问题上的一环。</p><h3 id="10-">10. 追求优秀即可</h3><blockquote>完美是优秀的敌人。——伏尔泰</blockquote><p>不管是开始新项目或者在已有软件系统上增加新特性，开发者都倾向从一开始就把所有事项所有细节都计划得明明白白，想让第一版就完美。他们不是关注自己要解决什么问题，或者软件要怎样帮助大众，而是专注思考每个小细节，构思“如果怎么样，将会怎么样”这个问题，作出假设和预测。他们总是预测未来，沉迷于想象，太想让项目跟想象中一样完美。</p><p>事实上，他们不知道未来会发生什么，也不知道追求完美的代价有多高。</p><p>让我告诉你接下来会发生什么：</p><ul><li>你会写不需要的代码</li><li>你会因为写的不需要的代码增加项目的复杂度</li><li>你会显得平庸，毫无特色</li><li>你会超出项目截止期限</li><li>你将处理由于复杂度带来的很多 bug</li></ul><p>你想让这些发生吗？我觉得你不想。</p><p>那你应该做什么呢？</p><p>先写一个小产品，然后在其基础上改善和扩展。</p><p>你应该遵循增量设计法则。比如说，要设计一个计算器，你应该这么做：</p><ol><li>设计一个只能做加法运算的系统</li><li>运行系统</li><li>改善现有系统设计，使它也可以做其他运算</li><li>设计减法运算，重复步骤 2 和 3</li><li>设计乘法运算，重复步骤 2 和 3</li><li>设计除法运算，重复步骤 2 和 3</li></ol><h3 id="11-">11. 预测</h3><blockquote>预测只是事先设想未来会发生什么，它可能是基于事实和某种客观数据，也有可能是基于一种假设。</blockquote><p>开发者面临着未来可能要改写代码这一事实，他们就试图设计一个非常通用的解决方案，（他们认为）这足以解决未来可能出现的任何情况。</p><p><strong>方案太通用了就会包含很多不必要的代码。</strong></p><p>你不可能准确预测未来，所以不管你的解决方案有多通用，它都不可能足以满足未来你会遇到的各种新要求。最可能的是，你所设想的未来永远都不会来，那你写的要解决未来问题的代码只会增加复杂度，让代码变更变得困难，最终成为可能毁掉你的软件的累赘。</p><p>不要预测未来，做到能解决当下的问题就好。</p><h3 id="12-">12. 假设</h3><p>假设是什么？</p><p>假设是虽然你主观上认为这件事情是真的，但你并没有切实证据。</p><p>软件项目的杀手之一就是假设。我们一起来看看假设是如何毁掉一个项目的。</p><p>开发者知道，为了实现 X，他们得开发一个系统。然后他们想系统未来可能会要求他们做 Y，所以他们也做了 Y，写了成千上万行的代码来设计 Y。</p><p>后来，开发者发现当下的情况比之前他们假设的复杂得多，软件里面有很多不必要的代码。但是，因为每个部分都交织在一起，想把不必要的代码删除就非常麻烦。他们花了好几个月来重构代码，最终决定重写代码，这又要花费他们数月的时间。</p><p>要想避免这样的事故发生，你得遵循这个准则：</p><blockquote>代码设计应该基于你现在所知道的情况，而非你所假设的未来会发生的情况。——<a href="https://link.zhihu.com/?target=https%3A//www.amazon.com/Code-Simplicity-Fundamentals-Max-Kanat-Alexander-ebook/dp/B007NZU848" rel="nofollow noreferrer">卡纳特-亚历山大《简约之美：软件之道》</a></blockquote><h3 id="13-">13. 不要重复造轮子</h3><p>举个例子，如果在已经有一个完美的垃圾回收器存在的情况下，你要创造自己的垃圾回收器，你把本可以花在自己软件开发系统上的时间，花在了垃圾回收器上。</p><p>在以下几种情况下你也可以重复造轮子：</p><ul><li>你需要的东西当前不存在</li><li>现有轮子的技术太差，或者不能满足你的需求</li><li>现有的轮子没有被维护好</li></ul><p>这条准则很简单： 不要重复造轮子。</p><h3 id="14-">14. 拒绝</h3><p>作为一名开发者，你对变更需求的第一反应应该是“不”。</p><p>要拒绝增加更多的代码、更多的性能，除非对方让你相信这些要增加的代码是必须的。不必要的变更会增加软件的缺陷。</p><p>你如何知道这些变更是必须的呢？</p><p>返回去思考你开发软件的目的，想想区分优先级的那个等式。</p><pre><code class="language-text">From: rsc@plan9.bell-labs.com (Russ Cox)Subject: Re: [9fans] design clairvoyance &amp; the 9 way 来自： rsc@plan9.bell-labs.com (洛斯 考克斯)回复主题：设计透视
Date: Thu, 8 May 2003 04:05:31 GMT 日期：2003 年 5 月 8 日 星期四 04：05：31 格林威治时间
&gt; What does tomorrow's unix look like? 明天 Unix 系统会是什么样子？
I'm confident that tomorrow's Unix will look like today's Unix, only cruftier. 我相信跟今天差不多，甚至更糟。
Russ 洛斯</code></pre><h3 id="15-">15. 自动操作</h3><p>不要在重复性工作上浪费你的时间，设定好就不要管他们了，你睡觉的时候他们也可以继续运转。当你意识到你在重复做某些事情时，请记住这个准则：</p><p>如果可以自动操作，就让它自动操作。</p><h3 id="16-">16. 代码评估</h3><blockquote>按照代码行数估量编程进度就像按照重量估量飞机建造进度。——比尔·盖茨</blockquote><p>我发现有些开发者通过代码行数估量他们的软件质量，他们觉得代码行数越多，意味着他们做的工作很好。软件包含数十万行代码，这说明他们开发的软件特别宏大。</p><p>但问题来了：软件是真的大？还是有些地方出错了？</p><p>答案是，非常有可能是设计的某个方面出了问题。大多数简便的解决办法都不需要太多代码，你只需要简洁的代码，就能解决问题。</p><p>但我并不是说，代码总是越少越好。当你想多写点代码时，你总是很容易写出很聪明但别人很难理解的代码。你应该找到一个平衡。</p><p>最合适的代码是：代码不多，同时也易于理解，易于阅读。</p><h3 id="17-">17. 工作效率</h3><p>你如何估测你的工作效率？</p><p>是通过写代码的行数还是删代码的行数？</p><p>你的主要目标应该是，让你的代码库尽可能的小。问题不是“我怎样才能写出更多的代码”，而是“我怎样才能删掉更多的代码”。</p><blockquote>工作效率最高的一天，我删掉了 1000 行代码。——肯·汤普逊</blockquote><h3 id="18-">18. 测试</h3><p>什么时候你才能把记录和错误处理加到项目里面？</p><p>起初你就应该把记录加进项目里，这会及早帮你发现问题，节约时间。</p><p>我发现在测试代码时会出现很多问题。我给你举个例子，有两种情况： 一个简单的条件语句块，输入内容进入 if 语块，开发者把输入的内容给到软件，然后开发者测试语句，把代码传给源码控制，测试就算完成。那 else 语块呢？结果就是，软件在实际操作过程中，出现了大量错误。所以，在测试代码时，至少应该把所有的代码全部测试一遍。测试过程也要先局部，再整体。</p><p>有 bug 的时候，首先你应该让 bug 重现。你不能猜测 bug 的来源，然后按照你的猜测修补 bug，因为大部分情况下你都会犯错。你应该查看 bug 的来源，然后有的放矢。</p><p>你得是个可靠的成员，让团队中其他开发者看到你在源码控制中增添新代码时，都知道你的代码时经过测试的，是没问题的。</p><p><strong>未经测试的代码就是无效代码。</strong></p><h3 id="19-">19. 适当评估</h3><p>开发者需要正确评估项目难度。</p><p>通常他们都会低估项目的难度，而不是高估。他们会觉得这只是一小段代码或者只是一个简单的特性，低估工作量和所需时间，结果，项目就延期了。</p><p>分解任务，任务越小，评估起来就越容易。虽然你还是有可能评估错误，但相对于直接评估一个大项目，评估小项目的犯错概率会小很多。</p><p>记住：</p><p><strong>做任何事情所需的时间都比你想象的要多。</strong></p><h3 id="20-">20. 避免重写代码</h3><p>我相信，如果你遵循本文提到的软件开发准则，你不会有需要重写代码的时候。但是，如果你真的犯了错，发现自己要考虑重写代码时，你应该知道：</p><p><strong>在大多数情况下，重写代码是开发者的异想天开，而不是解决办法。</strong></p><p>为什么是异想天开？</p><p>因为，比起写代码，读代码更困难。这也是为何复用代码如此困难，为何我们在读其他开发者写的代码时，下意识会告诉我们，“扔掉这些，自己重新写”。</p><p>有很多情况会让你考虑从头开始写代码，你可以看看<a href="https://link.zhihu.com/?target=https%3A//medium.freecodecamp.org/lessons-learned-in-my-10-years-as-a-developer-3d33c8702828" rel="nofollow noreferrer">这些情况</a>。但是，我还是有个忠告给你：</p><p><strong>代码重构应该是第一选择。</strong></p><h3 id="21-">21. 说明和注释</h3><p>一个关于注释的误解是“开发者补充注释是要说明代码运行的目的是什么”，这是不对的。代码应该很容易理解，否则，就说明代码不易于阅读，还可以更简洁。</p><p>如果代码实在简洁不了，那就需要你加一些注释来解释为什么是这样。</p><p>注释的根本意图在于解释你为什么要这样写代码，而不是解释代码是做什么。如果你没有解释，其他的程序员可能就会迷惑不解，他们改写你的代码时，很可能就会改掉其中的重要部分。</p><p><strong>注释是为了解释为什么这样写，而非解释写的是什么。</strong></p><p>另一方面是写文档来阐述软件的设计结构、每个模块、每个组成部分，这非常重要，需要你站在更高的角度来审视软件。一份文档可以帮助新加入到团队中的开发者快速整体理解软件代码。如果开发者对软件的其他部分一无所知，他们在做自己负责部分的工作时很可能会犯错，还可能影响到其他部分。</p><h3 id="22-">22. 选对技术（比如：工具，库）</h3><p>首先，牢记这条准则：</p><p><strong>不要依赖外部技术，或者说，尽可能减少对它们的依赖。</strong></p><p>为何？因为外部技术是提升项目复杂度的另一个原因，它们可能毁掉你正在开发的东西，把一切变得更为复杂。如果你太依赖外部技术，那么你本身就是受限制的。如果技术本身就有一个大 bug 怎么办？你还得等他们的开发者把 bug 修复好才行。但如果你的项目核心就使用到了这个有 bug 的技术，那你可就束手无策了，可谓举步维艰。因此，为项目挑选适合的技术变得尤为重要。</p><p>在你开始使用某项技术时，你应该考虑如下几个因素：</p><ul><li>技术背后的开发是否积极？</li><li>技术的维护工作会持续进行吗？</li><li>抛开这个技术转向其他技术容易吗？</li><li>开发者社区对它评价如何？</li></ul><p>如果你可以很好地回答这些问题，那就降低了选到不合适技术的风险。</p><h3 id="23-">23. 自我发展</h3><p>不断学习，多尝试不同的编程语言和编程工具，阅读与软件开发相关的书籍，这些能提供给你另一种角度。每天一点小小的提升都会给你的知识和技能带来实质性影响。</p><p>思维开阔，不要太沉迷某个技术，要用真正需要的技术解决某个特定的问题，不要做类似于比较 Microsoft 和 Linux 的无用讨论。</p><p><strong>要知道，每个特定问题都有特定的解决办法。</strong></p><h3 id="24-">24. 远离个人英雄主义</h3><p>大多数情况下，适时放弃是一件好事。</p><p>举个例子，你觉得你可以在两个小时以内完成某个任务，但是，四个小时过去了，你还是只进行了四分之一。你的直觉反应是：我不能放弃，我都已经花了四个小时了。所以你继续发扬不撞南墙不回头的精神，发誓要完成任务。但很尴尬的是，任务好像就是完不成。你沉浸在自己的世界里，一心就想完成任务。</p><p><strong>不要执念太深，懂得及时止损，记得及时求助。</strong></p><h3 id="25-">25. 不要立即提问，适时求助</h3><p>当你要执行某个任务，但你不确定解决办法是什么，不要问别人你应该怎么做，至少不要遇到问题就立马问，而是要尝试你能想到的所有解决办法——这很重要，要跳出你所熟知的概念或语言的舒适圈。</p><p>当你自己实在想不出解决办法时，善用搜索工具！找到答案就大胆尝试，修改这些答案，看看能不能理解为什么这样做就可行，并把这些加入到自己的代码库中。</p><p>但是，寻求别人的建议也是很好的。</p><p>在你尽力尝试，找到了可行的解决办法之后，你去寻求一下别人的建议，让同事或者有经验的开发者看看你的代码有没有问题。</p><p>在这篇文章中，我尝试解释一个优秀的开发者应该有什么样的思维模式。<a href="https://link.zhihu.com/?target=https%3A//www.amazon.com/Code-Simplicity-Fundamentals-Max-Kanat-Alexander-ebook/dp/B007NZU848" rel="nofollow noreferrer">《简约之美：软件之道》</a>这本书对我自己的思考过程有很大影响，所以我参考了书中的一些部分。我读这本书的时候，时常会有“啊，我犯了这个错误，我犯了那个错误”这样的反应。我摘录了书里的部分内容，结合到这篇文章里。</p><p>我由衷地推荐你们阅读这本<a href="https://link.zhihu.com/?target=https%3A//www.amazon.com/Code-Simplicity-Fundamentals-Max-Kanat-Alexander-ebook/dp/B007NZU848" rel="nofollow noreferrer">《简约之美：软件之道》</a>。</p><p>感谢阅读，happy coding！</p><p>原文：<a href="https://www.freecodecamp.org/news/learn-the-fundamentals-of-a-good-developer-mindset-in-15-minutes-81321ab8a682/">https://www.freecodecamp.org/news/learn-the-fundamentals-of-a-good-developer-mindset-in-15-minutes-81321ab8a682/</a>，作者：Huseyin Polat Yuruk</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 自由职业开发者如何打造个人品牌 ]]>
                </title>
                <description>
                    <![CDATA[ 软件行业发展如火如荼，这对自由职业者来说有利有弊。 为什么说有弊呢？ 如果你是一名自由职业的开发者，那么你免不了要和其他自由职业开发者竞争，你能提供的技术服务可能他们也能提供。 根据美国劳工统计局调查显示，到 2026 年，计算机开发领域将增长 15%。同一份工作，企业可以选择雇用国外的报价更低的自由职业开发者。 那么，自由职业开发者应该怎么避免成为一个廉价劳动力，怎么才能不那么容易被取代呢？ 解决办法就是：打造个人品牌。 什么是个人品牌？ “个人品牌”向你的目标客户传达“你是谁”、“你是做什么的”以及“你跟同行业的自由职业者相比有哪些优势”。也可以这样理解：你有什么为人所熟知的长处，或者你想自己因为什么为人所熟知？ 为什么要建立个人品牌？ 很多人觉得，只有专家级的自由职业开发者才能建立个人品牌，其实不然。在当今这个竞争激烈的社会，建立个人品牌极其重要，主要有三个原因： 利于你在人群中脱颖而出 对于很多自由职业开发者来说，获取新客户的过程就像在一间拥挤且人声鼎沸的房间，朝人群大声喊叫。 通过强调你的专业知识和技能，阐述你的价值观以及其他能把你跟其他人区别开来的独特品 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/how-to-brand-yourself-as-a-freelance-developer/</link>
                <guid isPermaLink="false">5df894dfca1efa04e196a9ee</guid>
                
                <dc:creator>
                    <![CDATA[ Miaomiao Ma ]]>
                </dc:creator>
                <pubDate>Thu, 19 Dec 2019 09:26:59 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2019/12/1576747578984.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>软件行业发展如火如荼，这对自由职业者来说有利有弊。</p><p>为什么说有弊呢？</p><p>如果你是一名自由职业的开发者，那么你免不了要和其他自由职业开发者竞争，你能提供的技术服务可能他们也能提供。</p><p>根据美国劳工统计局调查显示，到 2026 年，计算机开发领域将增长 15%。同一份工作，企业可以选择雇用国外的报价更低的自由职业开发者。</p><p>那么，自由职业开发者应该怎么避免成为一个廉价劳动力，怎么才能不那么容易被取代呢？</p><p>解决办法就是：打造个人品牌。</p><h4 id="-"><strong>什么是个人品牌？</strong></h4><p>“个人品牌”向你的目标客户传达“你是谁”、“你是做什么的”以及“你跟同行业的自由职业者相比有哪些优势”。也可以这样理解：你有什么为人所熟知的长处，或者你想自己因为什么为人所熟知？</p><h4 id="--1"><strong>为什么要建立个人品牌？</strong></h4><p>很多人觉得，只有专家级的自由职业开发者才能建立个人品牌，其实不然。在当今这个竞争激烈的社会，建立个人品牌极其重要，主要有三个原因：</p><p><strong>利于你在人群中脱颖而出</strong></p><p>对于很多自由职业开发者来说，获取新客户的过程就像在一间拥挤且人声鼎沸的房间，朝人群大声喊叫。</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/970ac045bce5aa227dbd0efee5d4dfe48191c011/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f6d454651674833697a3169554a7a30317475626e6d6c446e56646c38366567587634774e" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f6d454651674833697a3169554a7a30317475626e6d6c446e56646c38366567587634774e" width="600" height="400" loading="lazy"></figure><p>通过强调你的专业知识和技能，阐述你的价值观以及其他能把你跟其他人区别开来的独特品质，来打造你的个人品牌，可以让你在人群中脱颖而出。</p><p><strong>把自己培养成某个领域的专家</strong></p><p>企业更喜欢跟在某个领域有专业度的人共事，因此，找准自己的定位，并把自己打造成该领域内颇受信任的专家，这点非常重要。</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/50e004c23316800beff22a10d298e87317edfb2e/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f65546a76667a2d52765675427855464b4e6d4d664f56426c47434763517470577577324b" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f65546a76667a2d52765675427855464b4e6d4d664f56426c47434763517470577577324b" width="600" height="400" loading="lazy"></figure><p></p><p>当你可以证明自己是这个领域的专家时，就算你的报价比竞争者的报价更高，企业方也不会介意考虑多花点钱来跟你一起工作。</p><p><strong>获得信任</strong></p><p>客户在决定雇用哪个自由职业开发者前，会做些调查。如果有人推荐你，那么潜在客户会觉得你更可靠，这样你就会慢慢获得更多机会。</p><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/1df78e45b0d5dea3f1db9dcdfc7e351bac3ac785/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f50324c785779725a4237413062797172467065764e594b46594d496a6a385179785a7a36" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f50324c785779725a4237413062797172467065764e594b46594d496a6a385179785a7a36" width="600" height="400" loading="lazy"></figure><p>现在你已经明白了建立个人品牌的重要性，以及它会给你的自由职业带来怎样的巨大转变，那我们进入正题吧。</p><p><strong>以下这 10 个可执行要点可以帮你建立个人品牌：</strong></p><ul><li>了解你的理想客户</li><li>打造卖点</li><li>不忘初心</li><li>分享你的故事</li><li>开始写博客</li><li>制作在线作品集</li><li>建立正确的联系</li><li>利用社交媒体</li><li>收集推荐语</li><li>做自己</li></ul><p>我们来仔细地谈谈每个要点。</p><h3 id="--2"><strong>了解你的理想客户</strong></h3><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/a3b57b85f778e47c73abcee62412d551b09b6c9b/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f574d3255384c6a71444b706132684f48454f367534496167584b4f396f786e6b51795534" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f574d3255384c6a71444b706132684f48454f367534496167584b4f396f786e6b51795534" width="600" height="400" loading="lazy"></figure><p>了解理想客户非常重要，这会指导你建立个人品牌，跟目标客户产生联系，让你的个人品牌具有吸引力。</p><p>一种方法是建立买家角色。买家角色是半虚构的，代表你的理想客户，需要基于全面的市场调查和权威人士的推测来建立。</p><p>大多数自由职业开发者会通过年龄、性别、收入、生意规模和成业等个人统计数据分析来做对于买家角色的分析。这样开始很好，但是要想建立深入人心的个人品牌，你需要做得更加深入。</p><p>关于理想客户或者市场你要想一下这几个问题：</p><p><strong>他们面临的最大的挑战是什么？</strong><br>作为自由职业开发者，你的目标是给理想客户提供解决办法，明白他们面临的挑战，在个人品牌建立时你就知道要强调哪些专业技能与知识。</p><p><strong>他们的目标是什么？</strong><br>除了“增加收入”这一目标以外，你要找到激励你的理想客户的核心价值和原则是什么。</p><p><strong>他们得知信息的渠道是什么？</strong><br>你的理想客户找到你的唯一方法是，在他们经常寻找解决问题的答案的地方，你的个人品牌有很强的存在感。他们用什么工具搜索？他们会在某个社交媒体寻找答案吗？你需要在这些地方提供他们需要的解决办法。</p><p><strong>他们订阅哪些博客和出版物？</strong><br>这些会让你对理想客户关注哪些性格特质更加了解。比如，如果你的理想客户关注了像 Neil Patel 一类的人，很可能你的客户更青睐细节导向的开发者。</p><p>这样你就更加明白你的理想客户希望在自由职业开发者身上看到哪些性格特质，同时，你也知道你应该跟哪些人建立联系。</p><p>使用一个像 <a href="https://www.makemypersona.com/" rel="nofollow">HubSpot’s persona generator</a> 这样的工具做起来更快捷。它会让你回答列表上的问题，帮助你创建买家角色。</p><h3 id="--3"><strong>打造卖点</strong></h3><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/ca36a90e856fb85e4f7ff96090a1cdb4b3a4ea70/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f504154437249416c7575483930693954304573635735706876564d733056426558745662" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f504154437249416c7575483930693954304573635735706876564d733056426558745662" width="600" height="400" loading="lazy"></figure><p>独特的卖点是给客户看的，能帮你脱颖而出。你的客户正面临某个具体挑战，你正好可以提供解决办法，这就是卖点。</p><p>以下是打造独特卖点的步骤：</p><p><strong>了解客户需求</strong></p><p>客户有时候自己都不清楚自己想实现什么样的功能，这就需要你深入挖掘一下，看客户的主要问题究竟是什么，他们想要解决什么，或者他们想要实现什么目标。</p><p><strong>提供解决方案</strong></p><p><strong>客户不是为你的服务买单，他们是为解决方案买单。</strong></p><p>那你就需要清楚地告知客户，你的服务和专业知识可以给他们提供解决方案。</p><p>突出以下要点：</p><ul><li>他们的销售可以增长多少</li><li>他们在多长时间内可以看到预期效果</li><li>他们的商业品牌会获得怎样的提升</li><li>预计会有多少客户增长</li></ul><p><strong>让你的服务必不可少</strong></p><p>你得对自己的专业技能和提供的服务有信心，要让潜在客户相信，你就是这个领域的专家，能给他们的生意带来积极影响，这很重要。</p><p>不要像别的自由职业开发者一样单纯地把一个项目看做一个项目，花点时间去了解一下项目的商业背景，它的目标是什么，价值观是什么。</p><p>要让客户明白，你的服务怎样帮他们达成目标，你跟你的竞争者又是如何的不同。</p><p>很多方式可以帮你准备专属你自己独特的卖点。</p><p>你可以使用一下“电梯演讲公式”。这个公式强迫你在 30 秒甚至更少的时间内阐述你的卖点。这特别重要，因为研究显示，你只有几秒钟的时间来吸引目标群体的关注。</p><p>电梯演讲从下面的公式开始：</p><p><strong>你能提供的解决方案+你的目标市场+你能提供的价值</strong></p><p>举个例子，以下是我给一个网站制造的卖点：</p><p>“我帮助程序员们成为成功的自由职业开发者，帮他们开发高效网站。”</p><p>我提供的解决方案是，帮助发起并发展一种自由职业业务。我的目标受众是开发者。我能提供给他们的价值是全职做自由职业工作，从而获得更多自由。</p><p>把这些具体应用到某个理想客户身上，你可能得说：</p><p>“高效率的网站和在线市场可以帮助医生接诊更多的病人，而我能开发这些网站和在线市场。”</p><h3 id="--4"><strong>不忘初心</strong></h3><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/9c612bc4caa69cce04225e6ac5d035d9f3937a31/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f4b34472d75695566623572374a6e625a7342477944515a38436373575855674e6a4f3756" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f4b34472d75695566623572374a6e625a7342477944515a38436373575855674e6a4f3756" width="600" height="400" loading="lazy"></figure><p>建立个人品牌时，别忘了一开始你为何决定成为一名自由职业开发者。比起仅仅为了赚钱这个目的，你的初心不仅非常有力量，也会给你提供更广阔的目标感，它会点燃你的激情，让你活力满满，保持专注。</p><p>更重要的是，你的初心能够将你跟潜在客户连接起来，让你在芸芸众生中脱颖而出。</p><p><a href="https://www.ted.com/talks/simon_sinek_how_great_leaders_inspire_action" rel="nofollow">Simon Sinek</a> 说：“人们不因你所做的而买单，他们因你所做的理由而买单（People don’t buy what you do. They buy why you do it）。”</p><p>问问你自己：</p><ul><li>作为一名自由职业开发者，你想实现什么目标？</li><li>是什么让你选择做自由职业开发者？</li><li>做这个是为了什么？自由？金钱？出发点是什么呢？</li></ul><h3 id="--5"><strong>分享你的故事</strong></h3><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/cb22c503aeadc68abcd2a1a2768e6c98fc4f342b/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f48506f35644c726b6576436d4e71514c794247436c5856485745305433576f4f6e743131" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f48506f35644c726b6576436d4e71514c794247436c5856485745305433576f4f6e743131" width="600" height="400" loading="lazy"></figure><p>可能这是最具挑战性的部分，因为分享故事意味着，你需要透明、诚实地呈现自己，也随时可能受到别人的攻击。</p><p>同时，我也要说，这个部分不是必须的，但在一些情况下对你十分有益。</p><p>人们因为故事而彼此连接，特别是那些跟我们有相似经历的人，会因为这些故事跟我们产生共鸣。分享故事也会给目标受众展示你的性格，双方的联系就会到达更深的层次。</p><p>写故事的时候，不要只关注你的成功、你已经取得的成就，要主动分享你的纠结煎熬、曾面对的挑战和遭遇的失败。</p><p>你呈现出的自己越真实，你的目标客户就会越信任你，这样才能开始建立关系。</p><h3 id="--6"><strong>开始写博客</strong></h3><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/05d2cc078bac100b427924c7aaf490f613a35723/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f644452315841377443716e4841624756734f754970446e655176674b6c68492d4e33646d" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f644452315841377443716e4841624756734f754970446e655176674b6c68492d4e33646d" width="600" height="400" loading="lazy"></figure><p>作为一名开发者，快速建立个人品牌的有效方式之一就是写博客。这不仅仅给你提供了分享知识和建议的机会，也帮助你在目标客户眼中树立了专家或者权威的形象。如果你能连续输出有价值的文章，以后他们有问题或者有需求的时候都会主动来求助你。</p><p>确保你发表的博客逻辑连贯，结构清晰，观点明晰，易于阅读。</p><h3 id="--7"><strong>制作在线作品集</strong></h3><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/d9c7020b69f9179d5affced83506aeda68e6027d/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f3869662d6354457949596a507262795652397061314e346c546d30444e64734a664f7278" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f3869662d6354457949596a507262795652397061314e346c546d30444e64734a664f7278" width="600" height="400" loading="lazy"></figure><p>要建立个人品牌，有一个可以展示自己专业能力的在线作品集十分重要，它可以帮你吸引潜在客户，让他们更深入地了解你，了解你做过什么，以及你可以怎样帮助他们。</p><p>在线作品集应该包括以下几个方面：</p><p><strong>一个可识别的域名</strong><br>既然是个人品牌，如果可以的话建议用你自己的名字做域名。其他的话，公司的名字也可以。</p><p><strong>一个专业的网站</strong><br>第一印象很重要。要用一个不仅看起来高大上，还要容易上手的网站。我喜欢自己写代码开发一个网站，但是有一个叫 Divi 的工具也不错。再有，不要忘记，配色也会影响人们的印象。</p><p><strong>一个 logo</strong><br>logo 不应该华而不实，它应该能代表你的身份，你做的事情以及你的价值观。</p><p><strong>之前的工作成果展示</strong><br>客户想看看你之前做过的工作，那你需要在档案里添加之前做过的成功的项目，这会帮你赢得客户的信任，可信度 UPUPUP~</p><p><strong>个性化展示</strong><br>存在感强，客户能看见你，才能尽早联系上你，一起工作。没有人喜欢跟存在感弱、看不见的人一起工作。</p><p><strong>结果导向</strong><br>列上你擅长的编程语言和工具是必要的，但是要注意不要把这些当作你的网站的焦点。</p><p>大多数客户不关心你知道的编程语言或者框架，也不关心你对他们了解多深入。他们只关心，你具备的知识能不能给他们带来生意上的增长。</p><p><strong>放上你的 GitHub 和 CodePen 账号链接，</strong>因为这些账号展示了你的知识和专业能力，他们会帮你增加在潜在客户心中的可信度。</p><p><strong>引导性话语</strong><br>不要想当然地认为你的潜在客户知道下一步你想让他们采取什么行动。在网站的不同地方放上引导性话语，这样可以促进网站游客转化为客户。</p><p><strong>联系方式</strong><br>我知道这个听起来无需赘言，但让人惊讶的是，就是有人会忽视具体的邮件地址或简单的联系方式。</p><h3 id="--8"><strong>建立正确联系</strong></h3><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/a00176bd8328234b6dfdda5715f54faac3ff4cfe/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f61346a4f2d78566135325a74344d4564754c4e427365465441674d73784e6d586e567458" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f61346a4f2d78566135325a74344d4564754c4e427365465441674d73784e6d586e567458" width="600" height="400" loading="lazy"></figure><p>全球著名的市场监测和数据分析公司 Nielsen 做的一项研究显示，82% 的人更倾向于考虑他们信任的人推荐的产品和服务。这就是为什么跟合适的人建立联系十分重要。</p><p>一种方式是参加你所在地区的商业聚会。你可以在很多很好的场合向当地商业群体介绍你从事网络开发或者市场咨询工作，这可以为你打开未来工作机会的大门。</p><p>有机会你也可以去参加潜在客户汇聚的产业大会和活动。</p><h3 id="--9"><strong>利用社交媒体</strong></h3><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/252171ffa6209f14d645f48b1a77e49a7d6e520e/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f4942476f504d2d347a3877325048746a32694e546d6b4a47577241704d55337468657a34" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f4942476f504d2d347a3877325048746a32694e546d6b4a47577241704d55337468657a34" width="600" height="400" loading="lazy"></figure><p>平均来看，每个人每天在社交媒体上要花费两个小时。在理想客户所在的社交媒体平台保持活跃可以增加他们找到你的机会。也就是说，要确保你提供的动态能给潜在客户提供价值。Bop Design 发布的调查显示，80% 的消费者会根据他们的社交媒体账户来评估品牌。</p><p>寻找一些你可以加入的相关小组，你可以在小组内部跟其他人分享专业知识，这能帮你赢得潜在客户的关注，最终他们可能会私下单独找到你。</p><h3 id="--10"><strong>收集推荐语</strong></h3><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/9676b509e294c6287abcd5b25f48a8ce5904c6ef/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f7a6c7637507876446a664b6b436e467a38354b4641653042506e62496b2d4f426749414b" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f7a6c7637507876446a664b6b436e467a38354b4641653042506e62496b2d4f426749414b" width="600" height="400" loading="lazy"></figure><p>除了各种各样的营销策略，没有什么能比得过口口相传的力量。你可以利用这种力量。建立个人品牌时，你可以在在线作品集中加入之前客户写的推荐语。</p><p>你需要主动跟当前客户和之前客户提出这个要求。在项目完成以后立即跟客户发一个邮件，这样做最省事。你只需要问他们：“您能给我写一个简短的推荐信吗？内容就是您觉得跟我一起工作怎么样。”</p><p>推荐信越多越好，你至少要拿到 3-6 封推荐信。</p><h3 id="--11"><strong>做自己</strong></h3><figure class="kg-card kg-image-card"><img src="https://camo.githubusercontent.com/87a633f5c9f6fd767ea55c4be74e8e4c2d4f6294/68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f4b4146706633746c366e762d3535313766515468425538437842676a48686e4876466331" class="kg-image" alt="68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f4b4146706633746c366e762d3535313766515468425538437842676a48686e4876466331" width="600" height="400" loading="lazy"></figure><p>记住：你自己就是你的个人品牌。</p><p>不要害怕展示自己真实的性格，因为这就是你，独一无二的你。对自己要诚实，不要弄虚作假，保持提升知识储备，不断改善跟客户的相处模式。</p><p>建立自己的自由职业开发者品牌耗费时间也耗费精力。善始，也要善终。要在自己的领域内成为专家，而不是廉价的劳动力。好运会不请自来。</p><p>希望这篇文章能帮到你，happy coding！</p><p>原文：<a href="https://www.freecodecamp.org/news/how-to-brand-yourself-as-a-freelance-developer-in-2019-and-beyond-78a5d58ecd29/">https://www.freecodecamp.org/news/how-to-brand-yourself-as-a-freelance-developer-in-2019-and-beyond-78a5d58ecd29/</a>，作者：<a href="https://www.freecodecamp.org/news/author/kyle/">Kyle Prinsloo</a></p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
