GithubHelp home page GithubHelp logo

elemefe / node-interview Goto Github PK

View Code? Open in Web Editor NEW
10.5K 466.0 1.6K 804 KB

How to pass the Node.js interview of ElemeFE.

Home Page: https://elemefe.github.io/node-interview/

License: MIT License

HTML 100.00%
nodejs interview

node-interview's People

Contributors

achaabni avatar aiyogg avatar bodyno avatar cheogo avatar crispgm avatar dickeylth avatar godotdotdot avatar heanxu avatar heziqiang avatar huangxiaohuai avatar jiasm avatar lellansin avatar lijinke666 avatar marswong avatar matrixbirds avatar olegstotsky avatar qingwei-li avatar qqqian0819 avatar rustdreamer avatar shifengchen avatar sinchang avatar sodawy avatar stephenlyz avatar sublimeye avatar tauleos avatar webtaculars avatar yaokailun avatar yunyu950908 avatar zyszys avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-interview's Issues

Excellent program

This is an excellent program, I had learned a lot from it, and I hope the author can keep serializing 👍🏽

reduceAsync

Array.prototype.reduce = async function(callback, initValue) {
    const ctx = this;
    const len = this.length;
    let result = null;

    async function next(preValue, curValue, index, arr) {
        let temp = await callback(...arguments);
        if (index == len-1) return temp;
        return next(temp, ctx[index+1], index+1, ctx);
    }

    if (initValue) {
        result = await next(initValue, ctx[0], 0, ctx);
    } else {
        result = await next(ctx[0], ctx[1], 1, ctx);
    }
   
    return result;
}

// example
const arr = [1, 2, 3];
const sum = arr.reduce(async function(pre, cur) {
    const temp = await new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(pre + cur);
        }, 1000)
    })
    return temp;
});

sum.then(function(result) {
    console.log(result);
})

这么写可以不

对于内存释放的例子,感觉不是很好理解

对于内存释放的例子,感觉不是很好理解(每次都是一个例子)。不知道下面理解是否正确?
运行时添加 -expose-gc的node命令行参数。

https://github.com/ElemeFE/node-interview/blob/master/sections/js-basic.md#内存释放

// 错误
var theThing = null;
var replaceThing = function () {
    let 泄漏变量 = theThing;
    let unused = function () {
        if (泄漏变量)
            console.log("hi")
    };
    // 不断修改引用
    theThing = {
        longStr: new Array(1000000).join('*'),
        someMethod: function () {
            console.log('a')
        }
    };

    global.gc();
    // 每次输出的值会越来越大
    console.log(process.memoryUsage().heapUsed);
};
setInterval(replaceThing, 100);

正确修改1

// 正确
var theThing = null;
var replaceThing = function () {
    let unused = function () {
        if (theThing)
            console.log("hi")
    };
    // 不断修改引用
    theThing = {
        longStr: new Array(1000000).join('*'),
        someMethod: function () {
            console.log('a')
        }
    };

    global.gc();
    // 每次输出的值会保持不变
    console.log(process.memoryUsage().heapUsed);
};
setInterval(replaceThing, 100);

正确修改2

// 正确
var theThing = null;
var replaceThing = function () {
    let 泄漏变量 = theThing;
    let unused = function () {
        if (泄漏变量)
            console.log("hi")
    };
    // 不断修改引用
    theThing = {
        longStr: new Array(1000000).join('*'),
        someMethod: function () {
            console.log('a')
        }
    };

    泄漏变量 = null;
    // unused = null; // 不行匿名函数依然存在

    global.gc();
    // 每次输出的值会保持不变
    console.log(process.memoryUsage().heapUsed);
};
setInterval(replaceThing, 100);

模块章节中的一个问题

https://github.com/ElemeFE/node-interview/blob/master/sections/module.md#%E6%A8%A1%E5%9D%97%E6%9C%BA%E5%88%B6

“热更新”部分说“这里留下一个简单的问题, 既然可以通过新的上下文来避免污染, 那么为什么 Node.js 不给每一个.js文件以独立的上下文来避免作用域被污染?”

这里的答案是独立的上下文不会防止作用域被污染吧,因为node的vm模块创建的独立上下文中是可以访问到独立变量吧?

关于Io那个章节的一个问题

如何同步的获取用户的输入?那个问题中您写到:

而要同步读取, 则是不用异步的 read 接口, 而是用同步的 readSync 接口去读取 stdin 的数据即可实现.

从文档中可知Readable.read本来就是同步的,为何你说它是异步接口呢?

关于Events

url:https://elemefe.github.io/node-interview/#/sections/zh-cn/event-async
Events 中
有下面的描述

以及这样会不会死循环?

const EventEmitter = require('events');

let emitter = new EventEmitter();

emitter.on('myEvent', function sth () {
// 下面的代码是不是写错了?应该是 emitter.emit('myEvent')吧
  emitter.on('myEvent', sth);
  console.log('hi');
});

emitter.emit('myEvent');

能否再进一步解释一下,两种事件触发有啥区别?

