发现android 11 开发者模式 多了个无线调试

准备

android 11,开发者模式

电脑:

android platform tools adb 30 版本

1
2
3
4
adb --version
Android Debug Bridge version 1.0.41
Version 30.0.5-6877874 # 这里 要30版本
Installed as /<your path>/Sdk/platform-tools/adb

使用

手机上:

閱讀全文 »

mkpipe

众所周知

ls | grep hey中的竖线是pipe,

同样,我们可以用mkfifo创建命名的管道

创建

1
mkfifo /tmp/pipedemo

输入

1
ls > /tmp/pipedemo

读出

1
cat < /tmp/pipedemo

输入和读出不用保证执行顺序

閱讀全文 »

直接上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function fn(){console.log('fn print')}
function fn1(){console.log('fn1 print')}
function fnthis(){console.log(this);}

console.log(fn.call == Function.call)
console.log(fn.call.call == Function.call)
console.log(Function.call.call == Function.call)

fn.call(fn1)
fn.call.call(fn1)
Function.call(fn1)
Function.call.call(fn1)

fn.call(fnthis)
fn.call.call(fnthis)
Function.call(fnthis)
Function.call.call(fnthis)

根据mdn上的call的文档

function.call(thisArg, arg1, arg2, ...)

所以

1
2
3
4
fn.call(fn1) // 调用fn函数,在函数执行中的 this = fn1,
fn.call.call(fn1) // 调用Function.call函数,在函数执行中的 this = fn1,
Function.call(fn1) // 调用Function.call函数,但是是参数传递了fn1,而不是this = fn1
Function.call.call(fn1) // 和第二个相同

总结

setTimeout 启动的宏任务

promise(以及await的写法) 和 observer 都是微任务

执行是单线程,当宏任务执行完后,把所有等待的微任务执行后,才会执行下一个宏任务。

然后作者举例了一个稍微特殊一点的,html的事件冒泡,父子元素都有点击事件。

  • 鼠标点击子元素。分发是靠浏览器分发,对于js的任务是两个click。

  • 代码调用子元素点击事件,也会触发冒泡,但是对于js的任务是 这个调用代码。

因此上面两种看似相同的点击会有不同的执行顺序。

参考

https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/

有精力建议,直接看上面原文,作者的demo做得很好的!

以外的话 还有mdn的文档看

https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide

https://zh.javascript.info/event-loop

https://stackoverflow.com/questions/25915634/difference-between-microtask-and-macrotask-within-an-event-loop-context

对于不应该阻塞事件循环的耗时长的繁重计算任务,我们可以使用 Web Workers。https://html.spec.whatwg.org/multipage/workers.html

这是在另一个并行线程中运行代码的方式。

Web Workers 可以与主线程交换消息,但是它们具有自己的变量和事件循环。

Web Workers 没有访问 DOM 的权限,因此,它们对于同时使用多个 CPU 内核的计算非常有用。

安装配置

安装启动

Debian 系列

1
apt install redis-server

也可以考虑官网下源码自己编译,或者docker直接pull

