面试 技术 教训
It was almost like a dream. I had taken 6 months off to go all in on coding and moving to Australia with my girlfriend, when I finally returned to Norway — and a job.
这几乎就像一个梦。 我休假了6个月,全心全意地编写代码,并与女友一起搬到澳大利亚,最后我回到挪威,找到了一份工作。
It almost went without a hitch. I had it all. I’ll start by providing you a bit of my entrepreneurial background.
几乎没有障碍。 我都拥有 首先,我将为您提供一些我的创业背景。
I spent the last 6 months tirelessly working on my portfolio and personal projects. Most notably, I created CryptoDasher, a tool for tracking Crypto currencies and portfolio values in real time. I also submitted an entry to a web design contest for a Chinese blockchain company called Loopring.
在过去的6个月中,我不懈地致力于我的投资组合和个人项目。 最值得注意的是,我创建了CryptoDasher ,该工具可实时跟踪加密货币和投资组合价值。 我还提交了一个名为Loopring的中国区块链公司的网页设计竞赛的参赛 作品 。
I felt ready. I applied for a frontend developer job with a large consulting company in Norway, and I caught their attention — or at least I thought so.
我准备好了 我在挪威的一家大型咨询公司申请了前端开发人员的工作,引起了他们的注意-至少我是这么认为的。
After passing a home assignment and first round interview, I was invited for the technical interview.
通过家庭作业和第一轮面试后,我被邀请参加技术面试。
The main event.
主要事件。
I was nervous.
我很紧张
How do you prepare for the technical interview? I asked myself. I asked around and searched the internet like crazy. I watched mock interviews on YouTube. Here are some of the resources I used:
您如何为技术面试做准备? 我问自己。 我四处询问并疯狂地搜索了互联网。 我在YouTube上观看了模拟采访。 这是我使用的一些资源:
Cracking the front-end interview (freeCodeCamp Medium Article)
破解前端面试 (freeCodeCamp中等文章)
David Shariff’s take on Preparing for a Front-End Web Development Interview in 2017
David Shariff 在2017年进行前端Web开发面试的准备工作
10 Interview Questions Every JavaScript Developer Should Know
I spent hours and hours slaving over this material, trying to prepare myself as best as I could. I wouldn’t feel good about myself if I didn’t do all I could before the interview, as I’m sure you understand.
我花了几个小时来研究这些资料,尽我所能地做好自己的准备。 如果您在面试之前没有全力以赴,我不会对自己感到满意,我相信您会理解的。
The day of the interview arrived.
面试的日子到了。
I had been home for 4 days. After a 36 hour flight from Australia, I was still waking up at 5 AM in the morning each day.
我已经待了四天了。 从澳大利亚出发36个小时的飞行之后,我仍然每天早晨5点起床。
That day I woke at 4 AM.
那天我早上4点醒来。
Still scared, but curiously, excited as well.
仍然很害怕,但奇怪的是,他也很兴奋。
I met the interviewer in the lobby of the company, and we went up to their offices.
我在公司大厅遇到了面试官,然后我们去了他们的办公室。
We had a nice chat and started connecting immediately. I’m good at soft skills, so I was hoping to demonstrate that strength early on. We met up with another interviewer shortly and proceeded to the meeting room.
我们进行了愉快的聊天,并立即开始连接。 我擅长软技能,所以我希望尽早展现这种力量。 我们很快与另一位面试官会面,然后进入会议室。
The beginning of the interview went very well. We each introduced ourselves, and they started asking me some questions about my background. I was asked what I thought was the most difficult part about beginning to code, what kind of technology I’d like to learn, what kind of technology I’d like to teach others, and what I find exciting about it.
面试的开始非常顺利。 我们每个人都作了自我介绍,他们开始问我一些有关我的背景的问题。 有人问我,关于开始编写代码最困难的部分是什么,我想学习哪种技术,我想教别人什么样的技术,以及让我感到兴奋的地方。
At this point I felt the interview was going great. I was curious to learn more about the company and I felt I connected with my interviewers.
在这一点上,我感到采访进行得很顺利。 我很好奇要了解有关该公司的更多信息,我感到自己与面试官联系在一起。
Then the technical part began.
然后技术部分开始了。
First, I was asked to explain my code from the home assignment. The assignment was to create pagination for a dataset, and display it in a list. I had written it using React, and I started to go through the code. As we walked through the code, my interviewers would ask me questions about it. I’ll try to outline the questions below and what I think the interviewers were after.
首先,我被要求从家庭作业中解释我的代码。 任务是为数据集创建分页,并将其显示在列表中。 我已经使用React编写了代码,然后开始遍历代码。 当我们遍历代码时,面试官会问我有关此问题。 我将尝试概述以下问题以及我认为面试官的追求。
Do you know what unit testing is? What part of the code could be unit tested?
您知道什么是单元测试吗? 代码的哪一部分可以进行单元测试?
In all honesty, I think I answered this wrongly. A unit test is a piece of code that verifies that a unit or a specific part of the source code performs its intended purpose without unwanted side effects. I don’t remember what I answered, but I might have mixed it up with integration testing. I did have some knowledge of unit testing and TDD before the interview, but in the heat of the moment it may have eluded me.
老实说,我想我回答错了。 单元测试是一段代码,它可以验证源代码中的某个单元或特定部分是否达到了预期的目的而没有不良副作用。 我不记得我回答了什么,但是我可能会将其与集成测试混在一起。 在面试之前,我确实对单元测试和TDD有一定的了解,但是在此刻最热的时候,这可能使我难以理解。
After some discussion back and forth, I concluded that I could test the pagination function, as it was responsible for most of the logic in the program.
经过反复讨论,我得出结论,我可以测试分页功能,因为它负责程序中的大多数逻辑。
How would you improve the program?
您将如何改进该程序?
I found this question slightly confusing. When I delivered the home assignment (weeks ago), I was asked to include a list of things I could improve about the program. Assuming the interviewer already knew about those, I struggled to find other areas of improvement than those I had already included.
我发现这个问题有些令人困惑。 当我(数周前)完成家庭作业时,我被要求提供一份我可以对该程序进行改进的事项清单。 假设面试官已经知道了这些,我就很难找到除我已经包括的其他方面的改进。
It soon became clear to me that the interviewer was interested in hearing about the things that I had already mentioned in my email, and so I started mentioning all those points - error handling, mobile optimization, user feedback while Ajax call is loading, and page management in the event of a large dataset.
我很快就意识到,面试官有兴趣了解我在电子邮件中已经提到的内容,因此我开始提及所有这些要点-错误处理,移动优化,加载Ajax呼叫时的用户反馈以及页面大型数据集的情况下进行管理。
Do you know what BEM is? Is that BEM you are using in your code?
您知道什么是BEM吗? 您在代码中使用的是BEM吗?
I answered that I knew what BEM is. It’s a naming convention for working on CSS projects and stands for Block, Element, Modifier. I also answered that I was inspired by BEM in my CSS class naming, but that it wasn’t exactly BEM, as it didn’t follow all of the BEM rules.
我回答说我知道BEM是什么。 这是用于CSS项目的命名约定,代表Block,Element,Modifier。 我还回答说,我在CSS类命名中受到BEM的启发,但是它并不是完全BEM,因为它没有遵循所有BEM规则。
How would you make this site mobile friendly?
您如何使该网站移动友好?
CSS Media queries. That’s the main one here. They wanted to know that I knew how to work with media queries to make sites responsive.
CSS Media查询。 那是这里的主要。 他们想知道我知道如何使用媒体查询来使网站响应。
So far. So good. I felt I answered the questions fairly competently, although I needed to discuss the questions somewhat before understanding what exactly the interviewer was getting at.
至今。 这么好。 我觉得我相当称职地回答了这些问题,尽管我需要在了解面试官的确切意思之前先讨论一下这些问题。
编码挑战 (The coding challenge)
Then they asked me to extend the functionality. I was asked to implement a sorting mechanism that would take the paginated dataset and rearrange them by name and numbers. I was given a few minutes to think about the problem.
然后他们要求我扩展功能。 我被要求实现一种排序机制,该机制将采用分页的数据集并按名称和数字重新排列它们。 我花了几分钟时间考虑这个问题。
I asked some clarifying questions, like whether or not I was supposed to use the built in JavaScript sort function, or build my own (as we’ll see later, this was a big mistake). The paginated data exists as an array of objects where each object has a data array with 20 objects that represent each item in the list. I came up with the following algorithm:
我问了一些澄清的问题,例如是否应该使用内置JavaScript排序函数,还是构建自己JavaScript排序函数(我们将在后面看到,这是一个很大的错误)。 分页数据以对象数组的形式存在,其中每个对象都有一个数据数组,其中有20个对象代表列表中的每个项目。 我想出了以下算法:
- Combine each pagination objects data array into a new array. 将每个分页对象数据数组合并为一个新数组。
- Sort the new array 排序新数组
- Paginate the sorted array and set the state of the component to the newly sorted array. 对排序后的数组进行分页,并将组件的状态设置为新排序后的数组。
It was a good algorithm. And I was quick to figure out what to do. The only problem now was implementing it. Here’s where I made mistakes.
这是一个很好的算法。 而且我很快想出该怎么做。 现在唯一的问题是实施它。 这是我犯错误的地方。
First of all, I spent way to long finding out how to combine the arrays. I’ll admit, I think some of the pressure of the situation got to me here. Because I did all sorts of weird stuff when I could have solved it with a simple reduce. In fairness, I wasn’t as comfortable with reduce then as I am now.
首先,我花了很长时间寻找如何组合数组的方法。 我承认,我认为局势的某些压力在这里给了我。 因为当我可以用简单的reduce来解决它时,我做了各种各样奇怪的事情。 公平地讲,我不像现在这样适应减少。
// What I should have done
const pageData = pages.reduce((startingValue, page) => startingValue.concat(page.data), [])
// What I ended up doing
const pages = this.state.pages;
const pageData = [];
pages.forEach(page => pageData = pageData.concat(page.data));
Now that I had an array with all the data, I needed to write the logic to sort it. As my experience in programming has been largely based around building my own projects, it had been a long time since I had anything to do with the JavaScript sort function. I had to look it up, and I spent some time checking MDN and examples on stack overflow to really understand it before I implemented it.
现在我有了一个包含所有数据的数组,我需要编写逻辑来对其进行排序。 由于我在编程方面的经验主要是基于构建自己的项目,因此距我与JavaScript排序功能的关系已有很长时间了。 我必须查找它,并花了一些时间检查MDN和堆栈溢出示例以真正理解它,然后再实现它。
I got the sorting working, partially. I got stuck here for a while. Most of the names in the array were sorted correctly, however at the top there were some names that were out of order. At this point, I was trying to keep calm, but in my mind I was freaking out. I was trying to wrap my head around why it was not sorting correctly. And I was stuck here for longer than I’d like to admit.
我部分完成了排序工作。 我在这里停留了一段时间。 数组中的大多数名称都正确排序,但是在顶部,有些名称是乱序的。 在这一点上,我试图保持镇定,但在我的脑海中,我却吓坏了。 我试图绕过为什么排序不正确的问题。 而且我在这里停留的时间比我想承认的要长。
After some discussion and prodding from the interviewers. I finally remembered that strings are sorted by their ASCII values. Uppercase letters are valued from 65 - 90 and lowercase letters are valued from 97 - 122. The top results that were not sorted correctly had an uppercase first letter, which had the effect of sorting them first, since their ASCII value is lower than lowercase letters. It is a mistake I will never make again.
经过面试官的讨论和劝说。 我终于想起了字符串是按其ASCII值排序的。 大写字母的值介于65-90之间,小写字母的值介于97-122之间。未正确排序的顶部结果具有大写的第一个字母,由于它们的ASCII值小于小写字母,因此具有先排序的效果。 。 这是我永远不会犯的错误。
When the issue was identified, I immediately solved it with using .toLowerCase() on the names being sorted.
发现问题后,我立即对要排序的名称使用.toLowerCase()解决了问题。
Now only one thing remained.
现在只剩下一件事了。
Passing the sorted data into the pagination function.
将排序后的数据传递给分页功能。
Here too, I hit a snag.
在这里,我也遇到了障碍。
The pagination function expected an Ajax response and passed each item to a formatData function that picked apart the relevant pieces and returned a new object. However, when I tried to pass the new array of objects that was sorted into this function, it would no longer have the original property names and the function would throw an error.
分页函数期望Ajax响应,并将每个项目传递给formatData函数,该函数将相关部分分开并返回一个新对象。 但是,当我尝试传递已排序到该函数中的新对象数组时,它将不再具有原始属性名,并且该函数将引发错误。
I spent some time working on this before I figured out that I had to move the formatData out of the pagination function and perform it on the response data before the data was passed to the pagination function.
我花了一些时间进行此工作,然后才发现必须将formatData从分页功能中移出,并对响应数据执行该操作,然后再将数据传递给分页功能。
Once this and some more minor changes were done, the code was finally working. It had taken some time, but eventually I solved it.
完成此操作以及其他一些较小的更改后,代码终于可以正常工作了。 花了一段时间,但最终我解决了。
At this point the coding part of the technical interview was over.
至此,技术面试的编码部分结束了。
And I was feeling drained.
我感到筋疲力尽。
We concluded the interview with some more chatting. They told me more about their company, and I asked some questions before we parted ways.
最后,我们聊了聊。 他们告诉了我关于他们公司的更多信息,在我们分开之前,我问了一些问题。
However, the interview didn’t stop there.
但是,采访并不仅限于此。
I contemplated the interview, reflected over what I did wrong, went to sleep and then went to work.
我考虑了这次面试,思考我做错了什么,入睡,然后上班。
The next day I spent three hours improving the solution, and then I sent this email:
第二天,我花了三个小时改进解决方案,然后我发送了此电子邮件:
Hi interview X and interviewer Y.
嗨,面试X和面试官Y。
I’d like to thank you for agreeing to speak with me yesterday. I’ve thought a lot about the solution and I decided to work a little bit on improving it today. I’ve provided the code of an enhanced version of what we worked on yesterday. This is what I’ve done:
我要感谢您同意昨天与我交谈。 我已经对该解决方案进行了很多思考,因此决定在今天进行一些改进。 我提供了昨天工作的增强版本的代码。 这是我所做的:
I expanded the sorting functionality to be able to reverse the result if it’s pressed a second time.
我扩展了排序功能,以便能够在第二次按下结果时将其反转。
I expanded sorting functionality to all titles.
我将排序功能扩展到所有标题。
I added icons to sorting headers.
我在排序标题中添加了图标。
I refactored the pagination function, learned the basics of unit testing, and used Jest to test the functionality of it.
我重构了分页功能,学习了单元测试的基础知识,并使用Jest测试了它的功能。
I added query string support for the pagination so that reload and linking would show the correct data when visiting a different page.
我为分页添加了查询字符串支持,以便重新加载和链接在访问其他页面时将显示正确的数据。
I added media query styling to make the component mobile friendly.
我添加了媒体查询样式,以使组件移动友好。
I added a loader to be shown while the API call is happening
我添加了一个加载器以在API调用发生时显示
I added error handling, with an opportunity for the user to re-initiate the API call.
我添加了错误处理,为用户提供了重新启动API调用的机会。
I changed the sorting function on mobile to work with a select box.
我更改了移动设备上的排序功能,以使用选择框。
I fixed the error where an anchor tag was enclosing an li tag.
我修复了锚标签封装li标签的错误。
It might have been slightly overkill, but I was inspired and I wanted to improve the solution.
可能有些过大,但是我受到了启发,我想改善解决方案。
Best regards,
最好的祝福,
Fredrik Strand Oseberg
弗雷德里克·斯特兰德·奥斯伯格
It wasn’t enough. But at least I did all I could. Some time later I received this email:
这还不够。 但是至少我已经尽力了。 一段时间后,我收到了这封电子邮件:
Hi!
嗨!
We’d like to thank you for some nice interview rounds, but we have to conclude that we do not offer you the position, because you didn’t aspire to our expectations in the technical part.
我们要感谢您进行的几次面试,但我们必须得出结论,我们不向您提供该职位,因为您并不渴望在技术方面达到我们的期望。
We like your background and believe that you can fit well into our community, so we’re giving you a detailed feedback on your technical interview, hoping that you’ll apply to us again once you gain some more programming experience.
我们喜欢您的背景,并相信您可以很好地融入我们的社区,因此我们将为您提供有关技术面试的详细反馈,希望您一旦获得更多编程经验,便可以再次向我们提出申请。
我哪里做错了? (Where did I go wrong?)
Well, luckily I got a detailed feedback report. So let’s take a look at it and I’ll discuss it with you.
好吧,幸运的是我得到了详细的反馈报告。 因此,让我们看一下,我将与您讨论。
反馈意见1:“花太多时间寻找如何组合数组。 首先在互联网上搜索,而不是检查JavaScript文档(例如:“ js array doc”将给出w3schools或mdn,其中列出了函数),并错误地使用了示例(array.concat返回一个新数组)。 没有人会记住API中的所有内容,因此习惯使用JS或库文档很重要。” (Piece of Feedback 1: “Spends too much time finding out how to combine arrays. Searches the internet first instead of checking documentation for JavaScript (for example: “js array doc” would give w3schools or mdn, where the functions are listed), and uses the examples wrongly (array.concat returns a new array). No one remembers everything in the APIs, so being comfortable with using documentation for JS or a library is important.”)
Takeaway: Interviewers want to see you reach for MDN (or other relevant documentation) first. They want to see that you can find and read documentation and implement it based upon the information found there.
要点:面试官想首先看到您接触到MDN(或其他相关文档)。 他们希望看到您可以找到和阅读文档,并根据在那里找到的信息来实施它。
反馈意见2:“在排序作业中,候选人首先提出了一种奇怪的手动算法。 幸运的是,他选择使用JavaScript中的内置排序功能,但不确定其工作原理,必须反复检查文档。” (Piece of Feedback 2: “In the sorting assignment the candidate first suggests a weird manual algorithm. Luckily he chooses to use the built-in sort function in JavaScript, but is unsure of how this works and must check documentation repeatedly.”)
Takeaway: Be absolutely clear in your communication. In this case, I asked the interviewers about whether or not I should use the built-in JavaScript sort function or not, to clarify the boundaries/limitations of the task at hand, and to demonstrate that I didn’t jump into coding without knowing the terms under which I operated. Unfortunately, I think this was misinterpreted as me suggesting to use my own sorting algorithm, when I didn’t intend to do so unless that was specifically what they wanted out of the task.
要点:沟通中要绝对清楚。 在这种情况下,我询问了面试官是否应该使用内置JavaScript排序功能,以阐明手头任务的界限/局限性,并证明我在不知情的情况下就没有跳入编码领域我经营的条款。 不幸的是,我以为我建议使用我自己的排序算法,而我不打算这样做,除非他们特别希望他们完成任务,否则这会被误解。
This ended up having the opposite effect of what I wanted to convey. Make sure that you communicate clearly what your questions intend to uncover. Because they might make perfect sense to you, but can be perceived otherwise by your interviewers.
最终产生了与我想传达的相反的效果。 确保您清楚传达要解决的问题。 因为它们对您来说可能很有意义,但您的面试官却可以理解。
反馈意见3:“当代码正常工作时,文本按“区分大小写”的顺序排序,这是一种典型的情况。” (Piece of Feedback 3: “When the code works, the text is sorted “case sensitive”, a classic scenario.”)
Unfortunately the candidate spends a long time before the problem is understood, but once it’s identified it’s corrected immediately.
不幸的是,考生花了很长时间才能理解问题,但一旦发现问题,便会立即得到纠正。
Takeaway: Speed is of the essence. Bugs will always appear when writing programs, but try to solve them as quickly as you can. Find the essence of the problem, and turn to documentation quickly if you can not figure it out.
要点:速度至关重要。 在编写程序时,错误始终会出现,但是请尽快解决。 找到问题的实质,如果无法解决,请快速阅读文档。
反馈4:“花了一些时间来理解为什么在重构时必须将formatData从分页中移出。” (Piece of Feedback 4: “Spent some time to understand why formatData had to be moved out of pagination under refactor.”)
Takeaway: Again, speed is of the essence.
要点:再次,速度至关重要。
反馈5:“许多foreach循环,其中可能已使用array.map或array.reduce。 了解更多有关函数式编程的知识将是有益的。” (Piece of Feedback 5: “A lot of foreach loops, where array.map or array.reduce could have been used. It would be beneficial to learn more about functional programming.”)
Takeaway: Learn array.map, array.filter and array.reduce, and learn them well. I’ve been delving into functional programming on the back of this, and it’s a daunting task. But you don’t need to learn it all now, just make sure you get the basics down.
总结:学习array.map,array.filter和array.reduce并学得很好。 在此基础上,我一直在研究函数式编程,这是一项艰巨的任务。 但是您无需立即学习所有内容,只需确保您掌握了基础知识即可。
反馈意见6:我希望应聘者对单元测试有更多的了解。 (Piece of Feedback 6: I’d like the candidate to have more knowledge about unit-testing.)
Takeaway: This seems fairly obvious, but let’s write it out a few times just for good measure: Testing is important. Testing is important. Testing is important. Learn it. Incorporate it. Use it.
总结:这似乎很明显,但是为了好好衡量,让我们写几次:测试很重要。 测试很重要。 测试很重要。 学习吧。 合并它。 用它。
The rest of the document is praise. I won’t go into that much detail, because it’s not that important. But here is the gist of it:
该文件的其余部分都受到好评。 我不会详细介绍,因为它并不那么重要。 但是这是要点:
- He uses his editor well 他很好地使用了编辑
- He uses the debugger in Chrome (knowing advanced debugging tools is important) 他在Chrome中使用调试器(了解高级调试工具很重要)
- He checks that things work before moving on (using console.log) 他在继续之前检查一切是否正常(使用console.log)
- He tries to split the code up into lesser logical parts 他试图将代码分成较少的逻辑部分
- He uses variables with names instead of comments, this makes the code more readable. 他使用带名称的变量而不是注释,这使代码更具可读性。
- He knows React well 他很了解React
- Earlier projects are impressive 早期的项目令人印象深刻
- Possesses other positive qualities than programming (design/visual) 除了编程(设计/视觉)以外,还具有其他积极的素质
我在准备工作上可以做些什么? (What could I have done differently in preparation?)
Hindsight is 20/20. But when you get a no, you’ll inevitably spend some time thinking about what you could have done differently.
后见之明是20/20。 但是,如果您拒绝了,您将不可避免地花费一些时间来思考可以做些什么。
仔细阅读家庭作业代码。 (Go through the home assignment code more thoroughly.)
I spent too much time working on my JavaScript knowledge. I should have gone through my own code even more than I did. Even though I wrote it, when a few weeks pass between the time of writing and the interview, you need to go back and refresh your memory. I wish I’d spent more time on this than on obscure JavaScript questions.
我花了太多时间来学习JavaScript知识。 我应该比自己做的更多。 即使是我写的,在写作和面试之间又过了几周,您仍然需要回去重新整理一下自己的记忆。 我希望我花更多的时间在这个问题上,而不是花在晦涩JavaScript问题上。
做更多实用JavaScript分配。 (Do more practical JavaScript assignments.)
I did a lot of theoretical work leading up to the interview. I wish now that I had spent more time, or at least mixed in, practical assignments. Solve algorithms on Hackerrank or Code Wars. Or build common frontend components like a sorted list, dropdown menus, pagination, and so on.
在面试之前,我做了很多理论工作。 现在,我希望自己能花更多的时间,或者至少参与一些实际的工作。 解决Hackerrank或Code Wars上的算法。 或构建常见的前端组件,例如排序列表,下拉菜单,分页等等。
面试总结 (Interview wrap up)
How do I feel after my first technical interview? Honestly, it was a great experience. I’m very grateful to the interviewers that I talked to for giving me such a detailed feedback, and allowing me to correct my mistakes before my next interview. And even though I didn’t get this job, I’m one step closer to getting my first frontend developer job.
第一次技术面试后感觉如何? 老实说,这是一次很棒的经历。 非常感谢与我交谈的面试官给我这么详细的反馈,并允许我在下一次面试之前纠正我的错误。 即使我没有得到这份工作,我也离获得第一份前端开发人员工作仅一步之遥。
I’ve also learned that interviews are a fickle thing. Perhaps if I had built a sorting mechanism in my own projects, or if I had gotten a different assignment closer to something I had done before, it would’ve gone differently.
我还了解到面试是一个善变的事情。 也许如果我在自己的项目中建立了排序机制,或者如果我更接近以前所做的工作而获得了不同的任务,那情况就会有所不同。
My biggest strength is that I have spent a lot of time learning JavaScript over the past year, and I am able to learn and adopt new ideas quickly now. Unfortunately, I don’t think I was able to demonstrate this knowledge this time. I didn’t get to:
我的最大优点是,在过去的一年中,我花了很多时间学习JavaScript,现在我可以快速学习和采用新的想法。 不幸的是,我认为这次我无法证明这一点。 我没有去:
- Show them my knowledge about the JavaScript prototype chain, and how it allows for effortless and memory efficient sharing of methods between objects. 向他们展示我关于JavaScript原型链的知识,以及它如何实现对象之间方法的轻松共享和内存高效共享。
- Talk about closures and how JavaScript inner functions have the ability to close over variables in the outer scope and access them at a later time after the outer function has returned - and how this prevents garbage collection. 讨论闭包以及JavaScript内部函数如何关闭外部作用域中的变量并在外部函数返回后稍后再访问它们的能力-以及如何防止垃圾回收。
- Share my knowledge of JavaScript scope, and how JavaScript checks each level of it’s local scope all the way up to the global scope to find variables. 分享我对JavaScript作用域的知识,以及JavaScript如何检查本地作用域的每个级别,一直到全局作用域以查找变量。
- Share my knowledge of conversion and how === checks for equality without type conversion and == checks for equality and type conversion. 分享我的转换知识,以及===如何在不进行类型转换的情况下检查是否相等,以及==如何在相等和类型转换的情况下进行检查。
Talk about hoisting and how functions statements and variables (except let and const) are hoisted to the top in JavaScript, allowing preceding code to use them.
讨论提升,以及如何将函数语句和变量(let和const除外)提升到JavaScript的顶部,以允许前面的代码使用它们。
- Talk about the this keyword, and how the value of this entirely depends on the invocation (call site) of the function. 讨论this关键字,以及this的值如何完全取决于函数的调用(调用站点)。
I sort of (pun intended) wish that I had.
我有点 (双关语意)我希望。
成功之路 (The road to success)
Now, it would be easy for me to say to myself: “I’m not good enough. I need to spend 3 - 4 months learning more, and then try again.”
现在,我很容易对自己说:“我还不够好。 我需要花3-4个月来学习更多,然后再试一次。”
I didn’t.
我没有
I decided to apply to as many jobs as I possibly could in two weeks. I applied to the biggest IT firms in Norway.
我决定在两周内尽可能多地申请工作。 我申请了挪威最大的IT公司。
I aimed for the sky.
我瞄准了天空。
Two weeks after, I was done with going through interviews with several companies, and I had another technical interview.
两周后,我完成了对多家公司的采访,然后又进行了一次技术采访。
第二轮准备 (Second round of preparation)
If there is one thing I learned from my first technical interview, it’s that preparation is key. It helps by thinking of the technical interview as an exam, and take the necessary steps to ensure you pass.
如果我从第一次技术面试中学到的一件事,那就是准备是关键。 通过将技术面试视为一项考试,它会有所帮助,并采取必要的步骤来确保您通过考试。
Exams, like interviews, are faulty in that they fail to encompass the full knowledge spectrum of the candidate. So what can you do?
考试像面试一样,是有缺陷的,因为它们无法涵盖候选人的全部知识范围。 所以,你可以做什么?
Broaden your knowledge spectrum.
拓宽您的知识范围。
Be bulletproof. Be Neo.
防弹。 是新人。
For me, I used advanced memory techniques to memorise the answers to over 100 frontend interview questions in 8 hours. The questions can be found in this repository.
对我来说,我使用先进的记忆技术在8小时内记住了100多个前端面试问题的答案。 这些问题可以在此存储库中找到 。
How I did this is beyond the scope of this article, but if you are curious about how it works, leave a comment below and I’ll write another article about it.
我如何做到这一点超出了本文的范围,但是如果您对它的工作原理感到好奇,请在下面留下评论,我将撰写有关此内容的另一篇文章。
Furthermore, I spent time on practical examples on Code Wars and Hackerrank. As well as spending time actually building things.
此外,我花了一些时间在Code Wars和Hackerrank的实际示例上。 花费时间实际建造东西。
技术面试2 (Technical Interview 2)
Rich on lessons from my last failed interview, I had done my due diligence.
在上次失败的面试中汲取了很多教训,我进行了尽职调查。
This interview was focused more around a discussion of front end concepts. It was a comprehensive interview, and I felt that the interviewers really wanted to map my knowledge and learn my strengths and weaknesses.
这次采访更多地集中在对前端概念的讨论上。 这是一次全面的面试,我觉得面试官确实想了解我的知识并了解我的长处和短处。
The interview lasted around two hours this time, and I really appreciated that the interviewers did their due diligence so thoroughly as well.
这次采访持续了大约两个小时,我真的很感谢采访者也如此彻底地进行了尽职调查。
Here’s a list of all the topics we covered:
以下是我们涵盖的所有主题的列表:
- JS, CSS and HTML broad strokes JS,CSS和HTML粗笔
- Document structure 文件结构
- Project structure 项目结构
- Git 吉特
- Performance 性能
- Security 安全
- Accessability 可及性
- SEO 搜索引擎优化
- Responsive web design 响应式网页设计
The coding challenge was based on vanilla Javascript. I was challenged to add a simple class to a div using vanilla Javascript. Now, if you’ve spent time in JS using mainly frameworks, you might not be familiar with the classList API. Fortunately, I had spent most of my time doing all the freeCodeCamp projects with vanilla JS. This is what it looks like:
编码挑战基于原始Javascript。 我面临使用香草Javascript向div添加简单类的挑战。 现在,如果您主要在JS上花费时间使用框架,则您可能不熟悉classList API。 幸运的是,我花了大部分时间使用香草JS完成所有的freeCodeCamp项目。 看起来是这样的:
const btn = document.querySelector('.btn');
const menu = document.querySelector('.menu');
function addClassNameToDiv() {
if (!menu.classList.contains('new-class')) {
menu.classList.add('new-class');
} else {
menu.classList.remove('new-class');
}
}
btn.addEventListener('click', addClassNameToDiv)
Alternatively, you could use the classList.toggle(‘new-class’) to make it into a one liner. I was also asked to extend it to close the menu if you click outside of the dropdown menu:
或者,您可以使用classList.toggle('new-class')使其成为一个衬板。 如果您在下拉菜单之外单击,还要求我扩展它以关闭菜单:
window.addEventListener('click', () => menu.classList.remove('new-class'));
Takeaways from the coding challenge:
编码挑战的要点:
- Shorter is better, as long as it’s always readable. 越短越好,只要它始终可读即可。
- Performance wise, it’s better to put query selectors outside of an event listeners callback function (called just one time instead of every time the listener fires). 在性能方面,最好将查询选择器放在事件侦听器回调函数之外(仅调用一次,而不是每次触发侦听器时)。
- Performance wise, getElementById and getElementByClassName are more performant than querySelector 在性能方面,getElementById和getElementByClassName比querySelector更具性能
The next day, I was called up by the manager. I’d passed the interview, and they wanted to extend me an offer.
第二天,经理打电话给我。 我通过了面试,他们想给我一个报价。
I could have stopped here. I could have said: “I passed one technical, that is good enough”.
我本可以在这里停下来。 我可以说:“我通过了一项技术,足够了”。
I did the opposite.
我做了相反的事情。
I called every company I was talking to at the time and told them I had an offer on the table, and asked if we could expedite the process, as I now had time constraints to consider.
我打电话给当时与我交谈的每家公司,并告诉他们我有要约,并询问我们是否可以加快流程,因为我现在有时间限制。
Interviews, and especially technical interviews, are tough mental ordeals. You’re on all the time on display, all the time expected to perform and exceed expectations. It’s hard. So why did I do this?
面试,尤其是技术面试,是严峻的心理考验。 您一直在展示,总是期望表现并超过期望。 这个很难(硬。 那我为什么要这样做呢?
Four reasons.
四个原因。
- I wanted to prove to myself that it wasn’t luck. 我想向自己证明这不是运气。
- I wanted to be respectful to everyone I had been interviewing with and give them a fair chance. 我想尊重与我面试过的每个人,并给他们一个公平的机会。
- I wanted to make sure I found the right fit and best community for me to be in and grow as a developer. 我想确保自己找到合适的,最适合自己的社区,成为开发人员并在其中成长。
- You guys. This community has helped me so much, and I wanted to help garner as much information as possible from the technical interview, so that you may learn from my mistakes and prepare accordingly. 你们。 这个社区对我有很大帮助,我想从技术面试中获得尽可能多的信息,以便您可以从我的错误中学到并做相应的准备。
I am humbled by the help and support I have received from freeCodeCamp, and I wanted to give back.
我对来自freeCodeCamp的帮助和支持感到很沮丧,我想回馈。
技术面试3 (Technical Interview 3)
After getting in touch with the other companies and explaining that I had an offer on the table from a top tier firm, a lot of companies were keen to rush me through. In one week I conducted several interviews, and I had more technical interviews to get through.
与其他公司联系并解释说我有一家顶级公司提出要约后,许多公司都渴望让我过关。 在一个星期内,我进行了几次面试,然后进行了更多的技术面试。
Here’s a roundup of some of the interview questions from my third technical interview:
这是我第三次技术面试中一些面试问题的总结:
- How did you get into React? Why did you get into it? What is good about it? 您是如何进入React的? 你为什么要加入? 有什么好处?
- How does Redux work? What does the API consist of? What is immutability? What is good about immutability? Redux如何工作? API由什么组成? 什么是不变性? 不变性有什么好处?
- How would you redesign our web page? 您将如何重新设计我们的网页?
- How do you feel about working with deeper layers of the application? For example backend? 您对使用应用程序的更深层感觉如何? 例如后端?
- Do you do your own testing? What is a unit test? 你自己做测试吗? 什么是单元测试?
- What is a good user experience for you? 对您来说,什么是良好的用户体验?
- How do you test user experience? 您如何测试用户体验?
The coding challenge in this interview was based around CSS. I was given a piece of paper with some CSS rules on it that looked like this:
这次采访中的编码挑战基于CSS。 我得到了一张纸,上面写有一些CSS规则,如下所示:
<div id="menu" class="dropdown-menu"></div> // HTML Element
// CSS Rules
#menu {
color: black;
}
.dropdown-menu {
color: green;
}
div {
color: blue;
}
My task was to explain what I saw. I immediately identified the HTML element and told the interviewers that the id and class on the element could be used in CSS to select the HTML element. From there, I explained that CSS is cascading, meaning that normally the last rule will apply. However, in this case the selectors have different weighting. The order of weighting goes like this: id > class > element.
我的任务是解释我所看到的。 我立即识别出HTML元素,并告诉采访者,该元素的id和class可以在CSS中用于选择HTML元素。 从那里,我解释了CSS是级联的,这意味着通常将应用最后一条规则。 但是,在这种情况下,选择器的权重不同。 加权顺序如下:id> class> element。
Which means, in the example above, the color black will be applied to the HTML element.
这意味着,在上面的示例中,黑色将应用于HTML元素。
技术面试#4 (Technical Interview #4)
This is the last technical interview I had. And while it was still nerve racking, by now I was used to it. Here’s a rundown of what we talked about:
这是我最后一次技术面试。 虽然它仍然令人不快,但现在我已经习惯了。 以下是我们所讨论内容的摘要:
- Draw up a basic website. Identify the components. 画一个基本的网站。 识别组件。
- How would you make it responsive? 您将如何做出回应?
- How would you center the text vertically and horizontally? 您如何将文本垂直和水平居中?
- What is the CSS box model? What is the difference between content box and border box? 什么是CSS盒子模型? 内容框和边框之间有什么区别?
- What is the difference between double and triple equals? 双倍和三倍相等有什么区别?
- What is good about React? React有什么好处?
- What is the benefit of array.forEach over a for loop? Are there cases where you might need to use a for loop? 与for循环相比,array.forEach有什么好处? 在某些情况下,您可能需要使用for循环?
The coding challenge was to build a wordwrap function of varying degrees of difficulty. Imagine you can only fit 20 characters on a screen, and if you go above it, you have to start on a new line.
编码方面的挑战是构建难度不同的自动换行功能。 假设您在屏幕上只能容纳20个字符,并且如果屏幕上方只能容纳20个字符,则必须从新的一行开始。
My original solution to this question involved splitting the string, using a counter and the modulus operator to determine whether the count was 20, then inserting a newline character into the array and joining the string.
我对这个问题的最初解决方案包括使用计数器和模运算符来分割字符串,以确定计数是否为20,然后将换行符插入数组并连接字符串。
The task was then increased in difficulty to only allow full words to be on a single line. Meaning that if one word caused the total count to exceed 20, you needed to insert a newline character before that word.
然后增加了任务的难度,只允许将完整的单词放在一行上。 这意味着如果一个单词导致总数超过20,则需要在该单词之前插入换行符。
I didn’t solve this all the way in the interview, but I was on the right track. I used MDN when I was uncertain, and I was making good progress.
在面试中,我并没有解决所有问题,但是我走了正确的路。 当我不确定时,我使用了MDN,并且取得了良好的进步。
And that was enough.
这就足够了。
I couldn’t put it down though, so if you’re interested, here is the solved version:
不过我无法拒绝,因此,如果您有兴趣,这里提供了已解决的版本:
function wordWrap(str) {
let totalCount = 0;
const arr = str.split(' '), formattedStr = [];
arr.forEach((word, index) => {
totalCount += word.length;
if (totalCount >= 20) {
formattedStr.push('\n', word, ' ');
totalCount = word.length;
} else {
formattedStr.push(word, ' ');
}
});
return formattedStr.join('');
}
结论 (Conclusion)
If you made it all the way here, congrats. This was a long one. I did my best to make it as informative as possible, hoping that it may help someone like you.
恭喜,如果您在这里取得成功。 这是一个很长的时间。 我尽力使它尽可能丰富,希望对您这样的人有所帮助。
The end result of this landed me in a situation I never thought I’d be in. At the end, I had 5 offers on the table to choose from. One large company even made me an offer “blind”, based on me having an offer from a competitor. I ended up choosing the company where I first passed the technical, as I believed it would be the best fit for me.
最终的结果使我陷入了我从未想到过的境地。最后,我桌上有5个要约可供选择。 一家大公司甚至根据我收到竞争对手的提议,对我开出了“盲目的”要约。 我最终选择了我最先通过技术的公司,因为我认为这将是最适合我的公司。
The technical interview can be a tough mental ordeal. You’re going to be challenged, you’re going to be taken out of your comfort zone, and that is a good thing. It helps you grow. It makes you better.
技术面试可能是艰苦的心理考验。 您将受到挑战,您将被带离舒适区,这是一件好事。 它可以帮助您成长。 它使您变得更好。
And if you prepare, you will be ready for it.
如果您做好准备,您将为此做好准备。
So from my own experience, don’t shy away from the technical interview. Don’t put it off because you failed one. Don’t think that it’s the end-all measure of you as a developer. It’s not. It’s merely the least broken tool that company’s have to measure your productivity.
因此,以我自己的经验,不要回避技术面试。 不要因为你失败而推迟。 不要以为这是您作为开发人员的最终标准。 不是。 它只是公司用来衡量您的生产力的最少损坏的工具。
Apply for jobs. Prepare well. Attend technical interviews. Learn from mistakes. Repeat.
申请工作。 做好准备。 参加技术面试。 从错误中学习。 重复。
If you do this, I guarantee you, you will succeed.
如果您这样做,我向您保证,您将成功。
I’m rooting for you.
我为你加油。
面试 技术 教训