将基础类型包装也不能以引用的方式传递

在引用传递的问题中

通过将基础类型包装(boxing) 可以以引用的方式传递.

虽然传递的是指向数字对象的引用复本,但我们并不能通过它来更改其中的基本类型值:

    function foo (x) {
      x = x + 1
      console.log(x) // 3 
    }

    var a = new Number(1) // Object(a)也一样

    foo(a)
    console.log(a) // 是2,不是3

Add website

This is a awesome project! If you use docsify to generate a website it may be easier to read.

I can submit a PR if you agree.

错别字

如果只是发现一个错别字的话,可以pull requests吗?

English version

It would be helpful to have an English version. If not, what is the reason for the english repo name and description?

同源策略解释有误

Network模块的问题:什么是跨域请求?如何允许跨域?答案存在错误。
https://github.com/ElemeFE/node-interview/blob/master/sections/zh-cn/network.md#q-cors
出于安全考虑, 默认情况下使用 XMLHttpRequest 和 Fetch 发起 HTTP 请求必须遵守同源策略, 即只能向相同域名请求. 向不同域名的请求被称作跨域请求 (cross-origin HTTP request). 可以通过设置 CORS headers 即 Access-Control-Allow- 系列来允许跨域.

同源是指:相同协议,相同域名,相同端口。

而不仅仅是相同域名。

关于nodeJs连接池有个问题

https://github.com/ElemeFE/node-interview/blob/master/sections/network.md#agent

这里有段话是说 【当 keepAlive 为 true 是, 由于 socket 复用, 之前的事件监听如果忘了清除很容易导致重复监听】实际上不管是true还是false只要使用了连接池(agent),而且实际连接数超过了maxSocket设置的上限的话,socket都会复用。keepalive选项开的话,实际调用的是socke.setKeepAlive。作用就是激活操作系统的tcp协议的keepalive功能,在keepAliveMsecs时间之后会由系统发送keepalive嗅探包,具体的间隔根据操作系统定义。剩下keepalive的操作就都交给操作系统了。

回复:`如何实现一个异步的 reduce?`

看到这里时,发现了有留下一个问题,好奇的写了下。
https://github.com/ElemeFE/node-interview/blob/master/sections/zh-cn/event-async.md#阻塞异步

(async () => {
  let getPromise = (key) => new Promise(resolve => {
    setTimeout(() => {
      console.log('reduce item:', key ** 2)
      resolve(key ** 2)
    }, 1000)
  })

  let reduceResolve = 

  console.log('reduce start')
  console.log('reduce result:', await [1, 2, 3, 4].reduce((result, cursor) => {
    return async () => {
      return await result() + await getPromise(cursor)
    }
  }, async () => 0)())
  console.log('reduce end')
})()

不知道是不是作者想要的结果呢。。。

[请教] : mongodb 的一个问题?

我是一个新手, 在平时开发中 不管是 mysql 的 Sequelize 库 还是 mongoose
比如一个简单的 查询

const find = async ()=> await MODEL.find({xx})

现在需要 遍历 改变一些数据

(await find()).map(  v=> v.cname = v.name )

发现没生效, 把这个 v 打印出来 发现 除了自己的数据之外 , 还有 mongoose 的一些 proto

于是我用很傻的方法

const data = JSON.parse(JSON.stringify(await find() ))

这样获取到数据 就是干净的
但如果我不 处理这个数据 直接 res.send(await find()) (express) 也是没问题的
这是为什么呢?

关于 MySQL 的一些问题

  • count rows:记录行数 MyISAM 只在没有 where 条件下才快,因为总行数在 MyISAM 被保存了一份,有筛选条件下差不太多
  • MySQL 5.6 起 InnoDB 已支持全文索引了

在无特殊情况下还是使用 InnoDB 比较合适,毕竟 MySQL 5.5 起默认引擎已经是 InnoDB 了。有特殊需求时,我想以开发者的能力,应该能选择合适的引擎。😊

异步的 reduce

如何实现一个异步的 reduce? (注:不是异步完了之后同步 reduce)

function reduce(arr, cb, initial = null) {
	function iterator(res, vals, index) {
		if (vals.length == 1) return cb(res, vals[0], index)
		
		return cb(res, vals[0], index).then((n) => iterator(n, vals.slice(1), index + 1))
	}
	
	if (initial) {
		return iterator(initial, arr, 1)
	} else {
		return iterator(arr[0], arr.slice(1), 0)	
	}
}

// 测试用例
function cb(res, i, index) {
	return new Promise(function (resolve, reject) {
		setTimeout(() => {
			resolve(res + i)
		}, 1000)
	})
}

reduce([1, 2, 3, 4, 5], cb)
reduce([1, 2, 3, 4, 5], cb, 10)

题意应该没理解错吧?

process.nextTick与setTimeout递归调用区别

问题出自 ElemeFE

以下是我的理解,如有不对,请多多指正!

