preface

Was then jump season, a time to share with you a wave test, usually you will brush before job-hopping, even said never brush topic for many years development experience of the great god could do in the interview but painted with all kinds of questions of the interviewer, led to a volume, this side also confirm the importance of the interview questions.

I’ve also seen a lot of interview questions, and I hate the ones that are too long code snippets or involve a lot of knowledge or involve complicated mathematical formulas or are too low-level: Hand-written Promise A+ specification, hand-torn red and black trees, formula-implemented Canvas XX effects, how the browser implements the XXX API, and how to mimic it if the browser doesn’t provide it, What’s the difference between Vue3’s Diff algorithm and React’s Diff algorithm? Can you write a combined version of the Diff algorithm? Can you write a slice of the React time?

Believe most people also like me, every time to see this article, not watch them don’t have patience to continue to see, is half cannot but turn to see the comments section to read the comments, then the thumb up, attention, collect three even, a key on the favorites are going to accumulate in articles, this article although technology content is very high, but too boring, Or is involved in the knowledge is too wide, if one of the knowledge is not too familiar, the follow-up content will not understand. Just like in math class, at the beginning did not listen carefully, fell a point of knowledge did not hear, and then came back to find that it has not understood.

Such as there is a time to see an article is the Canvas to realize what a very cool special effects, watch out of nowhere the trigonometric function, while the middle school have learned these, but after so many years would have what sin, cos, tan, the meaning of these symbols to forget about, but also lazy don’t want to open a browser, a search for a check, Continue to see, looking at what matrix algorithm, in fact, also learned in college, in short, to see the result of the final implementation is very cool, but the specific is how to achieve the heart is also in the fog. Unless you really need to use this in your work, you will read the article carefully and study it. Even if you do not use it in your work at the same time, you will forget it very quickly.

The other kind of article is very immediate: it’s not complicated, it’s just never thought it could be used in this way before, it’s like an idea, or an API that you didn’t know before, and it’s easy to use. This article is not particularly dull and boring, and also see with relish, sigh: the original can also be used! Why didn’t you think of it before?

It’s not particularly easy to forget, and you may even find the opportunity to experiment with it in the course of your work. Here are some examples:

A video is played when no operation is performed for a certain period of time

At that time, I was just in the stage of entering the industry, and my experience was poor, so I had no idea about some very ordinary needs. At that time, I was working on the Electron project, which was displayed on a wall of Yangming Ancient Town. The requirement was that when the user did not operate the interface for ten minutes, the propaganda video of Yangming Ancient Town would be automatically played. At that time, my brain was like stuck: how could I know that the user did not operate for ten minutes? I went to find out if there was such an API, and then I saw an article that made me say, “What a wonderful thing!” 👍

The principle is super simple, which is to set a variable on the page for ten minutes:

let minute = 10
Copy the code

Then set a timer of -1 per minute:

