宏任务与微任务

//请写出输出内容
async function async1() {
    console.log('async1 start');
    await async2();
    console.log('async1 end');
}
async function async2() {
	console.log('async2');
}
console.log('script start');
setTimeout(function() {
    console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
    console.log('promise1');
    resolve();
}).then(function() {
    console.log('promise2');
});
console.log('script end');
/*
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
*/

这道题属于异步变成的知识点,但是底层是有一个叫 宏任务与微任务 的队列来支持

宏观任务:主进程代码,setTimeout, setInterval, UI交互事件

微任务:常见的就是.then, yield, await

68747470733a2f2f692e6c6f6c692e6e65742f323031392f30322f30382f356335643661353238626461662e6a7067.jpeg

相当于有一个渲染过程包含2个任务队列,先执行宏任务,宏任务里面行微任务(如果有),然后触发渲染,在进入下一个宏任务。

参考资料 https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/7

五种常见的算法模版

//循环
function loop(a, b, c) {
	// 终止条件
	if(a===xxx){
		return
	}
	doSomething(a, b, c);
	loop(a+1, b, c);
	reverse_state(a, b, c) //还原状态
}
//深度优先搜索
const visited = new Set();   //利用visited记忆化,防止重复计算
function DFS(node, a, b) {
	visited.add(node);
	doSomething(node, b, c);
	for(let i = 0; i<node.children.length; i++) {
		if(!visited.has(node.children[i])){
			DFS(node.children[i], a, b)
		}
	}
	reverse_state(node, b, c) //还原状态
}
//广度优先搜索
function BFS(root, a, b) {
	// 设置缓存队列
	const quene = [];
	quene.push(root);
	while(queue.length>0){
		let node = queue.pop();
		doSomething(_node, b, c);
		for(let i = 0; i<node.children.length; i++) {
			quene.push(node.children[i]);
		}
	}
}
//二分搜索
function binarySearch(array, target) {
		let left = 0;
		let right = array.length-1;
		while(left<=right){
			let mid = Math.floor((right + left)/2);
			if(array[mid] === target){
				//找到了
				return xx;
			}else if(target<array[mid]){
				right = mid-1; //左右边界调整
			}else{
				left = mid+1;
			}
		}
		return -1;
}
//DP
function DP(a, b, c){
	//定义DP[i]的含义,这里有可能是多维数组
	let DP = [];
	//设置DP[0]的值
	DP[0] = xxx;
	//这里可能是多重循环
	for(let i = 1; i<something; i++) {
		DP[i] = doSomething(DP[i-$])  //按照实际情况写出递推公式
	}
	return DP[i] //结果一般存在最后一个数组或第一个
}

主定理 与 时间复杂度

主定理最早出现在《算法导论》中,提供了分治方法带来的递归表达式的渐近复杂度分析。
规模为n的问题通过分治,得到a个规模为n/b的问题,每次递归带来的额外计算为c(n^d)
T(n) <= aT(n/b)+c(n^d)
那么就可以得到问题的复杂度为:

  • T(n) = O(n^d log(n)), if a = b^d

  • T(n) = O(n^d ), if a < b^d

  • T(n) = O(n^logb(a))), if a > b^d

二分搜索

  • 每次问题规模减半,a=1,b=2,c=0

  • 复杂度为n^0 O(log n)

二叉树遍历

    每次问题规模减半,a=2,b=2,c=0

    复杂度为n O(n)

快速排序

  • 随机选择待排序序列中的一个数字作为划分字问题的标准,划分是否平均影响算法复杂度

  • 每次问题规模减半,a=2,b=2,c=1

  • 复杂度为n^2 O(n log n)

  • 最差情况下,复杂度为O(n^2)

归并排序

  • 数据列均分为两部分,分别排序,之后以O(n)的复杂度进行合并,空间复杂度O(n)

  • 每次问题规模减半,a=2,b=2,c=1

  • 复杂度为n log(n)

一个关于 npm install 的安全问题

最近发现一个模块  pre-commit  https://www.npmjs.com/package/pre-commit

这个模块的用途是在git commit的时候可以运行一些命令。本质上是在.git/hooks/pre-commit 插入一些命令。

问题来了:为什么  npm install –save-dev pre-commit 具有这么大的权限?能够对非./node_modules/pre-commit 以外的文件做修改?如果真能修改是不是可以修改windows文件了?这样会有安全问题。

关键点在于 npm install 这个命令,自己还不够熟悉,要持续观察。以后找到原因再更新文章。

Scoped CSS 研究

看了徐飞大神对组件化的探索

https://github.com/xufei/blog/issues/22,里面提到Scoped CSS,于是顺便研究一下

在chrome和safair都试了几次,都无效果。查了一下caniuse,发现兼容性太差。。。放弃不研究

blob.png

关于instanceof的深入认识

如果刚认识这个操作符,有个肤浅的理解

a instanceof b 只要在a的原型链上有b就返回true。这个理解其实是错的。

直到我重新读了一下《javascript高级程序设计》的6.3节 173页。

function inheritPrototype(subType, superType){
	var prototype = Object(superType.prototype);
	prototype.constructor = subType;
	subType.prototype = prototype;
}
function SuperType(name){
	this.name = name;
	this.colors  = ["red","blue","green"];
}
SuperType.prototype.sayName = function(){
	alert(this.name);
}
function SubType(name,age){
	SuperType.call(this, name);
	this.age = age;
}
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge = function(){
	alert(this.age);
}
var instance = new SubType("jie",29)

instance instanceof SubType //true 这个没有异议吧

instance instanceof SuperType //true 这个就比较奇怪了

如果console.log(instance);是看不到SuperType出现在instance的原型链上面的。

于是我上百度谷歌了一下:

a instanceof b底层的运算机制关键点如下:

1 b的数据类型必须为[object Function],否则就抛TypeError;

2 若a为Primitive Value则直接返回false, 若a的数据类型为Object则执行后续运算;

3 当且仅当b.prototype位于a的prototype chain中时,才返回true(由于Object.prototype.__proto__为null,因此prototype chain是有限链表);

所以正确的说法是   a instanceof b 只要在a的原型链上有等于b的原型就返回true

树莓派控制云台按角度转动

代码下载: git clone https://github.com/offbye/rpiservocamra.git
 
2) install ServoBlaster
Please read ServoBlaster/README.txt for more information
$: cd ServoBlaster/
$: ls
$:  make servod
$:  sudo ./servod
$: echo 1=160 > /dev/servoblaster
 
Copy web to your php web server. then you can browser it in Chorome browser
http://yourserver/web/cam.html