preface
Article reprinted: Le Byte
Do you still remember that I met with 6 companies in a day and finally rejected all the men from big factories? Yes, I did. After a delay of one and a half months, we met again. This article sorted out the interview questions appeared during the recent interview of Brother Shark and detailed explanation of the answer difficulty is divided into three types of simple and medium difficulty. We can test ourselves without looking at the answer. If you have different views on the answer, welcome to discuss in the comments section. Finally, welcome to click the link to join the shark brother’s front group push discussion technology to touch fish for help
If you think this article is helpful, please remember to like three lian Oh, thank you very much!
simple
1 Complete the whole process of rendering from entering a URL address to the browser
This is a classic question that has been asked for a long time
- Enter the URL in the browser address bar and press Enter
- The browser looks up whether the current URL is cached and compares whether the cache is expired
- The DNS resolves the IP address of the URL
- Establishing a TCP connection based on IP (three-way handshake)
- Sending an HTTP request
- The server processes the request and the browser accepts the HTTP response
- The browser parses and renders the page
- Closing the TCP connection (four-way handshake)
Attention! This question can be used as a starting point for a variety of topics, from HTTP web knowledge to browser principles to front-end performance optimization
So I recommend you take a look at one of the most detailed interview questions ever written from typing the URL to seeing the page what happens?
2 What is event broker (event delegate) and what are the benefits
The idea behind event delegation is that instead of setting event listeners on each child node, you set event listeners on its parent node and then set each child node using the bubbling principle.
Advantages:
- In JavaScript, the number of event handlers added to the page is directly related to the overall performance of the page, because the more dom manipulation is required, the more likely it is to cause browser redraw and reflow, and the longer the page interaction events become. That’s why you want to reduce dom manipulation. Each event handler is an object, and each additional event handler takes up more space in memory. If you want to use the event delegate, you will put all the operations into the JS program, only to its parent level operation, and dom operation only need to interact once, so that can greatly reduce the number of interactions with DOM, improve performance;
- Dynamically bound events because the event is bound to the parent element, new elements can fire the same event
The default addEventListener is capture or bubble
The default is bubbling
The third argument to addEventListener defaults to false to perform event bubbling.
When true, the event capture behavior is performed.
How do browsers create new render layers
In the DOM tree, each node corresponds to a RenderObject. When their rendering objects are in the same coordinate space (z-axis space), a RenderLayers will be formed, which is also called the rendering layer. The rendering layer ensures that the page elements are stacked in the correct order, which is when composite layers are created to properly handle the display of transparent and overlapping elements. This process is especially important for pages with overlapping elements, because if the layers are merged in the wrong order, the elements will display incorrectly.
How does the browser create a new rendering layer
- The root document
- Have clear positioning attributes (relative, fixed, sticky, absolute)
- opacity < 1
- It has the CSS fliter property
- The CSS mask property is available
- Has the CSS mix-blending-mode property and the value is not normal
- Has a CSS transform property and is not None
- Backface -visibility property is hidden
- CSS Reflection property
- It has the CSS column-count attribute and the value is not auto or it has the CSS column-width attribute and the value is not auto
- Currently, animations are applied to opacity, Transform, fliter, and backdrop filter
- The overflow is not visible
Attention! Many people confuse the conditions of the compositing layer with those of the rendering layer. These two conditions occur in two different layers and are completely different. See this article for details on browser compositing and page rendering optimization
5 Differences between WebPack Plugin and Loader
- Loader: Used to convert module source code. Loader describes how Webpack handles non-javascript modules and introduces these dependencies into BULD. Loader can convert files from different languages (such as TypeScript) to JavaScript, or convert inline images to data urls. For example, CSS-loader, style-loader and so on.
- The Plugin is designed to do something else that Loader can’t, and it works directly on WebPack to extend its functionality. A number of events are broadcast during the life cycle of a WebPack run, and the Plugin can listen for these events and change the output when appropriate through the API provided by WebPack. Plug-ins range from packaging optimization and compression to redefining variables in the environment. Plug-in interfaces are extremely powerful and can be used to handle a wide variety of tasks.
Webpack related knowledge can see shark brother this article front-end advanced high salary must see -Webpack said very easy to understand the basic response to a simple interview is enough
B: Apply, call, and bind
- All three can change the function’s this object.
- The first argument in all three cases is the object to which this refers. If there is no argument or the argument is undefined or null, it points to the global window by default.
- All three can be passed, but apply is an array, call is a list of parameters, and apply and call are passed once, while bind can be passed multiple times.
- Bind is a function that returns after binding this for later call; Apply and call are executed immediately.
- Bind () returns a new function, and if the new function is used as a constructor to create a new object, this no longer points to the first argument passed to Bind, but to the instance created with new
Attention! Many students may overlook the fact that the bind function is used as a constructor for new instantiation
Give practical examples of closures
For example, the common anti-shake throttling
Function debounce(fn, delay = 300) {let timer; Return function () {const args = arguments; if (timer) { clearTimeout(timer); } timer = setTimeout(() => { fn.apply(this, args); }, delay); }; }Copy the code
Block-level scopes can be simulated in JavaScript using closures
function outputNumbers(count) { (function () { for (var i = 0; i < count; i++) { alert(i); }}) (); alert(i); // Cause an error! }Copy the code
Closures can be used to create private variables in objects
var aaa = (function () { var a = 1; function bbb() { a++; console.log(a); } function ccc() { a++; console.log(a); } return {b: BBB, //json structure c: CCC,}; }) (); console.log(aaa.a); //undefined aaa.b(); //2 aaa.c(); / / 3Copy the code
8 How is the CSS priority calculated
- First priority:! Important overrides element styles anywhere on the page
- 1. Inline style, for example, style=”color: green”, weight: 1000
- 2.ID selectors, such as #app, have a weight of 0100
- 3. Class, pseudo-class, attribute selector, such as. Foo, :first-child, div[class=”foo”], weight 0010
- 4. Tags and pseudo-element selectors, such as div::first-line, have a weight of 0001
- 5. Wildcard, subclass selector, sibling selector, such as *, >, +, weight is 0000
- 6. Inherited styles have no weights
9. Event loop questions — Mandatory (usually code output order judgment)
setTimeout(function () { console.log("1"); }, 0); async function async1() { console.log("2"); const data = await async2(); console.log("3"); return data; } async function async2() { return new Promise((resolve) => { console.log("4"); Resolve ("async2 result "); }).then((data) => { console.log("5"); return data; }); } async1().then((data) => { console.log("6"); console.log(data); }); new Promise(function (resolve) { console.log("7"); // resolve() }).then(function () { console.log("8"); });Copy the code
Result: 247536 Async2 result 1
Attention! I buried a pit in the last Promise, and I didn’t call the resolve method. I met this pit in the interview of Meituan. At that time, I didn’t see it clearly and thought it was the same routine
10 HTTP Status code 204 301 302 304 400 401 403 404 Meaning
- HTTP status code 204 (no content) The server successfully processed the request, but did not return anything
- The page requested by HTTP status code 301 (permanent move) has been permanently moved to a new location. When the server returns this response (a response to a GET or HEAD request), it automatically forwards the requester to the new location.
- HTTP Status Code 302 (Temporary mobile) The server is currently responding to requests from web pages in different locations, but the requester should continue to use the original location for future requests.
- HTTP Status code 304 (unmodified) The requested page has not been modified since the last request. When the server returns this response, the web page content is not returned.
- HTTP status code 400 (error request) The server does not understand the syntax of the request (usually parameter error).
- HTTP status code 401 (unauthorized) requests require authentication. The server may return this response for a web page that requires login.
- HTTP status code 403 (Forbidden) The server rejects the request. (Generally, the user permission of the client is insufficient.)
- HTTP status code 404 (Not found) The server could not find the requested web page.
What improvements did HTTP2.0 make to 3.0
Http2.0 features are as follows
- Binary frame transmission
- multiplexing
- The head of compression
- Server push
Http3.0 is a complete change from Http2.0!
HTTP is an application-layer protocol built on top of the transport layer. We all know that TCP is not the only protocol at the transport layer, but there is another powerful protocol, UDP. Both 2.0 and 1.0 are based on TCP, so they both have the same vulnerabilities and limitations as TCP. Http3.0 is built on top of UDP. So it’s qualitatively different from Http2.0.
Http3.0 features are as follows
- Connect the migration
- No queue head is blocked
- Custom congestion control
- Forward safety and forward error correction
I encourage you to take a closer look at some of the thoughts on Http2.0 and the advantages of Http3.0
12 What are the values of position
- Static Static (without position) is the default value for position, and the element is in normal document flow, ignoring the left, top, right, bottom, and Z-index attributes.
- Relative Is the position of an element relative to its original position. The element is not removed from the flow of the document, so the original position of the element is preserved and the position of other elements is not affected. Usage scenario: Child element is positioned relative to parent element
- Absolute Absolute refers to the setting of an absolute position on an element. Objects that are relatively located can be divided into two situations: Element with absolute If there is an ancestor element with position set to relative or absolute, then the element’s location object is the ancestor element with position set. If the ancestor element of the position attribute is not set, then the position is positioned relative to the body. Use scenario: Follow the icon Icon uses the absolute and margin attributes independent of the positioning parent, so that the position of the icon can be adjusted when the number of characters in the text changes
- Fixed can simply be said to be a special version of absolute, fixed elements are always positioned relative to the body. Usage scenario: sidebar or AD graphics
- Inherit inherits the position property of the parent element, but note that Internet Explorer 8 and previous versions do not support inherit.
- If a sticky element is set, its position will not be affected by its location in viewport (top, left and other attributes are invalid). When the element is about to move out of the offset range, its location will be changed to fixed. Set the left and top properties to a fixed position. When an element is rolled past a specified offset value, it is fixed to the specified position within the container. That is, if you set top: 50px, the sticky element will be fixed when it reaches 50px at the top of the relative positioned element and will no longer move upwards. Usage scenario: Follow the window
13. Implementation of vertical horizontal center
This is basically a CLASSIC CSS problem but there are already a lot of generic answers on the Internet if you want to score points on this problem
Many different schemes can be implemented for fixed and variable width heights
I suggest you look directly at the interviewer: How many horizontal, vertical and middle layouts can you achieve (fixed width and variable height)
14 What are the communication methods of VUE components
- The props and EMIT parent components pass data to the child components via prop, the child components pass data to the parent components via PROP, the child components pass data to the parent components via prop, and the emit parent components pass data to the child components via prop, The child component passes data to the parent component by emitting an event
- The parent, the parent, the parent and children takes the current components of the parent component and the current component child components
- Attrs and listeners A->B->C Vue 2.4 starts with attrs and attrs and attrs and Listeners to address this problem
- Variables are provided by provide in the parent component and injected by inject in the child component. (Officially not recommended for use in real business, but commonly used when writing component libraries)
- $refs gets the component instance
- The envetBus sibling can use the event bus approach for data transfer in this case
- Vuex status management
15 Vue response principle
The whole idea is data hijacking + observer mode
Attributes are internally hijacked using object.defineProperty (only existing attributes are hijacked) via the defineReactive method, while arrays are done by overriding array methods. When a page uses a corresponding attribute, each attribute has its own DEP attribute, which stores the watcher it depends on (dependent collection). When the attribute changes, the corresponding Watcher will be notified to update (distributed update).
The relevant codes are as follows
Class Observer {// Constructor (value) {this.walk(value); } walk(data) {let keys = object.keys (data); for (let i = 0; i < keys.length; i++) { let key = keys[i]; let value = data[key]; defineReactive(data, key, value); Function defineReactive(data, key, value) {observe(value); function defineReactive(data, key, value) {observe(value); // Recursion key // -- if the value is still an object, the odefineReactive loop continues until the value is not an object. Object.defineproperty (data, key, {get() {console.log(" get value "); Return value; return value; }, set(newValue) { if (newValue === value) return; Console. log(" Set value "); Value = newValue; }}); } export function observe (value) {/ / and if the Object or array of attributes to hijack the if (Object. The prototype. ToString. Call (value) = = = "[Object Object]" || Array.isArray(value) ) { return new Observer(value); }}Copy the code
The principle of responsive data explains the portal
16 Vue nextTick principle
The callbacks in nextTick are deferred callbacks that are executed after the next DOM update cycle ends. Use this method immediately after modifying the data to get the updated DOM. The main idea is to invoke asynchronous methods to execute nextTick wrapped methods in a microtask-first manner
The relevant codes are as follows
let callbacks = []; let pending = false; function flushCallbacks() { pending = false; For (let I = 0; i < callbacks.length; i++) { callbacks[i](); } } let timerFunc; // Define asynchronous methods that gracefully degrade if (typeof Promise! Const p = promise.resolve (); timerFunc = () => { p.then(flushCallbacks); }; } else if (typeof MutationObserver ! == "undefined") {// let counter = 1; const observer = new MutationObserver(flushCallbacks); const textNode = document.createTextNode(String(counter)); observer.observe(textNode, { characterData: true, }); timerFunc = () => { counter = (counter + 1) % 2; textNode.data = String(counter); }; } else if (typeof setImmediate ! Setimerfunc = () => {setImmediate(flushCallbacks); }; } else {setTimeout timerFunc = () => {setTimeout(flushCallbacks, 0); }; } export function nextTick(cb) {// In addition to rendering watcher, the nextTick is collected in the array callbacks.push(cb); if (! Pending) {// If the nextTick is called multiple times, it will only execute one async call until the async queue is empty and then change the flag to false pending = true; timerFunc(); }}Copy the code
NextTick principle explains the portal
17 Principles of Vue Diff
It is recommended to look directly at the DIff algorithm to solve the portal
18 Routing Principles Features of history and Hash routing modes
Hash pattern
- The value of location.hash is exactly what comes after the # in the URL. It’s nice to see that the hash appears in the URL, but it’s not included in the HTTP request. It doesn’t affect the back end at all, so changing the hash doesn’t reload the page.
- You can add listening events for changes to the hash
window.addEventListener("hashchange", funcRef, false);
Copy the code
Each change to the hash (window.location.hash) adds a record to the browser’s access history. Using the above features of the hash, we can implement the front-end routing “update the view without rerequesting the page” function
Features: Good compatibility but not beautiful
The history mode
Takes advantage of the new pushState() and replaceState() methods in the HTML5 History Interface.
These two methods apply to the browser’s history station and provide the ability to modify the history in addition to the existing back, Forward, and Go methods. The two methods have a common feature: when they are called to modify the browser history stack, the browser does not refresh the page even though the current URL has changed, which provides the basis for single-page application front-end routing “update the view without rerequesting the page.”
Features: Although beautiful, but refresh will appear 404 needs to be configured on the back end
19 handwritten bind
/ / bind implementation is a little complex Because he considered the situation more Also involves the parameter (similar Function curry) Function. The prototype. MyBind = Function (context,... args) { if (! context || context === null) { context = window; } // create a unique key for the internal method name of the context we construct. context[fn] = this; let _this = this; // bind const result = function (... InnerArgs) {// If we use the new operator as a constructor, we do not bind this. The new operator calls this to the result instance, which in turn inherits from _this.__proto__ === result.prototype //this instanceof result =>true // this.__proto__.__proto__ === result.prototype.__proto__ === _this.prototype; //this instanceof _this =>true if (this instanceof _this === = true) {if (this instanceof _this === true) _this; this[fn](... [...args, ...innerArgs]); Bind: delete this[fn]; } else {// If it is called as a normal function then it is very simple to change this to refer to the passed context context[fn](... [...args, ...innerArgs]); delete context[fn]; }}; Create result.prototype = object.create (this.prototype); return result; }; // function Person(name, age) {// console.log(name); // console.log(age); // console.log(this); // constructor this points to the instance object //} // // constructor prototype method // person.prototype. say = function() {// console.log(123); // let obj = {// objName: 'I am the name of obj ', // objAge: // function normalFun(name, age) {// console.log(name); // console.log(age); // console.log(this); // The normal function this points to the first argument to bind, which in our example is obj // console.log(this.objname); // console.log(this.objage); // console.log(this.objage); // let bindFun = person.mybind (obj, 'I am the name of the parameter passed in ') // let a = new bindFun(' I am the age of the parameter passed in ') // a.say() //123 // test again as a normal function call // let bindFun = Normalfun. myBind(obj, 'I am the name passed in ') // bindFun(' I am the age passed in ')Copy the code
19 Handwritten promise. All and Race (JINGdong)
Static all(promiseArr) {let result = []; // declare a count for each promise return with let count = 0; return new Mypromise((resolve, reject) => { for (let i = 0; i < promiseArr.length; Promise.resolve(promiseArr[I]). Then ((res) => {// We can't push the array directly Result [I] = res; count++; If (count === promise.length) {resolve(result); } }, (err) => { reject(err); }); }}); } static race(promiseArr) {return new Mypromise((resolve, reject) => {for (let I = 0; i < promiseArr.length; I ++) {promise.resolve (promiseArr[I]). Then ((res) => {// Resolve (res); }, (err) => { reject(err); }); }}); }}Copy the code
20 handwriting – implement a parasitic combination inheritance
function Parent(name) {
this.name = name;
this.say = () => {
console.log(111);
};
}
Parent.prototype.play = () => {
console.log(222);
};
function Children(name) {
Parent.call(this);
this.name = name;
}
Children.prototype = Object.create(Parent.prototype);
Children.prototype.constructor = Children;
// let child = new Children("111");
// // console.log(child.name);
// // child.say();
// // child.play();
Copy the code
21 Handwritten -new operator
function myNew(fn, ... args) { let obj = Object.create(fn.prototype); let res = fn.call(obj, ... args); if (res && (typeof res === "object" || typeof res === "function")) { return res; } return obj; // // function Person(name, age) {// // this.name = name; // // this.age = age; // // } // // Person.prototype.say = function() { // // console.log(this.age); / / / /}; // // let p1 = myNew(Person, "lihua", 18); // // console.log(p1.name); // // console.log(p1); // // p1.say();Copy the code
22 handwritten -setTimeout simulation setInterval (Ali)
function mySetInterval(fn, time = 1000) {
let timer = null,
isClear = false;
function interval() {
if (isClear) {
isClear = false;
clearTimeout(timer);
return;
}
fn();
timer = setTimeout(interval, time);
}
timer = setTimeout(interval, time);
return () => {
isClear = true;
};
}
// let a = mySettimeout(() => {
// console.log(111);
// }, 1000)
// let cancel = mySettimeout(() => {
// console.log(222)
// }, 1000)
// cancel()
Copy the code
23 Handwriting – Publish subscribe mode (bytes)
class EventEmitter { constructor() { this.events = {}; } // Implement subscription on(type, callBack) {if (! this.events[type]) { this.events[type] = [callBack]; } else { this.events[type].push(callBack); }} // Delete subscription off(type, callBack) {if (! this.events[type]) return; this.events[type] = this.events[type].filter((item) => { return item ! == callBack; }); Function fn() {callBack(); function fn() {callBack(); this.off(type, fn); } this.on(type, fn); } // Emit the event emit(type,... rest) { this.events[type] && this.events[type].forEach((fn) => fn.apply(this, rest)); // Const event = new EventEmitter(); // const handle = (... rest) => { // console.log(rest); / /}; // event.on("click", handle); // event.emit("click", 1, 2, 3, 4); // event.off("click", handle); // event.emit("click", 1, 2); // event.once("dbClick", () => { // console.log(123456); / /}); // event.emit("dbClick"); // event.emit("dbClick");Copy the code
24 handwriting – Anti shake throttling (JD)
// 防抖
function debounce(fn, delay = 300) {
//默认300毫秒
let timer;
return function () {
const args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, args); // 改变this指向为调用debounce所指的对象
}, delay);
};
}
window.addEventListener(
"scroll",
debounce(() => {
console.log(111);
}, 1000)
);
// 节流
// 设置一个标志
function throttle(fn, delay) {
let flag = true;
return () => {
if (!flag) return;
flag = false;
timer = setTimeout(() => {
fn();
flag = true;
}, delay);
};
}
window.addEventListener(
"scroll",
throttle(() => {
console.log(111);
}, 1000)
);
Copy the code
25 Handwriting – Converting a virtual Dom to a real Dom (similar recursion questions – Required)
{ tag: 'DIV', attrs:{ id:'app' }, children: [ { tag: 'SPAN', children: [ { tag: 'A', children: [] } ] }, { tag: 'SPAN', children: [ { tag: 'A', children: [] }, { tag: 'A', children: []}}}]] to appeal the virtual real Dom Dom into below < div id = "app" > < span > < a > < / a > < / span > < span > < a > < / a > < a > < / a > < / span > < / div >Copy the code
The answer
Function _render(vnode) {if (typeof vnode === "number") {vnode = String(vnode); Return document.createTextNode(vnode); if (typeof vNode === "string") {return document.createTextNode(vnode); } // const DOM = document.createElement(vnode.tag); If (vnode.attrs) {// Traversing the attribute object.keys (vnode.attrs).foreach ((key) => {const value = vnode.attrs[key]; dom.setAttribute(key, value); }); } vnode.children.foreach ((child) => dom.appendChild(_render(child))); return dom; }Copy the code
26 Handwriting – Implementing the Flatten Method for an object (Ali)
Topic describes
Const obj = {a: {b: 1, 2: c, d: {e: 5}}, b: [1, 3, 3} {2, a: b:], c: 3} flatten (obj) results returned the following / / {/ / 'a.' : 1, // 'a.c': 2, // 'a.d.e': 5, // 'b[0]': 1, // 'b[1]': 3, // 'b[2].a': 2, // 'b[2].b': 3 // c: 3 // }Copy the code
The answer
function isObject(val) { return typeof val === "object" && val ! == null; } function flatten(obj) { if (! isObject(obj)) { return; } let res = {}; const dfs = (cur, prefix) => { if (isObject(cur)) { if (Array.isArray(cur)) { cur.forEach((item, index) => { dfs(item, `${prefix}[${index}]`); }); } else { for (let k in cur) { dfs(cur[k], `${prefix}${prefix ? "." : ""}${k}`); } } } else { res[prefix] = cur; }}; dfs(obj, ""); return res; } flatten();Copy the code
27 Handwriting – Check whether the parenthesis string is valid (mi)
Topic describes
Given a only include a '(',') ', '{','} ', '/', ' 'the string s, determine whether a string is effective. A valid string must meet the following requirements: The left parenthesis must be closed with the same type of the right parenthesis. The left parentheses must be closed in the correct order. Example 1: Input: s = "()" Output: true Example 2: Input: s = "()[]{}" Output: true Example 3: Input: s = "(]" Output: falseCopy the code
The answer
const isValid = function (s) { if (s.length % 2 === 1) { return false; } const regObj = { "{": "}", "(": ")", "[": "]", }; let stack = []; for (let i = 0; i < s.length; i++) { if (s[i] === "{" || s[i] === "(" || s[i] === "[") { stack.push(s[i]); } else { const cur = stack.pop(); if (s[i] !== regObj[cur]) { return false; } } } if (stack.length) { return false; } return true; };Copy the code
28 Handwriting – Find array public Prefix (Meituan)
Topic describes
Write a function to find the longest public prefix in an array of strings. Returns the empty string "" if no public prefix exists. Example 1: Input: STRS = ["flower","flow","flight"] Output: "FL" Example 2: Input: STRS = ["dog","racecar","car"] Output: "" Description: The input does not have a public prefix.Copy the code
The answer
const longestCommonPrefix = function (strs) { const str = strs[0]; let index = 0; while (index < str.length) { const strCur = str.slice(0, index + 1); for (let i = 0; i < strs.length; i++) { if (! strs[i] || ! strs[i].startsWith(strCur)) { return str.slice(0, index); } } index++; } return str; };Copy the code
29 Handwritten – The longest non-repeating substring of a string
Topic describes
Given a string s, find the length of the smallest string that does not contain repeating characters. Example 1: Input: s = "abcabcbb" Output: 3 Explanation: Since the oldest string without repeating characters is "ABC", its length is 3. Example 2: Input: s = "BBBBB" Output: 1 Explanation: Since the oldest string without repeating characters is "b", its length is 1. Example 3: Input: s = "pwwkew" Output: 3 Explanation: Since the oldest string without repeating characters is "wKE", its length is 3. Note that your answer must be the length of the substring, "pwke" is a subsequence, not a substring. Example 4: Input: s = "" Output: 0Copy the code
The answer
const lengthOfLongestSubstring = function (s) {
if (s.length === 0) {
return 0;
}
let left = 0;
let right = 1;
let max = 0;
while (right <= s.length) {
let lr = s.slice(left, right);
const index = lr.indexOf(s[right]);
if (index > -1) {
left = index + left + 1;
} else {
lr = s.slice(left, right + 1);
max = Math.max(max, lr.length);
}
right++;
}
return max;
};
Copy the code
30 handwriting – How to find the first smallest positive integer in an array that does not appear how to optimize (bytes)
Given an unsorted integer array nums, find the smallest positive integer that does not appear in it. You implement a solution with O(n) time complexity and use only constant level extra space. Example 1: input: nums = [1,2,0] output: 3 example 2: input: nums = [3,4,-1,1] output: 2 example 3: input: nums = [7,8,9,11,12] output: 1Copy the code
This is a bit of an algorithm problem that is constantly trying to optimize the idea of the algorithm
- The first version O(n^2) method
const firstMissingPositive = (nums) => {
let i = 0;
let res = 1;
while (i < nums.length) {
if (nums[i] == res) {
res++;
i = 0;
} else {
i++;
}
}
return res;
};
Copy the code
- The second edition is O(n) in time and space.
const firstMissingPositive = (nums) => { const set = new Set(); for (let i = 0; i < nums.length; i++) { set.add(nums[i]); } for (let i = 1; i <= nums.length + 1; i++) { if (! set.has(i)) { return i; }}};Copy the code
- The final version has O(n) time complexity and uses only constant level space
const firstMissingPositive = (nums) => { for (let i = 0; i < nums.length; I ++) {while (nums[I] >= 1 && nums[I] <= nums.length && // arrange nums[I] -1]! Const temp == nums[I] // const temp = nums[I] -1; Nums [I] -1] = nums[I]; nums[i] = temp; }} // now expect [1,2,3...] For (let I = 0; i < nums.length; i++) { if (nums[i] ! = i + 1) { return i + 1; } } return nums.length + 1; // find element 1~nums.length full array};Copy the code
31 Handwriting – how many ways to generate a non-repeating random number set of length N in the data source time complexity (bytes)
- First version time complexity O(n^2)
function getTenNum(testArray, n) {
let result = [];
for (let i = 0; i < n; ++i) {
const random = Math.floor(Math.random() * testArray.length);
const cur = testArray[random];
if (result.includes(cur)) {
i--;
break;
}
result.push(cur);
}
return result;
}
const testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
const resArr = getTenNum(testArray, 10);
Copy the code
- Second edition tokenization/custom attribute method time complexity O(n)
function getTenNum(testArray, n) { let hash = {}; let result = []; let ranNum = n; while (ranNum > 0) { const ran = Math.floor(Math.random() * testArray.length); if (! hash[ran]) { hash[ran] = true; result.push(ran); ranNum--; } } return result; } const testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]; const resArr = getTenNum(testArray, 10);Copy the code
- The time complexity of the third edition switching method is O(n)
function getTenNum(testArray, n) {
const cloneArr = [...testArray];
let result = [];
for (let i = 0; i < n; i++) {
debugger;
const ran = Math.floor(Math.random() * (cloneArr.length - i));
result.push(cloneArr[ran]);
cloneArr[ran] = cloneArr[cloneArr.length - i - 1];
}
return result;
}
const testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
const resArr = getTenNum(testArray, 14);
Copy the code
It’s worth mentioning that swapping is a common idea in algorithms when you’re dealing with arrays
- The time complexity of traversal and deletion in the final version is O(n)
function getTenNum(testArray, n) {
const cloneArr = [...testArray];
let result = [];
for (let i = 0; i < n; ++i) {
const random = Math.floor(Math.random() * cloneArr.length);
const cur = cloneArr[random];
result.push(cur);
cloneArr.splice(random, 1);
}
return result;
}
const testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
const resArr = getTenNum(testArray, 14);
Copy the code
medium
1 what are the optimization methods of Webpack
As the project becomes larger and larger, the Webpack construction speed may become slower and slower, and the size of the JS built becomes larger and larger. In this case, the configuration of Webpack needs to be optimized
This knowledge can be a separate article, please see take you deep unlock Webpack series (optimization)
2 How can I Enable Hardware Acceleration of the CSS (GPU Acceleration)?
The browser will use GPU rendering when processing the CSS below
- Transform (GPU acceleration is used when 3D transform styles appear)
- opacity
- filter
- will-change
Use transform: translateZ(0) use transform: translate3D (0, 0, 0) using the WILL-change property of CSS. Will-change can be set to opacity, transform, top, left, bottom, and right.Copy the code
Attention! Layer of explosion, for some reason may lead to a large number of composite layer, not in expected despite the browser layer compression mechanism, but also has a lot of cannot be compressed, this layer of explosion phenomena may appear (simple understanding is that many don’t need to be upgraded to synthetic layer elements for some improper operation became the composite layer). To solve the problem of layer explosion, the best solution is to break the condition of overlap, that is to say, let other elements not overlap with the elements of composite layer. Simple and direct way: when using 3D hardware acceleration to improve animation performance, it is best to add a Z-index attribute to the element, artificial interference composition of the sorting, can effectively reduce the creation of unnecessary layers of composition, improve rendering performance, especially mobile optimization effect.
3 Common design modes and application scenarios are provided
1. Factory mode – Create instance by passing in parameters
The virtual DOM returns the Vnode of the base tag and the component Vnode depending on the parameter
2. Singleton mode – There is only one instance of the entire program
The vuex and VUE-Router plug-in registration method install determines if there is an instance of the system directly return to the system
3. Publish-subscribe (VUE event mechanism)
4. Observer mode (Responsive data Principle)
5. Decorator mode: (@ decorator usage)
A policy pattern is when an object has a behavior that can be implemented differently in different scenarios – for example, a merge strategy of options
. Other modes are welcome
4 what is the browser cache policy (strong cache negotiated cache) and what is the process?
This is also a classic front-end cache problems add up to an article recommended to see the front-end browser cache knowledge comb
5 What is the HTTPS encryption process
A mixture of symmetric and asymmetric encryption is used
See the specific process of front-end advanced salary must see -HTTPS
6 Flex :1 which attributes are made up of
Flex is actually a contraction of flex-grow, Flex-shrink, and Flex-basis.
Flex-grow: defines the scale of the project;
The default value is 0, that is, it will not be enlarged even if there is free space. Flex-grow for all projects is 1: evenly divide the remaining space (auto zoom space placeholder); An item with flex-grow of N takes up n times as much space (magnification ratio) as an item with Flex-grow of 1.Copy the code
Flex-shrink: defines the shrink of a project;
The default is 1, which means that the project shrinks if there is insufficient space; The flex-shrink value is 1 for all projects: when space is insufficient, the amount of shrink is the same. If flex-shrink is 0, the project does not shrink when space is insufficient. A flex-shrink of N will shrink n times as much when space is insufficient as a Flex-shrink of 1.Copy the code
Flex-basis: Defines the main size of the project prior to allocating extra space. The browser uses this property to calculate whether there is extra space on the main axis
The default value is auto, the original size of the project; After setting, the project will occupy a fixed space.Copy the code
What does 304 mean? What is the status code returned by a strong cache hit
Negotiation cache hit returns 304
This approach uses two fields in the headers request header, last-modified & if-Modified-since. The server tells the browser when the resource was Last Modified via the last-modified response header:
Last-Modified: Thu, 20 Jun 2019 15:58:05 GMT
When the resource is requested again, the browser needs to confirm to the server that the resource is expired. This proof is the if-Modified-since field in the request header, which is the value of the last-Modified field in the response header in the previous request:
If-Modified-Since: Thu, 20 Jun 2019 15:58:05 GMT
The server checks if-modified-since in the request header when the browser sends a request, and returns 304 If the last modified time is the same. Otherwise, last-Modified is added to the response header and the response body is returned.
In addition, when the browser sends a request, the server checks the if-none-match value in the request header against the contents of the current file using a hash algorithm (such as nodejs) : Cryto.createhash (‘sha1’)) returns 304; otherwise, add the etag attribute to the current response header and return the content.
To sum up, it can be summarized as follows:
The last-Modified date of the request header is the same as the last-Modified date of the response header. The hash of the request header if-none-match is the same as the etag of the response headerCopy the code
Strong cache hit 200 200
8 handwritten Vue. Extend implementation
// src/global-api/initExtend.js import { mergeOptions } from ".. /util/index"; export default function initExtend(Vue) { let cid = 0; Extend = function (extendOptions) {// Create a constructor for the subclass and call the initialization method const Sub = function VueComponent(options) { this._init(options); // Call Vue initializer}; Sub.cid = cid++; Sub.prototype = Object.create(this.prototype); / / subclass prototype points to the parent class Sub. The prototype. The constructor = Sub; //constructor points to yourself sub. options = mergeOptions(this.options, extendOptions); // merge your own options with your parent's Options Return Sub; }; }Copy the code
Specific can see this handwritten Vue2.0 source code (eight) – component principle
9 Vue-router Whether pushState and replaceState route methods trigger the popSate event
The answer is: no
PushState and replaceState
HTML5’s new interface allows you to change urls (with cross-domain restrictions) without refreshing the page, a powerful feature that was later used in single-page applications such as jue-router and React-router-dom.
Note: just by changing the url, the page does not actually jump and no new content is retrieved, essentially the page remains the same
window.history.pushState(state, title, targetURL); @ status object: indicates the information sent to the destination route. It can be empty. @ Page title: is not supported by all browsers and can be filled with a blank string. If you don't pass the, that is, add data to the current url window. History. ReplaceState (state, title, targetURL); @ is similar to pushState, but replaces the current URL without being recorded in historyCopy the code
The popState event is emitted when the back or forward buttons are clicked (or when the history.back(), history.forward(), or history.go() methods are called)
Note: Using history.pushState() or history.replacEstate () does not trigger the popState event
What is tree shaking
Tree shaking is a technique for optimizing the packaging volume of a project by removing redundant code, known as Dead Code Elimination
What does Tree shaking work for?
ES6 Module introduces static analysis, so when compiling, it can correctly determine which Module static analysis program flow is loaded, determine which modules and variables are not used or referenced, and then delete the corresponding codeCopy the code
Extensions: What are the differences between common.js and es6 module introductions?
CommonJS is a module specification that was originally applied to Nodejs as the module specification for Nodejs. JavaScript running on the browser side also lacks a similar specification, so before ES6 came out, the same module specification was implemented on the front end (e.g. AMD) to manage the front end modules. Since ES6, a new ES6 Module specification has been introduced, which implements Module functions at the level of language standards and is quite simple to implement. It is expected to become a common Module solution for browsers and servers. However, ES6 Module is not compatible with browsers at present. Export and import that we usually use in Webpack will be converted to CommonJS by Babel. The main differences in use are:
CommonJS module outputs a copy of a value, ES6 module outputs a reference to a value.
2, CommonJS module is run time load, ES6 module is compile time output interface (statically compiled).
3, CommonJs is a single value export, ES6 Module can export multiple
ES6 Module static syntax can only be written at the top level
5, CommonJs this is the current Module, ES6 Module this is undefined
11 What is Babel? Do you know how it works
Babel is a JavaScript compiler. It compiles the latest version of javascript into a currently executable version. In short, Babel allows us to freely use the new es6 and even ES7 syntax in our current projects.
The three main processing steps of Babel are: parse, transform and generate.
- Parsing parses code into abstract syntax trees (AST). Each JS engine (such as V8 in Chrome) has its own AST parser, and Babel is implemented through Babylon. In the parsing process, there are two stages: lexical analysis and syntax analysis. The lexical analysis stage transforms strings of code into a stream of tokens. Tokens are like nodes in the AST. The parsing phase converts a token flow into the AST form and converts the information in the token into the AST representation structure.
- At this stage, Babel receives the AST and performs depth-first traversal with babel-traverse, adding, updating, and removing nodes. This is where the Babel plug-in comes in.
- Generating transforms the transformed AST into JS code via babel-Generator by going depth-first through the AST and building a string that represents the transformed code.
For more information, see the Babel principle
12 Prototype chain judgment
Please write down the answers below
Object.prototype.__proto__;
Function.prototype.__proto__;
Object.__proto__;
Object instanceof Function;
Function instanceof Object;
Function.prototype === Function.__proto__;
Copy the code
Object.prototype.__proto__; //null
Function.prototype.__proto__; //Object.prototype
Object.__proto__; //Function.prototype
Object instanceof Function; //true
Function instanceof Object; //true
Function.prototype === Function.__proto__; //true
Copy the code
This topic deeply investigates the knowledge points related to prototype chain, especially the relationship between Function and Object
Function, Object, null, etc
13 What are RAF and RIC
RequestAnimationFrame: tells the browser to execute the incoming callback function (usually manipulating the DOM, updating the animation) before the next redraw Since it is executed once per frame, this results in the same number of executions per second as the number of browser screen refreshes, usually 60 per second.
RequestIdleCallback: : performs callbacks during browser idle time, which allows developers to perform low-priority tasks in the main event loop without affecting some later-critical events. If there are multiple callbacks, they are executed on a first-in, first-out basis, but when timeout is passed, it is possible to shuffle the order to avoid timeouts.
RequestIdleCallback and requestAnimationFrame details can be found in this article
difficult
1 Let implementation principle of Es6
Original ES6 code
var funcs = []; for (let i = 0; i < 10; i++) { funcs[i] = function () { console.log(i); }; } funcs[0](); / / 0Copy the code
Es5 code compiled by Babel (Polyfill)
var funcs = []; var _loop = function _loop(i) { funcs[i] = function () { console.log(i); }; }; for (var i = 0; i < 10; i++) { _loop(i); } funcs[0](); / / 0Copy the code
In fact, we can see from the results of Babel compilation that let uses closures and function scope to achieve block-level scope effect. In different cases, let compilation results are different
How to design and implement a rendering engine
This question is the last question of the end of the byte, which is an open question with no fixed answer. I felt that the concept of the question was too big and I was confused. I just answered the principle of browser rendering, it seems that the interviewer was not satisfied with it
Check out this article for details about browser page rendering that you don’t know
3. What is the specific implementation principle of require
Require basic principles
Require find path
Module. Exports = module. Exports = module. Exports = module. Exports = module. When I run this line of code and add the value of module.exports to the object with the key of the corresponding file name, the object looks like this:
{
"a.js": "hello world",
"b.js": function add(){},
"c.js": 2,
"d.js": { num: 2 }
}
Copy the code
When you require a file again, if the object has a value in it, it will be returned to you. If not, repeat the previous steps, execute the object and add its module.exports to the global object and return it to the caller. This global object is what we often hear about as a cache. So there’s nothing dark about require and Module. exports, they just run and get the value of the object file, add it to the cache, and pull it out of the cache.
For details, see this article delving into node.js’s module loading mechanism by writing the require function
4 Front-end performance positioning and optimization indicators
Front-end performance optimization has been a cliche of a technology, many people talk about performance optimization solutions, but the real for the performance analysis positioning and performance indicators of this part of the knowledge, so this problem is related to performance but the research point is how to carry out performance positioning and analysis of ordinary projects
- We can answer this in terms of front-end performance monitoring – buried points and window.performance related apis
- You can also use the Performance analysis tools Performance and Lighthouse
- You can also start with performance indicators such as LCP, FCP, FID, CLS, etc
Here are some performance related articles you can check out
5 minutes for a front-end performance monitoring tool
Talk about common performance indicators and reporting strategies for front-end performance optimization
Front-end performance optimization indicators + detection tools
summary
Shark elder brother more than face by just a start out of jade The front interview problems emerge in endlessly Let’s just remember that the answer is no Hope everyone eventually by the surface via the principle behind learn front end points Of course for social recruit students to master the principles of the front-end knowledge related topic is not enough It is very important for the social recruitment interview to show the past project experience and project highlights and difficulties. It is impossible to brush the questions or it depends on the continuous accumulation of practice in ordinary work to refuse to be a CV engineer. Finally, I wish you all get your satisfactory offer in the good days of golden nine silver ten oh ~~
Links to other interview questions series
- The most complete Vue interview questions + detailed answers
- Interview 6 big companies in one day – Offer me
- The most complete handwritten JS programming problem
Article reprinted: Le Byte
Shark’s front-end fishing skills
Welcome everyone technical exchange inside push touch fish help all may – link note: 75