setInterval(() = > {
  minute--
  if (minute <= 0) {
    // Play the video}},1000 * 60)
Copy the code

When an event occurs, it represents that the user is operating and the variable needs to be restored:

window.addEventListener('click'.() = > minute = 10)
Copy the code

You can also listen for events like Mousemove or keyboard, but that project is a touch screen, there’s no mouse or keyboard, so just listen for click events

Just a few lines of code to solve my urgent need, of course, at that time also dish, so simple requirements have not thought out, but who is not from the small white step by step to come up? It is with these articles that I expand my thinking step by step that I can make rapid progress.

Vue performance optimization

Read the revelation of Vue.js nine Performance Optimization Techniques produced by Teacher Huang.

For example, a function on computed can accept a this parameter:

computed: {
  a () { return 1 },
  b ({ a }) {
      return a + 10}}Copy the code

So you don’t get the getter again and again when the component is refreshed, and you’ve never noticed that before.

Pure CSS drag-and-drop effect

Before we do drag and drop when the basic will use JS to achieve, very troublesome, but read the front end team “pure CSS can also achieve drag and drop effect” makes me admire:

In the traditional Web, page scrolling is a very common interaction, the operation is using the mouse wheel or directly drag the scroll bar. However, the mobile end is different, just drag the page with your finger to scroll. Usually the page scrolls either vertically or horizontally. What if you can scroll in both directions? Such as:

.dragbox {
  width: 300px;
  height: 300px;
  overflow: auto
}
.dragcon {
  width: 500px;
  height: 500px;
}
Copy the code

You can scroll in both directions as long as the inside element is larger than the container (remember to set overflow:auto).

Normally, the mouse wheel can only scroll in one direction at a time (hold Shift to scroll in the other direction), but the mobile can simply drag and scroll, as shown below:

Now, add an element in the middle of the content and scroll along with the content area:

Next, hide the text behind it:

Isn’t that a bit of a drag? It’s that simple!

New syntax for Vue3

A search for Vue3 now results in either Composition API or the new responsive principles, both of which are complicated to talk about, and many of the other points that people miss, such as a lot of times we want CSS to be responsive as well, such as the syntax we once fantasize about:

<template>
  <h1>{{ color }}</h1>
</template>

<script>
export default {
  data () {
    return {
      color: 'red'}}}</script>

<style>
h1 {
  color: this.color;
}
</style>
Copy the code

Since CSS and JS are in different contexts, this can be difficult to do, but since I read Vue’s exciting New Feature: Introducing JS variables into CSS, I can also write this:

<template>
  <h1>{{ color }}</h1>
</template>

<script>
export default {
  data () {
    return {
      color: 'yellow'}}}</script>

<style>
h1 {
  color: v-bind(color)
}
</style>
Copy the code

When this. Color changes, CSS will respond as well.

Then there’s Vue’s super fun new feature: DOM Portal. These tips can be very handy to improve our development efficiency, but are rarely mentioned in Vue3 articles today.

The nine grid interview questions

There are not many code questions for this type of interview, but very few people can get them right. It gives us a good idea, because when you’re doing this:

A lot of people think they just need to add a border to each cell, when in fact doing so would look something like this:

Because by adding a border to each box, the adjacent borders will fit together, making it look twice as thick to the naked eye. And “Don’t underestimate the nine grid, one question can let a candidate reveal his true colors!” This problem is easily solved by using negative margins:

Negative CSS values you don’t know

The mention of negative margins brings to mind this post on negative CSS Tips and Details you didn’t know:

<template>
  <div></div>
</template>

<style>
div {
  width: 200px;
  height: 200px;
  outline: 20px solid # 000;
  outline-offset: -118px;
}
</style>
Copy the code

I really didn’t think that would be a plus.

The title

The algorithm problems in this article, like the ones listed above, are small and even simple, but the point is to see how flexible you are with the technology and how well you can think about it.

, of course, also is not to say that the amount of code a lot of articles is very complicated, in fact, those articles have high technical content, but after all, most people do not mind so carefully study a variety of complex algorithms, but if you want to is a byte to beat ali, tencent, baidu, such companies go to the interview, delve into the complex articles or very be necessary.

Scene reappearance

On the day of the interview I went into what looked like a conference room. The interviewer gave me some papers and a pen to write first. Then he went out. I still wondered: Aren’t you afraid that no one is looking at me while I search for answers on my phone? Is there a camera on the screen to see if I’m using my phone to search for answers, to see if the candidates are honest…

Of course I didn’t want to use my phone

The paper was a bit like a high school exam: multiple choice, fill in the blank, and big questions

The big problem is hand-written code, which is really annoying… On the one hand, you can only write half of the braces first, because you don’t know how many lines of code are going to be inside the braces, unlike in an editor, where the closing brackets automatically move as the number of lines increases; On the other hand, you don’t have a console, and you don’t know if what you’re writing is right, you can only tell by intuition.

One of the questions asked was to write a function that would return an array of random integers between 2 and 32 (which cannot be repeated). The function could also return the length of the array as an argument

Like this:

Just see the problem when still think this has what difficult, write bai! Start by generating random numbers between 2 and 32… How to generate random numbers between 2 and 32? Math.random() * 32 = 0 ~ 32 Mr. Into a random number between 0 and 30 and then add 2 not to get:

const fn = num= > {
  let arr = []

  for (let i = num; i-- > 0;) {
    arr.push(Math.round(Math.random() * 30 + 2))}return arr
}
Copy the code

The problem with writing this way is that randomly generated numbers will overlap:

Then I thought about ES6’s new data structure Set, which is guaranteed to have no duplicate values, and it can also use… Operator is handy to convert to an array, so continue:

const fn = num= > {
  let arr = []

  for (let i = num; i-- > 0;) {
    arr.push(Math.round(Math.random() * 30 + 2))
  }

  arr = [...new Set(arr)]

  return arr
}
Copy the code

This solves the problem of duplicate values, but creates a new problem: If there are several duplicate values, the length of the array will be smaller, like this:

The way I thought about it was this: if fn(10) is passing 10, and if the array is not 10, subtract the length of the array from 10 to get the number of digits. For example, fn(10) results in arr.length = 8, then 10-8 means that only two random numbers need to be regenerated, but the two random numbers may also overlap with the existing 8-bit array, so we need to connect the randomly generated two-digit number to the original 8-bit array. If the value 10 minus the length of the array arr.length is not equal to 0, then it is still a random number. Repeat the previous step. Until we generate an array of 10 digits with all digits unique, we automatically break out of the while loop and return the array:

const fn = num= > {
  let arr = []

  for (let i = num; i-- > 0;) {
    arr.push(Math.round(Math.random() * 30 + 2))
  }

  arr = [...new Set(arr)]
  
  let len = arr.length
      
  while (num - len > 0) {
    arr = [...new Set(arr.concat(fn(num - len)))]
    len = arr.length
  }

  return arr
}
Copy the code

Running result:

Of course, I could not see the result of the operation during the written test. This is the code I wrote with my impression after returning home, and I want to test whether it is right or not.

The second answer is more difficult

At the second interview (without asking any other questions), the interviewer said that while you got the question right, it was a bit of a brute force hack. For example, if I pass 30 into the function, which is a total of 30 numbers from 2 to 32, think about how many times this method for generating random numbers will run. If I’m lucky enough to get an array of 29 different digits from the first run of the function, and I’m still one digit short, how often do you think the last digit will be repeated? Is it 29 out of 30? Repeat and run again, repeat and run again… Every time you have to create an array and then create a Set and then go back to an array, it’s expensive, is there anything you want to optimize?

So what I’m thinking about at this point is not using a Set to redo, but how can I reuse the original array and not have it regenerate, just return one number at a time and recurse? Or do I add a second argument and pass in the array that was originally generated?

After I told him my idea, he was not satisfied that I was not getting to the point he wanted, so he gave me a hint: Given that generating random numbers is a particularly time-consuming operation, is there a way you can only let him run the parameters passed in so many times? Just like fn(10), can we make math.random run only 10 times?

At that time, MY head was all big, how is this possible? Since we are generating random numbers within a certain range, it is inevitable that there will be duplicates, even if we do not use the Set to do it in other ways, it must be run more than 10 times! But since he asked so I testify that what method can definitely do it, so I’ve been racking my brains to think of it, eventually, drill the end: that no matter what method can avoid generating repeat item, even if is lucky enough to run once get the desired results, it is not a technology, can be good luck, finally had to a showdown said he didn’t train of thought.

I thought the interview was about to end here, but I didn’t think he actually volunteered to tell me the solution of this problem, but I was a little frustrated at that time, I didn’t listen to a lot of what he said, I just remembered what he said to define two arrays. On the way home by subway, I kept thinking: two arrays… Student: Two arrays?

When I got home, I opened my computer and began to write code. First, I tested my original solution to see if the performance was as bad as he said:

0.1 milliseconds, not bad! Maybe the number is small, if it is generated from 0 to 10000 random number should crash? Modify the function:

const fn = num= > {
  let arr = []

  for (let i = num; i-- > 0;) {
    arr.push(Math.round(Math.random() * 10000))
  }

  arr = [...new Set(arr)]

  let len = arr.length

  while (num - len > 0) {
    arr = [...new Set(arr.concat(fn(num - len)))]
    len = arr.length
  }

  return arr
}
Copy the code

Running result:

This time, I felt that I was definitely caught. It took more than two seconds for the results to come out. In computer computing, two thousand milliseconds is an astronomical number. Let’s try these two arrays again: Define an empty array containing all integers from 2 to 32, and then define an empty array to hold the result. Generate random integers in the length range of the array. Use the generated integer as a subscript to pull the numbers from that array and put them in the empty array. This does not matter if the random number generated has duplicates, because the two arrays do not have duplicates:

const fn = num= > {
  const allNums = Array.from({ length: 31 }, (_, i) = > i + 2)
  const result = []

  for (let i = num; i-- > 0;) {
    result.push(allNums.splice(Math.floor(Math.random() * allNums.length), 1) [0])}return result
}
Copy the code

Try it again:

Nothing wrong with it. What about performance? To test:

It is much faster than before. Let’s try the random numbers from 0 to 10000 again.

const fn = num= > {
  const allNums = Array.from({ length: 10001 }, (_, i) = > i)
  const result = []

  for (let i = num; i-- > 0;) {
    result.push(allNums.splice(Math.floor(Math.random() * allNums.length), 1) [0])}return result
}
Copy the code

Running result:

This time the difference was particularly striking: one, which was more than 2,300 milliseconds, was able to produce a noticeable sensation of stalling, while the other, which was the human sensation of hitting Enter and producing results, took only seven milliseconds.

Actually this function encapsulation is incomplete, because the random Numbers are generated from a few to several entirely write die within the function, if you don’t want to generate a random number from 2 to 32 words also need to internal function to change the code, this is obviously not in conformity with the open closed principle, and use flexible enough, let’s again encapsulation, Let’s make it a more general function:

const fn = (len, from = 0, to = 100) = > {
  const allNums = Array.from({ length: to - from }, (_, i) = > i + from)
  const result = []

  for (let i = len; i-- > 0;) {
    result.push(allNums.splice(Math.floor(Math.random() * allNums.length), 1) [0])}return result
}
Copy the code

Running result:

You can see that it works perfectly to get the result that we want, but why don’t we have the number 12 in the tens place from 2 to 12? The substring function is closed on the left and opened on the right. The substring function is closed on the left and opened on the right. The substring function is closed on the left and opened on the right.

'0123456'.substring(1.5)
Copy the code

Running result:

You can see that the parameters we passed in are 1 through 5, but the final result includes 1 instead of 5. We learned in high school that an open interval and a closed interval, an open interval means it doesn’t include this number, and a closed interval means it does. The math teacher has always emphasized this concept, so the program should also be designed to try to conform to the rules of mathematics.

But I think can’t say that the random number generator is better than the previous one, but also to be divided into situations, take an extreme point of case: if from 0 to 10000 randomly generated 10 not repeating numbers, in such a large range of the case is the probability of repeating is very low? So the first solution probably only needs to generate ten random numbers. But the second option is to generate an array from 0 to 10000. The array is too large, but only 10 of the numbers are needed. It’s a bit like shooting at a mosquito with an anti-aircraft gun. If you want to make encapsulation a little more intelligent, here’s an idea:

To – from divided by len, that’s the ratio. For example, to get 10 numbers from 0 to 10000 is equivalent to 10/10000, which is one in a thousand. In this case, we use the first function to get random numbers. If we get 3000 numbers from 0 to 10000, it is three in ten. The second function is more appropriate:

const fn = (len, from = 0, to = 100) = > {
  const ratio = (to - from) / len
  let result = []
  
  if (ratio > 0.3) {
    const allNums = Array.from({ length: to - from }, (_, i) = > i + from)

    for (let i = len; i-- > 0;) {
      result.push(allNums.splice(Math.floor(Math.random() * allNums.length), 1) [0])}}else {
    for (let i = len; i-- > 0;) {
      result.push(Math.round(Math.random() * to + from))
    }

    result = [...new Set(result)]

    let length = result.length

    while (len - length > 0) {
      result = [...new Set(result.concat(fn(len - length, from, to)))]
      length = result.length
    }
  }
  

  return result
}
Copy the code

Of course, this function lacks many judgments: what happens when from is larger than to? What if I pass negative numbers? What about decimal numbers? What happens when bigint and number are mixed? What happens when len is bigger than to-from? These are not here to waste space to one by one package, you can be interested in the words to encapsulate their own.

use

Do you think that this function has little use other than being able to do an in-person test? Not really! After finishing this question, I immediately remembered the question and answer module of the teacher when I was doing the cultural experience table of Qingdao Bank:

The cultural experience table can be arrived in Qingdao bank doing business friends in the process of waiting for not so boring, especially those with kids to customers, in the propaganda of shandong culture at the same time slots, by the way the two ads earn extra money (they earn is not I make), the module initially back-end let me choose generation problem is sent him out of the analects of Confucius, his entry into the database, And then I ask for 10 questions at random. Later he was really too busy, said anyway not a few questions, let me write all in front of their own random access!

So casually find some of the Analects of Confucius into it, then the next is the algorithm, the user certainly do not want to go in each time is exactly the same ten questions, at least with some randomness, right? At that time, I was in a hurry. I didn’t write the algorithm well. I just wrote a simple version:

const arr = ['questions'.'questions'.'questions'.'questions']

const result = arr.filter(() = > Math.random() > 0.5)

result.length = 10
Copy the code

This is a requirement, but it is not rigorous. The result is that the questions at the top of the array will appear more often, and the questions at the bottom of the array will be less likely to appear.

const arr = [0.1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20]

const fn = num= > {
  const result = arr.filter(() = > Math.random() > 0.5)
  result.length = num
  return result
}
Copy the code

Running result:

As you can see, the later numbers are less likely to appear, but the first few digits do appear frequently, with 0(question 1) or 1(question 2) almost all the time, and the last question in most cases does not even have a chance to appear.

But because at that time every day overtime into the early morning, tired no energy to think about the algorithm, looked for library, like Lodash, Underscore and other library surface also did not find a way to achieve similar functions, so the first so, and so on the test said there are problems when to change it! Getting the software done first is the most important thing. But no one found out about it, except me (and now you do!). , heaven knows, you know I know, do not go to Qingdao bank to say with others!

Of course, with the function of our previous interview questions, all this will be solved, and the generated random questions will be very balanced, there will not be a high chance of the first three questions, the last three questions can be met by chance! If you are in front of the screen or in Qingdao area, you can go to the Bank of Qingdao to see, try the teacher question is not there will be this situation.

If you ask me clearly write out the algorithm why not replace the cultural experience table algorithm in Qingdao Bank? Because already left! I have no authority to touch this project again, and my colleagues in Qingdao have all withdrawn, and the contract between the company and the Qingdao Bank has been finished. The leader of Party A was also satisfied with the acceptance and did not put forward any suggestions for rectification, so the project has been successfully concluded.

I can only bury the flaws of that algorithm in the years, here to tell you.

This article was published on the official account “Front-end Learning does not Move”.

Previous excellent article

  • Create your own Visual Data Map without any libraries
  • A fun new feature of Vue: Introducing JS variables into CSS
  • What? Can you pull and pull with just the H5 TAB?
  • Microsoft launches comments section on GitHub
  • Vue 3.0.3: New CSS variable passing and the latest Ref Proposal
  • “Double 11 small black box is cool? Let’s use CSS variables to improve!”
  • “Don’t underestimate the nine grid, one question can let a candidate reveal his true colors!”
  • “Mobile Layout Interview Questions to test your CSS Skills (Center)”
  • A series of confusing behaviors after setting prototype Objects as Proxies
  • Vue’s Super Fun New Feature: DOM Portal
  • “Use of React’s Super-popular CSS-in-JS Library in the Vue Project: Styled – Components”
  • Is It Finally Vue’s Turn to Inspire React?
  • A Small Pit in Vue3 on IOS
  • Hooks use of the New VUe-Router
  • React 17 is officially a transition version!
  • Yu Yuxi: The Design Process of Vue3
  • The Father of Node’s refactoring Deno is finally released. Will it Replace Node after all?