snapchat
by Jon Deng
乔恩·邓
About a year ago, while deployed to Iraq as an Army officer, I started coding for fun. (You can read the whole story here.) Well, after a lot of studying, I landed my first job as a software engineer at Snapchat (Snap) in Venice Beach.
大约一年前,当我作为陆军军官部署到伊拉克时,我开始玩得开心。 (您可以在此处阅读整个故事。)好吧,经过大量研究,我找到了第一家工作在威尼斯海滩Snapchat( Snap )的软件工程师。
The job search wasn’t easy. I faced a lot of rejections, false leads, and moments of doubt. But the experience helped me develop a mental framework for approaching activities that have a high probability of success over the long term, but a small probability of success on any given day — activities like searching for a first job as a software engineer.
找工作并不容易。 我面临许多拒绝,错误的线索和令人怀疑的时刻。 但是,这些经验帮助我开发了一种思维框架,以应对那些长期来看很可能成功的活动,但是在任何一天都不太可能成功的活动-例如寻找第一份软件工程师的活动。
Because finding my particular job was mostly due to a lot of luck (good timing, a fortuitous connection, a good year of funding for startups in Los Angeles), outlining the specific steps I took wouldn’t be super useful to you. That’s because I did the same things that everyone tells you to do:
因为找到我自己的工作主要是由于运气好(时间安排好,人际关系偶然,为洛杉矶的初创公司提供了不错的资金),所以概述我采取的具体步骤对您没有多大用处。 那是因为我做了所有人都告诉您的相同事情:
The actions that you take, and the emphasis you put on each one, will differ greatly depending on your personality and specific circumstances. This said, the mental framework I arrived at during my job search can help you, regardless of your circumstances.
这些动作, 你拿的, 你把每一个重点,将有很大的不同取决于你的个性和具体情况。 这就是说,无论您的情况如何,我在求职期间所建立的思想框架都可以为您提供帮助。
So I’m going to share the thought process that ultimately lead to my mental framework, while giving you a quick introduction to dynamic programming at the same time. I hope you find this useful ?!
因此,我将分享最终导致我的思想框架的思维过程,同时让您快速了解动态编程 。 希望这个对你有帮助 ?!
While searching for my first programming job, I read quite a few personal accounts of how other self-taught programmers and bootcamp grads found their first jobs. From their stories, the job search seemed like a very sequential model:
在寻找我的第一份编程工作时,我读了很多关于其他自学成才的程序员和Bootcamp毕业生如何找到第一份工作的个人记录。 从他们的故事来看,求职似乎是一个非常有序的模型:
In data structure terms, I pictured it as traversing through nodes of a Linked List.
用数据结构的术语,我将其描述为遍历链表的节点。
I think a common flaw when people recount their memories (especially if they’ve been working as an engineer for a little while), is that they place too much emphasis on cause-effect relationships between the specific actions they took and the outcome that occurred:
我认为人们在回忆自己的记忆时(特别是如果他们已经作为工程师工作了一段时间)的一个普遍缺陷是,他们过分强调自己采取的具体行动与所发生的结果之间的因果关系:
I did A, then B occurred. Therefore, A caused B.
我做了A,然后发生了B。 因此,A导致了B。
Because they have the benefit of hindsight, their outcome seems deterministic. If you only just follow the same steps, you will find a good job.
因为它们具有事后观察的优势,所以其结果似乎是确定性的。 如果仅遵循相同的步骤,您将找到一份好工作。
Yes. And no. From my experience, in the long term, if you’re really committed to programming and constantly pushing yourself to get better, you will eventually find a job worthy of your skills (regardless of whether you have a Computer Science degree from a certain school in Palo Alto). The demand for software engineers is real and only growing. But in the short term, the process is super random, and is based on lots of variables that you have no visibility on or control over: company hiring needs, market trends, what hip technologies companies are currently hiring for.
是。 和不。 从我的经验来看 ,从长远来看 ,如果您真的致力于编程并不断推动自己变得更好,那么您最终将找到一份值得您的技能的工作(无论您是否拥有某所学校的计算机科学学位)帕洛阿尔托)。 对软件工程师的需求是真实的,并且只会不断增长。 但是从短期来看 ,该过程是超级随机的,并且基于许多您无法查看或无法控制的变量:公司的招聘需求,市场趋势,公司目前正在招聘的时髦技术。
When I started searching for jobs in Los Angeles, I sent out a ton of applications, trying to find something — anything. I would have coded in exchange for free food and t-shirts if the anyone had offered me the opportunity. Here are some of the early responses I got:
当我开始在洛杉矶寻找工作时,我发出了很多申请,试图寻找一些东西- 任何东西。 如果有人给我机会的话,我本可以编码来换取免费的食物和T恤。 以下是我得到的一些早期回复:
You write nice clean Javascript code. And you were super friendly and we enjoyed talking to you. However, we didn’t see you coding as productively as we needed. To move forward with junior candidates, we need to see an exceptional strong point, and we didn’t see enough of such a strength with you at this point. This means that we can’t work with you.
您编写了不错的干净Javascript代码。 而且您超级友好,我们很高兴与您交谈。 但是,我们没有看到您需要的编码效率很高。 为了与初级候选人一起前进,我们需要看到一个非凡的优势,而在这一点上,我们还没有看到如此强大的实力 。 这意味着我们无法与您合作。
We all think very highly of you and each enjoyed interviewing you, with the strong belief that your drive, work ethic, and natural curiosity are exactly what we seek in a candidate. Unfortunately, given the timeline of where we are logistically, we are looking for someone with more current experience in front-end development.
我们都非常重视您,并且每个人都喜欢与您面谈,坚信您的动力,职业道德和天生的好奇心正是我们在求职者中所追求的。 不幸的是,鉴于我们在物流方面的时间表, 我们正在寻找在前端开发方面拥有更多最新经验的人员。
Sorry for all the delays. This process is more complicated than I had anticipated. I’ll update you sometime next week as we get closer to making a decision.
对不起,所有的延迟。 这个过程比我预期的要复杂。 我将在下周的某个时候与您联系,因为我们临近做出决定。
Then [silence] for many weeks.
然后[沉默]好几个星期了。
Well that was bananas. I did a coding challenge that took me 6 hours and the company can’t even send me a reply email?
那就是香蕉。 我进行了一次编码挑战,这花了我6个小时,而公司甚至无法给我发送回复电子邮件?
Getting each of these emails (and the numerous non-responses too) was a very painful experience for me. But never waste an opportunity to learn something useful from hardship. By showing you the thought process that my job search inspired, hopefully this article will give you a tool to optimize the choices you make during the job search, and give you inspiration to continue pushing toward your goal.
获得这些电子邮件中的每一个(以及众多无回应的邮件)对我来说都是非常痛苦的经历。 但是不要浪费机会从困难中学习有用的东西 。 通过向您展示我的求职启发的思维过程,希望本文将为您提供一个工具,以优化您在求职过程中做出的选择,并为您提供继续前进的灵感。
“Pain is inevitable, suffering is optional” -Haruki Murakami
“痛苦是不可避免的,痛苦是可以选择的”-村上春树
Let me illustrate the steps I took to get to my mental framework, using a variation of a common Computer Science interview question: the Knapsack problem.
让我用一个常见的计算机科学面试问题: 背包问题来说明为达到我的思想框架而采取的步骤。
**UPDATE: I put my code in a GitHub repo with a small test suite, allowing you to play around with the code and develop a solution yourself.**
**更新:我将代码放在带有小型测试套件的GitHub存储库中 ,使您可以随意使用代码并自行开发解决方案。**
Here is the problem:
这是问题所在:
You have a set of activities that you can choose to do to increase your chances of finding a job. Each activity takes a certain amount of time, but provides some amount of experience. We only have limited time to prepare for the job search, so we can’t do everything. Our goal is to maximize the amount of experience points by choosing the optimal set of activities.
您可以选择一系列活动来增加找到工作的机会。 每种活动都需要一定的时间,但是会提供一定的经验。 我们只有有限的时间来准备工作,所以我们不能做任何事情。 我们的目标是通过选择最佳的活动集来最大化经验值。
How do you write a function that will choose the optimal set of activities from a list of available activities and a limited amount of time?
您如何编写一个函数,该函数将从可用活动列表和有限时间中选择最佳活动集?
Restating the problem, you want to choose the set of activities that:
重现该问题,您想选择以下活动集:
The most intuitive way is to use the same algorithm we would utilize in daily life. We would try out various combinations of activities, checking to see if it met our constraint of fitting within a limited amount of time. We would keep searching through all possible combinations and choose the one that maximizes XP.
最直观的方法是使用与日常生活中相同的算法。 我们将尝试各种活动组合,并检查活动是否在有限的时间内满足了我们的适合性约束。 我们将继续搜索所有可能的组合,并选择能最大化XP的组合。
Here is the code for this algorithm:
这是此算法的代码:
The problem is that this approach is really complex with respect to time, meaning as the size of our input (number of activities we could possibly choose) increases, the amount of time it takes to calculate a solution increases at a much faster rate.
问题在于,这种方法相对于时间而言确实很复杂 ,这意味着随着我们输入的大小(我们可以选择的活动数量)增加,计算解决方案所花费的时间以更快的速度增加。
If we have 6 possible activities, we start by creating every possible combination with a single activity, giving us 6 combinations that contain one activity.
如果我们有6个可能的活动,那么我们首先创建一个可能的组合,并为每个活动提供6个包含一个活动的组合。
Then we have to create all possible combinations with 2 activities. For each of the original 6 combinations, we have to create a combination with each of the 5 remaining activities (you can only do each activity once).
然后,我们必须使用2个活动创建所有可能的组合。 对于原始的6个组合中的每个组合,我们必须与其余5个活动中的每个组合创建一个组合(每个活动只能执行一次)。
Then to create all possible combinations with 3 activities, we have to take each of our combinations containing 2 activities and create a combination with each of the 4 remaining activities.
然后,要创建包含3个活动的所有可能组合,我们必须采用包含2个活动的每个组合,并与其余4个活动中的每个创建一个组合。
Eventually we’ll have something that looks like (6 * 5 * 4 *3 * 2 * 1), which is O(n!). Also, because we sum all the items in each combination every time to calculate the total time and XP, our end time complexity is O(n! * n).
最终,我们将得到类似于(6 * 5 * 4 * 3 * 2 * 1)的值,即O(n!) 。 另外,由于我们每次都会对每个组合中的所有项目求和以计算总时间和XP,因此结束时间复杂度为O(n!* n) 。
Imagine that instead of running this algorithm on a computer that can execute trillions of operations a second, you have to run it on your limited brain, which actually takes 10 hours (in a very optimistic world) to do a side project to learn a new JavaScript MV* framework.
想象一下,您必须在有限的大脑上运行它,而不是在每秒可以执行数万亿次运算的计算机上运行此算法,实际上这需要10个小时(在非常乐观的世界中)才能完成一项附带项目以学习新知识JavaScript MV *框架。
And also instead of a choice of 6 activities, you have thousands of possible things you could be doing to prepare for job search. (Just look up “how to code” on Google).
而且,除了选择6个活动之外,您还可以做成千上万种可能的事情来准备求职。 (只需在Google上查找“如何编码”)。
It is completely impractical to try every possible combination of activities to prepare yourself for job search. The lesson from this example is there is an almost infinite amount of things you could be doing that will increase your chances of finding a job, but you can’t try all of them. You need a better method to determine your optimal set of activities.
尝试各种可能的活动组合来为求职做好准备是完全不切实际的。 这个例子的教训是,您可以做的事情几乎是无限的,这将增加您找到工作的机会,但是您不能尝试所有这些。 您需要一种更好的方法来确定最佳活动集。
Obviously, as programmers (and hackers ?), we’re going to want to optimize our current solution somehow.
显然,作为程序员(和黑客?),我们将要以某种方式优化当前解决方案。
Let’s try the BUD approach from Cracking the Coding Interview by Gayle McDowell (an awesome prep resource, even if your job interviewers never ask algorithmic questions).
让我们尝试一下Gayle McDowell 撰写的“ Cracking the Coding Interview”中的BUD方法(这是一个很棒的准备资源,即使您的工作面试官从不问算法问题)。
What Bottlenecks does our brute force solution have?
我们的强力解决方案有哪些瓶颈 ?
When looking for the bottleneck, we’re usually trying to identify the most complex part of the process, i.e. the n! part of of our O(n! * n) algorithm.
在寻找瓶颈时,我们通常试图确定过程中最复杂的部分,即n! O(n!* n)算法的一部分。
The bottleneck, or most complex part of our job search problem is the fact that we have to dynamically create many different combinations and try them out. Every time we add another option, we have many more possible combinations to try out.
求职问题的瓶颈或最复杂的部分是我们必须动态创建许多不同的组合并进行尝试的事实。 每次添加另一个选项时,我们都会尝试更多可能的组合。
Now I have to admit I kind of led you down a false road. My job search problem, as a variation on the Knapsack Problem, is part of a set of problems called NP-Hard. In short, problems are NP-Hard when there is no known efficient way to solve the problem, or verify that that a solution to a problem is correct. So unless you’re a world changing computer scientist, you’re probably not going to figure out an objectively efficient way to combine all the activities.
现在,我不得不承认,我有点带你走错了路。 我的求职问题是背包问题的一种变体,它是一系列称为NP-Hard的问题的一部分。 简而言之,当没有已知的有效方法来解决问题或验证问题的解决方案正确无误时,问题就是NP-Hard。 因此,除非您是一个改变世界的计算机科学家,否则您可能不会想出一种客观有效的方法来组合所有活动。
But that’s ok!!! Sometimes, in interviews and job search, we follow false leads. As long as we learn something from the process, we haven’t really wasted time. Even if we can’t find an overall efficient way to solve the problem, we can still find a more efficient way that we’re currently using.
但这没关系!!! 有时,在面试和求职中,我们会追踪错误的线索。 只要我们从过程中学到了什么,我们就没有真正浪费时间。 即使我们找不到解决问题的整体有效方法,我们仍然可以找到目前正在使用的更有效的方法。
So let’s move on.
因此,让我们继续前进。
2. Is my algorithm doing Unnecessary work or Duplicated Work?
2.我的算法执行不必要的工作还是重复的工作 ?
This is where we can make major gains on our solution.
这是我们可以从我们的解决方案中获得重大收益的地方。
One thing we should change is that for every possible combination, we have to iterate through all the activities in the set to calculate the total XP and total time from that set of activities. This is duplicated work, because we’re adding up the same values over and over.
我们应该改变的一件事是,对于每种可能的组合,我们都必须遍历集合中的所有活动,以计算出该组活动的总XP和总时间 。 这是重复的工作 ,因为我们要一遍又一遍地累加相同的值。
If we just saved the total XP and time of the combination in a variable, we could just add the XP and time of each new activity we add to to the total. This would take our solution from O(n! * n) to O(n!).
如果我们只是将组合的总XP和时间保存在一个变量中,则可以将添加到总计中的每个新活动的XP和时间相加。 这将使我们的解从O(n!* n)变为O(n!)。
This is helpful, but doesn’t fundamentally make our problem too much faster to run.
这很有用,但从根本上不会使我们的问题运行得太快。
What other optimization could we do?
我们还能做什么其他优化?
We’re also calculating a lot of combinations that could not possibly lead to a valid solution. This is unnecessary work.
我们还计算了许多可能无法得出有效解决方案的组合。 这是不必要的工作 。
For reference here is the list of activities again:
作为参考,这里再次列出活动:
const ACTIVITIES = [ {name: 'side-project', time: 10, xp: 12}, {name: 'algorithms', time: 3, xp: 7}, {name: 'networking', time: 1, xp: 0.5}, {name: 'exercise', time: 2, xp: 1.5}, {name: 'systems design', time: 4, xp: 4}, {name: 'making CSS codepens', time: 3, xp: 4}];
Let’s say we have 8 hours total to prepare for our job search. How would our brute force algorithm check combinations?
假设我们总共有8个小时的时间为求职做准备。 我们的蛮力算法将如何检查组合?
Based on the order of the ACTIVITIES array, we would first consider a set just including the side-project object. There is no valid solution containing the side-project activity because it takes 10 hours to do and we only have 8 hours total.
根据ACTIVITIES数组的顺序,我们首先考虑一个仅包含副项目对象的集合。 没有有效的解决方案包含副项目活动,因为这需要10个小时才能完成,而我们总共只有8个小时。
But our brute force algorithm (being brute force) doesn’t know that, and will then check every possible combination we can create with side-project.
但是我们的蛮力算法(即蛮力)不知道这一点,然后将检查我们可以使用side-project创建的每种可能的组合。
So it will check if [side-project, algorithms] is a valid solution. It is not.
因此它将检查[侧项目,算法]是否是有效的解决方案。 它不是。
And it will check if [side-project, algorithms, networking] is valid. It is not.
并且它将检查[副项目,算法,网络]是否有效。 它不是。
And it will check if [side-project, algorithms, networking, exercise] is valid. It is not.
并且它将检查[副项目,算法,网络,练习]是否有效。 它不是。
See how much unnecessary work we’re doing?
看看我们正在做多少不必要的工作?
What if we could give our algorithm a little bit of intelligence, so it can check if our current state (the activities we currently have selected) can lead to a valid solution? If the activities we currently have selected can lead to a valid solution (specifically, if our selected set of activities takes less or equal time than the total time we have as a parameter to the function) then we keep selecting new activities and checking if they’re valid.
如果我们可以给我们的算法一点智慧,然后可以检查我们当前的状态(我们当前选择的活动)是否可以导致有效的解决方案,那该怎么办? 如果我们当前选择的活动可以导致有效的解决方案(特别是,如果我们选择的活动集所花费的时间少于或等于我们作为该函数的参数所花费的总时间),那么我们将继续选择新的活动并检查是否有新活动是有效的。
If not, we stop and unselect the last activity we selected.
如果没有,我们将停止并取消选择我们选择的上一个活动。
For example, if we have 8 hours total, we will first check to see if a combination containing just side-projects can possibly lead to a valid solution. As we determined before, it cannot, because it takes up more time than we currently have.
例如,如果我们总共有8个小时,我们将首先检查看看仅包含侧项目的组合是否可能导致有效的解决方案。 正如我们之前确定的那样,它不能,因为它比现在占用了更多时间。
So we unselect side-projects, and try out different combinations starting with algorithms. By checking to see if our current selected activities could lead to a valid solution, we’re avoiding having to check any of the combinations containing side-projects, because they could not possible lead to a valid solution.
因此,我们取消选择副项目,并尝试从算法开始尝试不同的组合。 通过检查当前选择的活动是否可以导致有效的解决方案,我们避免了必须检查包含副项目的任何组合,因为它们不可能导致有效的解决方案。
This approach is called backtracking. We check to see if where we are could lead to a valid solution, if not, we go back one step and try to make a different choice.
这种方法称为回溯。 我们检查一下我们是否可以找到有效的解决方案,否则,我们将退后一步并尝试做出其他选择。
Here is the code:
这是代码:
This solution implements the two optimizations that we discussed earlier:
该解决方案实现了我们前面讨论的两个优化:
While backtracking saves a lot of work it doesn’t really reduce the overall runtime complexity of our algorithm. It’s still O(n!), because we’re still recursively checking most possible combinations.
回溯虽然节省了大量工作,但并没有真正降低我们算法的整体运行时复杂性。 它仍然是O(n!),因为我们仍在递归检查大多数可能的组合。
But implementing the backtracking algorithm has probably given you a clue on how to continue working on the problem. In the brute force solution, we had to assemble and check the entire combination for each possible combination. With backtracking, we get to check if the path we’re on will lead to a valid solution, before we assemble the entire combination.
但是实施回溯算法可能为您提供了如何继续解决该问题的线索。 在蛮力解决方案中,我们必须组装并检查每个可能组合的整个组合。 通过回溯,我们可以在组装整个组合之前检查所走的路径是否会导致有效的解决方案。
Hmmmmm…..
嗯...
Is there a way to consider only whether or not we should add another activity to our set? This would be a much easier problem than trying to create the entire combination at once. It would allow us to break up our hard problem (finding the optimal combination) to a series of smaller problems (deciding whether or not to add a single activity).
有没有办法只考虑我们是否应该向集合中添加另一个活动? 这比尝试立即创建整个组合要容易得多。 这将使我们能够将难题(找到最佳组合)分解为一系列较小的问题(决定是否添加单个活动)。
Dynamic programming is a method where we can divide our big optimization problem (what combination of activities should I choose?) into a series of manageable decision problems (should I include this activity in my optimal solution or not?). We divide and conquer.
动态编程是一种方法,可以将大的优化问题(我应该选择哪种活动组合?)划分为一系列可管理的决策问题(我应该将此活动包括在最优解决方案中吗?)。 我们分而治之。
Dynamic programming is a common way to solve NP-Hard problems like the Knapsack problem, and coincidentally also a good way to think about job search. It’s hard to determine what combination of activities will make you ready for job search. There’s no efficient way to find the optimal combination or to check if your current choice is optimal.
动态编程是解决诸如背包问题之类的NP-Hard问题的常用方法,同时也是思考求职问题的一种好方法。 很难确定哪种活动组合可以使您为求职做好准备。 没有找到最佳组合或检查当前选择是否最佳的有效方法。
But it’s a lot easier to break your time period down into individual days and weeks, and try to figure out which activities you should be doing for each small period of time.
但是,将时间段分成几天和几周要容易得多,并尝试找出在每个小时间段内应该执行的活动。
To solve our job search problem using dynamic programming, we break the problem up into a series of smaller problems (how do I optimize a smaller period of time?) and then take the solution from each of the smaller problems and combine them into a larger solution.
为了使用动态编程解决我们的求职问题,我们将问题分解为一系列较小的问题(如何优化较短的时间段?),然后从每个较小的问题中获取解决方案,并将它们组合为一个较大的问题解。
Sounds confusing? Let’s walk through it:
听起来令人困惑? 让我们来看一下:
const ACTIVITIES = [ {name: 'side-project', time: 10, xp: 12}, {name: 'algorithms', time: 3, xp: 7}, {name: 'networking', time: 1, xp: 0.5}, {name: 'exercise', time: 2, xp: 1.5}, {name: 'systems design', time: 4, xp: 4}, {name: 'making CSS codepens', time: 3, xp: 4}];
What’s the optimal solution if we have a total time of t=0 (zero) to prepare?
如果我们准备的总时间为t = 0(零),那是最佳解决方案?
If we have zero time, we can’t do any activities, so return an empty set, [].
如果我们的时间为零,那么我们将无法进行任何活动,因此请返回一个空集[] 。
Ok, now what’s the optimal solution is we have a total time of t=1?
好的,现在的最佳解决方案是总时间为t = 1?
First, let’s see what activities are possible to do: we can’t do a side-project (time t=10) or study algorithms (time t=3). The only thing we can do is networking (time t=1).
首先,让我们看看可以进行哪些活动:我们无法进行边际项目(时间t = 10)或研究算法(时间t = 3)。 我们唯一能做的就是联网(时间t = 1)。
So we need to decide if adding networking to the optimal solution for time t=0 will lead to an optimal solution.
因此,我们需要确定在时间t = 0时将网络添加到最佳解决方案是否会导致最佳解决方案。
If we add networking, we come out with a total XP of 0.5, not bad.
如果添加网络,则总XP为0.5,还不错。
If we don’t add networking, we can’t really do anything else, so we come out with a total XP of 0.
如果不添加网络,那么我们将无能为力,因此我们得出的总XP为0。
0.5 is still better than 0, so if we only have a total time of t=1, we should do networking. The optimal solution for time t=1 is [networking]
0.5仍然比0好,因此,如果我们只有总时间t = 1,则应该进行联网。 时间t = 1的最佳解决方案是[联网]
What’s the optimal solution for time t=2?
时间t = 2的最佳解决方案是什么?
What activities are possible with time t=2, that we haven’t already considered? Just exercise.
我们尚未考虑的时间t = 2可能发生什么活动? 只是运动。
If we choose to add exercise, which takes time t=2, we no longer have any time to do anything else, so our solution is [exercise], which leads to 1.5 XP.
如果我们选择增加运动,这需要花费时间t = 2,那么我们将不再有时间做其他任何事情,因此我们的解决方案是[运动],得出1.5 XP。
We compare the optimal solution including exercise (which leads to 1.5XP) and the optimal solution not including exercise (which leads to 0.5XP). Since the solution containing exercise is better, we choose that one (In real life, I also feel that with very limited time, some self-care is always more useful than more prep ?).
我们比较了包括运动的最佳解决方案(导致1.5XP)和不包括运动的最佳解决方案(导致0.5XP)。 因为包含运动的解决方案更好,所以我们选择其中一种(在现实生活中,我也觉得在很有限的时间里,一些自我护理总是比准备更有用?)。
Now here is where it gets really interesting: What’s the optimal solution for time t=3?
现在,这里是它得到真正有趣的: 什么是 时间t = 3的最佳解决方案?
Again, what activities are possible for time t=3?
同样,在时间t = 3时可能进行哪些活动?
We have the option to choose from [algorithms, exercise, networking].
我们可以选择[算法,练习,网络]。
If we choose algorithms which takes time t=3, we have no time to do anything else, so one possible solution is [algorithms].
如果我们选择需要时间t = 3的算法 ,那么我们就没有时间做其他任何事情,因此[算法]是一种可能的解决方案。
If we choose exercise which takes time t=2, we have t=1 time left to do something else? How do we know what to choose for the remaining time?
如果我们选择运动这需要时间t = 2,我们有T = 1周时间留给别人做一些事情? 我们如何知道剩余时间要选择什么?
We know the optimal solution for time t=1, is [networking], so we don’t have to calculate it again. We know we can’t do better than the optimal solution for time t=1.
我们知道时间t = 1的最佳解决方案是[网络], 因此我们无需再次计算。 我们知道,对于时间t = 1,我们不能做得比最优解更好 。
So one possible solution is [exercise, networking].
因此,一种可能的解决方案是[运动,网络]。
Again we compare all the possible solutions and see that the best we can do is [algorithms].
再次,我们比较了所有可能的解决方案,发现我们所能做的最好的就是[算法]。
This is the basic structure of a dynamic programming solution: at each amount of time, we test the decision of whether or not to add a specific activity. We compare all possible solutions, and figure out the optimal one.
这是动态编程解决方案的基本结构:在每个时间段,我们都会测试是否添加特定活动的决策 。 我们比较所有可能的解决方案,并找出最佳解决方案。
Solutions for greater amounts of time build upon the optimal solutions for the same problem with a smaller amount of time. This allows us to call the dynamic programming function recursively.
较长时间的解决方案以较少时间的相同问题的最佳解决方案为基础。 这使我们可以递归调用动态编程函数。
For my example I chose to sort the array of activities by the time it takes to complete them (least to greatest). This allows us the quickly determine which items are possible in the given time because they are sorted by time.
在我的示例中,我选择按完成活动所需的时间对数组进行排序(从最小到最大)。 这使我们能够快速确定在给定时间内哪些项目可行,因为它们是按时间排序的。
Below is the code:
下面是代码:
Wooooo! If you made it through that example the first time, then you’re a way faster learner than I am. I hope it was an interesting in finding alternate ways to solve hard algorithmic questions!
! 如果您是第一次完成该示例,那么您的学习速度将比我快。 我希望找到解决硬算法问题的替代方法会很有趣!
Finally, what is the purpose of this series of three examples you might ask?
最后,您可能会问这三个示例系列的目的是什么?
Not only did I stealthily give you some practice working on a question very similar to the ones you might be asked in technical interviews, I showed you the steps that I took to come to my mental framework.
我不仅偷偷地给了您一些练习,以解决与技术面试中可能会问到的问题非常类似的问题,而且还向您展示了我进入心智框架所采取的步骤。
There are an almost infinite combinations of activities you could be doing, and there’s no efficient way to determine the optimal set of activities you should do. A lot of paths don’t lead to a valid solution, just like a lot of job applications and interviews won’t lead to a job.
您可能要进行的活动几乎是无限的组合,并且没有有效的方法来确定您应该执行的最佳活动集。 许多途径并不能带来有效的解决方案,就像许多工作申请和面试不会带来工作一样。
You could try every possible combination of job search activities (brute force), but since we are human beings with finite time, this isn’t an efficient way to arrive at our goal.
您可以尝试各种可能的求职活动(蛮力)组合,但是由于我们是时间有限的人,因此这不是达成目标的有效方法。
We could optimize our approach by evaluating at each step whether or not our approach will lead to our goal (backtracking). For example, if we are constantly reaching out to third-party recruiters to help us find job leads, and the recruiters haven’t been very helpful in generating interviews, maybe we should backtrack and consider a different activity.
我们可以通过在每个步骤中评估我们的方法是否会实现我们的目标(回溯)来优化我们的方法。 例如,如果我们一直在与第三方招聘人员联系以帮助我们找到工作机会,而招聘人员在进行面试方面并不是很有帮助,那么也许我们应该回头考虑其他活动。
Lastly, since job search is not a one day affair, we could try to optimize each day and combine days together (dynamic programming). This way we have a manageable problem to deal with (should I study algorithms today?) versus a really hard one (what should I do for the next month to prepare myself for job search?).
最后,由于求职不是一日游,因此我们可以尝试优化每一天并结合在一起(动态编程)。 这样,我们就可以解决一个可管理的问题(我今天应该学习算法吗?),而不是一个非常困难的问题(下个月我应该怎么做才能为找工作做准备?)。
Finally, I just want to point out that with all 3 approaches, even though they were not objectively efficient, we did eventually reach a solution. While in the middle of job search, it’s really important to remember that in the long term, you will achieve your goal, and to keep pushing forward each day.
最后,我只想指出,尽管这3种方法客观上都不高效,但我们最终还是找到了解决方案。 在求职过程中,切记从长远来看,您将实现自己的目标,并每天不断前进,这一点非常重要。
I’m going to succumb to my temptation to give you two pieces of advice from my experience.
我将屈从于我的诱惑,从我的经验中给您两个建议。
If you’re looking for your first programming job, I hope reading this was useful or at least inspirational for you — look, a talentless duffer like me found a great job! Good luck out there and I’d like to close by sharing the best piece of advice given to me during my job search:
如果您正在寻找自己的第一份编程工作,我希望阅读这篇对您有用或至少鼓舞人心-看起来,像我这样的无才干的傻瓜找到了一份好工作! 祝你好运,我想在求职时分享给我最好的建议,以结束我的生活:
“Don’t worry about whether you’re good enough, worry about whether you like programming and whether you’re willing to work hard enough. If you do those two things, you’ll make it.” — paraphrased from Edgar Pabon on the Breaking Into Startups podcast
“不必担心您是否足够出色,不必担心您是否喜欢编程以及是否愿意努力工作。 如果您做这两件事,就会成功。” —摘自Edgar Pabon在Breaking Into Startups播客中的演讲
Thanks for reading, and good luck with your job search!
感谢您的阅读,并祝您工作顺利!
翻译自: https://www.freecodecamp.org/news/a-dynamic-framework-for-finding-your-first-programming-job-b4eb0605b4f3/
snapchat