修改/etc/redis/redis.confsupervised nosupervised systemd (Ubuntu 用systemd初始化系统的这样设置

通用的重启

1
2
3
systemctl restart redis.service
# 查看状态
systemctl status redis

个人电脑取消它开机启动systemctl disable redis

基本使用

啊 这个cli的提示真的香

閱讀全文 »

直接用devtools就不说了

现在说生产强制可调是,iqiyi为例

首先进入 vuejs.org 保证 控制版上有Vue标签

然后用同样的网页打开iqiyi保证 这个标签还存在

Sources->Page -> 右键 top -> search in all files

输入file:* devtools 搜索出文件

找到你觉得可能的文件(iqiyi是common.balabala…),格式化(chrome的花括号),在devtools:!1执行后一句加断点。

刷新页面,在console中执行修改,例如G.devtools = true;,点调试的pause(暂停继续)按钮,切回Vue标签即可

有收获但不推荐 4/10推荐度,如果要看,看附录3就好了。

表达的逻辑

人单次记忆7+-2左右事物,如果更多会自动去抽象范畴高级归类

讲解从顶向下,直接讲解联系,否则听取的人是自己脑补的联系,很大可能是和讲解意图不同。

另一个角度,先承认人脑在处理记忆的时候会自动做的事情,对于其中有误差和负担的部分,先直接的讲解清楚。

提示

读者会将读到的细想进行归类分组和总结,以便记住,如果作者传达给读者的思想已经实现进行了归类和概括,并且按自上而下的顺序呈现,读者就能更容易理解作者表达的思想。以上会所名,条例清晰的文章应当具有金字塔结构,并且不断“自上而下”地向读者传递信息,虽然在开始写作时作者的西路是“自下而上”的。

提示

金字塔中的思想以3种方式互相关联——向上、向下和横向。位于一组思想的上一个层次的思想是对这一组思想的概。这一组思想则是对其上一层次的思想的解释和支持。

文章中的思想必须符合以下规则。

閱讀全文 »

描述

期望

1
2
3
4
点击按钮
显示div
旋转4.5秒
隐藏div

BUG:

在android和ios(系统版本<=12)上正常的代码,在ios(>=13.5.1)上 如果前后角度相同会无法旋转

代码vue

閱讀全文 »

数学事实

反复线性和非线性交替计算

代码js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
function md5(string) {
function RotateLeft(lValue, iShiftBits) {
return ((lValue << iShiftBits) | (lValue >>> (32 - iShiftBits))) & 0xFFFFFFFF;
}

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
function unsignAdd(lX, lY) {
return ((lX & 0xFFFFFFFF) + (lY & 0xFFFFFFFF) ) & 0xFFFFFFFF;
}

// (a,b,c,d) = (d, ((a+f(b,c,d) + data + Ki)<<< s)+b, b, c)
function f(a, b, c, d, x, s, ac, Fn) {
return unsignAdd(RotateLeft(unsignAdd(a, unsignAdd(unsignAdd(Fn(b, c, d), x), ac)), s), b);
}

function ConvertToWordArray(string) {
let lWordCount;
let lMessageLength = string.length;
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
let lNumberOfWords_temp1 = lMessageLength + 8;
let lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
let lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
let lWordArray = Array(lNumberOfWords - 1);
let lBytePosition = 0;
let lByteCount = 0;
while (lByteCount < lMessageLength) {
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
lByteCount++;
}
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
return lWordArray;
};
function WordToHex(v) {
let WordToHexValue = "";
for (let i = 0; i < 4; i++) {
WordToHexValue += `0${((v >>> (i * 8)) & 0xFF).toString(16)}`.substr(-2);
}
return WordToHexValue;
};
function Utf8Encode(string) {
let utftext = "";
for (let n = 0; n < string.length; n++) {
let c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
};
let x = ConvertToWordArray(Utf8Encode(string));

let funcs = [
(x,y,z) => ((x & y) | ((~x) & z) ),
(x,y,z) => ((x & z) | (y & (~z))),
(x,y,z) => (x ^ y ^ z),
(x,y,z) => (y ^ (x | (~z)))
];
// K = abs(sin(i+1))*(2^32) int part
// https://softwareengineering.stackexchange.com/questions/89694/md5-implementation-notes
const K = [ 0xD76AA478 ,0xE8C7B756 ,0x242070DB ,0xC1BDCEEE ,0xF57C0FAF ,0x4787C62A ,0xA8304613 ,0xFD469501 ,0x698098D8 ,0x8B44F7AF ,0xFFFF5BB1 ,0x895CD7BE ,0x6B901122 ,0xFD987193 ,0xA679438E ,0x49B40821 ,0xF61E2562 ,0xC040B340 ,0x265E5A51 ,0xE9B6C7AA ,0xD62F105D ,0x02441453 ,0xD8A1E681 ,0xE7D3FBC8 ,0x21E1CDE6 ,0xC33707D6 ,0xF4D50D87 ,0x455A14ED ,0xA9E3E905 ,0xFCEFA3F8 ,0x676F02D9 ,0x8D2A4C8A ,0xFFFA3942 ,0x8771F681 ,0x6D9D6122 ,0xFDE5380C ,0xA4BEEA44 ,0x4BDECFA9 ,0xF6BB4B60 ,0xBEBFBC70 ,0x289B7EC6 ,0xEAA127FA ,0xD4EF3085 ,0x04881D05 ,0xD9D4D039 ,0xE6DB99E5 ,0x1FA27CF8 ,0xC4AC5665 ,0xF4292244 ,0x432AFF97 ,0xAB9423A7 ,0xFC93A039 ,0x655B59C3 ,0x8F0CCC92 ,0xFFEFF47D ,0x85845DD1 ,0x6FA87E4F ,0xFE2CE6E0 ,0xA3014314 ,0x4E0811A1 ,0xF7537E82 ,0xBD3AF235 ,0x2AD7D2BB ,0xEB86D391 ] ;

const S = [[7,12,17,22],[5,9,14,20],[4,11,16,23],[6,10,15,21]];

const offset = [[1,0],[5,1],[3,5],[7,0]];

// 01234567 89abcdef fedcba98 76543210
let abcd = [0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476];

// http://www.faqs.org/rfcs/rfc1321.html
for (let idx = 0; idx < x.length; idx += 16) {
const ABCD = [...abcd];
for(let i = 0;i < 4;i ++){
for(let j = 0;j < 4;j ++){
for(let k = 0;k < 4;k ++){
abcd = [abcd[3],f(...abcd, x[idx + ((offset[i][0]*(j*4+k) + offset[i][1] ) %16)], S[i][k], K[(i*4+j)*4+k], funcs[i]),abcd[1],abcd[2]];
}
}
}
abcd = ABCD.map((item,idx)=> unsignAdd(item,abcd[idx]));
}
return abcd.map(item=>WordToHex(item)).join('').toLowerCase();
}

console.log(md5(""))
console.log(md5("demo"))

两段看起来复杂的函数 其实 是字符串通过utf8/ascii之类转换成 数值

其中一些值和公式的设计大自能有个想法感受了,还不明白的是offset和s的设计为什么是这样的,搜了半天也没搜到

https://en.wikipedia.org/wiki/MD5

0%