process.nextTick属于微任务,是在当前执行栈的尾部,EventLoop之前触发,下面两个都是递归调用,test1中process.nextTick,是在当前执行栈调用,是一次性执行完,相当于 while(true){},主线程陷入了死循环,阻断IO操作。

test2方法中,setTimeout属于宏任务,在任务队列中,同样也是递归不是一次性的执行而是在多次Loop,不会阻断IO操作,另外注意setTimeout有一个最小的时间4ms。

function test1() {
    process.nextTick(() => test());
}

function test2() {
    setTimeout(() => test(), 0);
}

process.nextTick将会阻塞IO,setImmediate不会输出的情况:

{
    function test() {
        return process.nextTick(() => test());
    }

    test();

    setImmediate(() => {
        console.log('setImmediate');
    })
}

下面使用setTimeout不会造成IO阻塞,会输出 setImmediate的情况:

function test() { 
    setTimeout(() => test(), 0);
}

test()

setImmediate(() => {
    console.log('setImmediate');
})

// setImmediate

闲暇之余会写一些技术博客,感兴趣的的可以star下 https://github.com/Q-Angelo/summarize

模块中的全局变量问题

模块章节:
如果 a.js require 了 b.js, 那么在 b 中定义全局变量 t = 111 能否在 a 中直接打印出来?
原文写的是可以,并给了示例,但在本机测试会显示referenceerror: t is not defined
是否还有其他的限制条件呢?

几个杂务

今天刷招聘信息有人发这个给我问我懂不懂。。。相见恨晚啊。。。
感谢大佬们的工作,顺便求大佬们带带我= =。

一个小问题

sections/zh-cn/common.md#L50 这里提到一个StackOverflow的问题,但是这个答案排序是动态的,看了一下应该是指的Shog9的那个,我这里现在看他排第二,引用答案可以点它的share按钮。

然后我的建议其实是:这个是不是应该翻译一下😂😂😂

这个知识点我觉得很尴尬,以前我给别人讲过这个问题,可能我表达的不好,对方根本没懂。如果和略懂C语言(指针)的人讲就特别容易。
面试的时候我也不敢说,就怕面试官以为我装逼把我踢了。。。我也很绝望啊。。。

关于Let It Crash 的求助

大佬们有没有尝试把这个**推广一下?有没有什么可行的办法。我曾经在之前的2家公司推广过,但都失败了。。。

dns的lookup那里有错

看dns里 lookup和resolve的区别到时候,文章中提到lookup是同步的,为此我专门看了源码,确实文档里提到 getaddrinfo(3)是同步的,但是后面还有一句话就是使用了threadpool,所以这一块跟fs.readFile是一样的并不会造成主线程的阻塞,源码中的uv_getaddrinfo中会让线程池中的线程来处理这个阻塞的任务,并在完成以后会通过异步watcher来通知主线程执行回调。

发现一个小问题

首先十分感谢团队做了这份让大家有机会从中学习。

1.在 事件异步.并行/并发里发现一个问题:
原文:Node.js 通过事件循环来挨个抽取事件队列中的一个个 Task 执行, 从而避免了传统的多线程情况下 2个队列对应 1个咖啡机的时候上线文切换以及资源争抢/同步的问题, 所以获得了高并发的成就。

上线文切换是否为上下文切换

模块章节中关于循环require的一个问题

原文关于a.js和b.js的相互require的问题讨论中提到

以从 a.js 启动为例, a.js 还没执行完 exports 就是 {} 在 b.js 的开头拿到的就是 {} 而已

这里可能没有考虑到a.js文件在require('./b.js')之前就已经修改过module.exports的情况。下面是一个从官方文档中找到并简化过的例子

// a.js
exports.done = false;
const b = require('./b');
exports.done = true;

// b.js
const a = require('./a');
console.log('a = ', a);

// main.js
require('./a.js'); // a = {done: false}

所以当循环获取已经被require,但是没有被执行完的文件时,拿到的不一定是空对象,而是该文件的module.exports拷贝,官方文档中使用了一个叫unfinished copy的术语。

关于CDN

elemeFE的同学,您好,我这里有一个问题想请教:
整站静态化后,整个文件包放入CDN,链接该如何配置?如果过nginx,那么相当于进一遍服务器,再跳入CDN,就等于在服务器绕了一圈,没有达到最优速度;如果不配置,那链接就不友好;求赐教,万分感谢了!

关于"Javascript 基础问题"中"内存释放"的问题

比如上述情况中 unused 的函数中持有了 originalThing 的引用, 使得每次旧的对象不会释放从而导致内存泄漏 (例子出自《Node.js 垃圾回收》)

根据我的理解,这个答案是不完整的,可以试着把unused的定义注释掉,一样会存在内存泄露的问题

真实的原因是这个:
image

这是由于lexical scope所引起的,所有function的定义都会使用到originalThing形成闭包,而originalThing是指向上一个闭包的,产生一条引用链

而且现在的V8引擎已经优化了这问题(但不是完美解决这个问题)

本人其实也是一知半解描述不清楚,在这就尝试抛砖引玉了

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.