currying
柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术
1 | function add(a, b) { |
柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术
1 | function add(a, b) { |
前置知识:JavaScript是静态作用域
闭包:访问自由变量的函数
1 | var a = 1;//既不是foo的局部变量,也不是foo函数的参数,a为自由变量 |
即使上下文被销毁,它仍然存在,因为在作用域链上被引用了,是js的一个特性,目前如PHP,Java不会原生支持
面试题
常见的新手面试题,我遇到过好几次(作用域+闭包考点)
1 | var data = []; |
1.install remote ssh
in vscode
2.click remote explorer
and select ssh targets
3.click remote ssh configure
or press F1
and input remote-ssh:Open configuration file
4.selete path ~/.ssh/config
,and modify config file
if you dont have rsa ,please generate keys before
1 | //optional |
1 | Host alias |
5.login without password ready
ECMAscript 6 原生提供了 Promise 对象。
Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。
1、对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。
2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
1 | var promise = new Promise(function(resolve, reject) { |
以上来自:菜鸟https://www.runoob.com/w3cnote/javascript-promise-object.html
因为在2020年01月07日有一篇文章讲了使用promise实现延时队列的一道面试题,因为之前写业务没有用到过所以一直以为用处不大,但今天对接阿里的录音文件识别
转文字的接口中,示例代码是一个setInterval轮询得到结果的一种方式,但是他带来了一个很严重的问题
!!没有办法返回前端转文字的结果!!
大概代码如下
1 | //url:https://help.aliyun.com/document_detail/94242.html?spm=a2c4g.11174283.6.601.15eb7275a8rq00 |
使用promise进行包裹,等到promise内部的函数取到了结果在返回
1 | if (statusText == 'SUCCESS' || statusText == 'SUCCESS_WITH_NO_VALID_FRAGMENT') { |
外层通过如下代码实现
1 | var promise = new Promise(function(resolve, reject) { |
1 | async function getWords() { |
另外记录一件事情,左侧单元图标地址:https://fontawesome.com/v4.7.0/icons/
Jupiter = Julia + Python + R
Jupyter notebook(http://jupyter.org/) 是一种 Web 应用,能让用户将说明文本、数学方程、代码和可视化内容全部组合到一个易于共享的文档中。
1 | $docker pull jupyter jupyter/scipy-notebook:latest |
1 | To access the notebook, open this file in a browser: |
To solve some problems
Picture Bed can offer you a excellent platform to share your pictures and protect them, however it has a problem that you need a server to run the service,even though you can use 七牛云,alioss,weibo for free.
Chevereto is aim what I find
Chevereto is a php project , I use docker to run it
1 | docker pull nmtan/chevereto:latest |
1 | //this is docker-compose.yml |
You maybe run into a stone wall when you first visit 127.0.0.1:8000
Before you can use docker exec -it chevereto bash
into container /var/www/html
no permission write phots to /home/xxx/images,you can use chmod -R 777 /home/xxx/images
no permission update chevereto from 1.1.4 to1.2.2 ,no update possible: /app/install/update/temp/ path
,that is no temp folder in /app/install/update/ under version 1.2.0,you can mkdir temp and then chmod -R 777 ./temp and then refresh the webpage ,the prics bed will update successfully
So , you can use ip address to visit your chevereto . However , we usually use domain name such as example.com to visit web, a https isn ecessary as well
1 | server { |
https://pics.example.com
That‘s my story that building pics bed ,and hope to help you.
2020-09-28 append
use picgo
,upload pictures in typora to chevereto
GitHub download picgo,mac use .dmp,and then install it
open 插件设置
,search chevereto
and install chevereto 1.0.0
Open 图床设置>Chevereto Uploader
and put in params,
Url is your upload service ip/domain
Key is chevereto api in Dashboard>Settings>API>API v1 key
param is not in use now
1 | Url:https://example.com/api/1/upload |
确定
and 设为默认图库
PicGo设置>设置Server>点击设置
,if it is on ,noting should be doneand then we modify config in typaro
apply above rules to local images
and apply above rules to online images
in option, and I suggest you check both of them to approve all pics managed by cheveretoPicGo.app
in images Uploader and click Test Uploader
to test your upload pictures automaticallyfor more information ,youcan visit
MQ-message queue
三足鼎立
rocketmq -Made by Java 吞吐量高一些 阿里中间件
rabbitmq -Made by Erlang
Kafka-
以后有更多的了解再补充性能/功能差距
功能:解耦(双方通过mq交互)、异步、削峰
应用:
问题:
之所以选择rabbitmq是因为rocketmq的nameserver所需要的内存太大了,更何况boker,对于1C2G的乞丐机器来说根本跑不起来
Because of rocketmq need more than
1 | docker pull rabbitmq:management |
1.open chrome and input ‘localhost:15672’ or ‘192.168.1.1:15672’ then you can touch rabbitmq UI
Overview–the queued msg, msg rate in your server, some global counts, your nodes stats (if u use the above method,you only see one node in the screen ),you also can build a cluster with more nodes
Connections–
Channels–
Exchanges–direct,fanout,headers,match,trace,topic
Queses–
Admin–users management with passport && permission
2.use 5672 in your code
1 | amqp.connect({ |
more in official docs–> I’m doc
or some blogs–>I’m blog
or my GitHub–>click here
有看到石墨技术文档
cnode技术文档,作者:youth7
记录以下知识点:
process.nextTick()
在6个阶段结束的时候都会执行timers | 执行setTimeout() 和 setInterval() 中到期的callback |
---|---|
I/O callbacks | 上一轮循环中有少数的I/Ocallback会被延迟到这一轮的这一阶段执行 |
idle, prepare | 仅内部使用 |
poll | 最为重要的阶段,执行I/O callback,在适当的条件下会阻塞在这个阶段 |
check | 执行setImmediate的callback |
close callbacks | 执行close事件的callback,例如socket.on("close",func) |
1 | ┌───────────────────────┐ |
1 | # /deps/uv/src/unix/core.c |
执行setTimeout()
和 setInterval()
中到期的callback
1 | void uv__run_timers(uv_loop_t* loop) { |
上一轮循环中有少数的I/Ocallback会被延迟到这一轮的这一阶段执行
1 | //deps/uv/src/unix/core.c |
/* loop */
void uv__run_idle(uv_loop_t* loop);
void uv__run_check(uv_loop_t* loop);
void uv__run_prepare(uv_loop_t* loop);
1 | void uv__run_##name(uv_loop_t* loop) { |
最为重要的阶段,执行I/O callback,在适当的条件下会阻塞在这个阶段
可见poll阶段的任务就是阻塞等待监听的事件来临,然后执行对应的callback,其中阻塞是带有超时时间的,以下几种情况都会使得超时时间为0
- uv_run处于UV_RUN_NOWAIT模式下
uv_stop()
被调用- 没有活跃的handles和request
- 有活跃的idle handles
- 有等待关闭的handles
如果上述都不符合,则超时时间为距离现在最近的timer;如果没有timer则poll阶段会一直阻塞下去
个人理解nodejs的服务,大部分时间会被阻塞在这个阶段,而不去执行closing
1 | // 不行了,看不懂了 |
见idle prepare
关闭handle
1 | static void uv__run_closing_handles(uv_loop_t* loop) { |
1 | //lib/internal/process/task_queues.js |
1 | setTimeout(() => { |
在举例:
1 | setTimeout(() => { |
1 | const fs = require('fs') |
在引用一下官方对于check phase的介绍
This phase allows a person to execute callbacks immediately after the poll phase has completed. If the poll phase becomes idle and scripts have been queued with
setImmediate()
, the event loop may continue to the check phase rather than waiting.
setImmediate()
is actually a special timer that runs in a separate phase of the event loop. It uses a libuv API that schedules callbacks to execute after the poll phase has completed.Generally, as the code is executed, the event loop will eventually hit the poll phase where it will wait for an incoming connection, request, etc. However, if a callback has been scheduled with
setImmediate()
and the poll phase becomes idle, it will end and continue to the check phase rather than waiting for poll events.
fs.readFile 的回调函数执行完后:
所以,在 I/O Callbacks 中注册的 setTimeout 和 setImmediate,永远都是 setImmediate 先执行。
1 | setInterval(() => { |
运行结果:setInterval 永远不会打印出来。
//这个在node官方文档也有相关的描述
//我在这里也进行了笔记记录
//允许用户处理errors,清理不需要的资源,事件循环前 尝试重新连接
//有时有必要在eventloop继续之前,在call stack unwound之后,让callback执行
解释:process.nextTick 会无限循环,将 event loop 阻塞在 microtask 阶段,导致 event loop 上其他 macrotask 阶段的回调函数没有机会执行。//这段解释是前端的,后端是没有microtask的实际队列的
解决方法通常是用 setImmediate 替代 process.nextTick,如下:
1 | setInterval(() => { |
运行结果:每 100ms 打印一次 setInterval。
解释:process.nextTick 内执行 process.nextTick 仍然将 tick 函数注册到当前 microtask 的尾部,所以导致 microtask 永远执行不完; setImmediate 内执行 setImmediate 会将 immediate 函数注册到下一次 event loop 的 check 阶段,而不是当前正在执行的 check 阶段,所以给了 event loop 上其他 macrotask 执行的机会。
再看个例子:
1 | setImmediate(() => { |
运行结果:
1 | setImmediate1 |
注意:并不是说 setImmediate 可以完全替代 process.nextTick,process.nextTick 在特定场景下还是无法被替代的,比如我们就想将一些操作放到最近的 microtask 里执行。
1 | const promise = Promise.resolve() |
运行结果:
1 | TypeError: Chaining cycle detected for promise #<Promise> |
解释:promise.then 类似于 process.nextTick,都会将回调函数注册到 microtask 阶段。上面代码会导致死循环,类似前面提到的:
1 | process.nextTick(function tick () { |
再看个例子:
1 | const promise = Promise.resolve() |
运行结果:
1 | nextTick |
解释:promise.then 虽然和 process.nextTick 一样,都将回调函数注册到 microtask,但优先级不一样。process.nextTick 的 microtask queue 总是优先于 promise 的 microtask queue 执行。
1 | setTimeout(() => { |
运行结果:
1 | 2 |
解释:Promise 构造函数是同步执行的,所以先打印 2、3,然后打印 5,接下来 event loop 进入执行 microtask 阶段,执行 promise.then 的回调函数打印出 4,然后执行下一个 macrotask,恰好是 timer 阶段的 setTimeout 的回调函数,打印出 1。
1 | setImmediate(() => { |
运行结果:
1 | 9 |
process.nextTick、setTimeout 和 setImmediate 的组合,请读者自己推理吧。
1 | //lib/timers/promises.js |
Why: 复杂度O(n)—>O(logn)
使用限制:有序数组
指出算法运行时间的增速,算法需要做的就是把O(n^2)优化到O(n)等
数组:连续物理空间,可随机访问,增删数据复杂度高
链表:分散无力空间,不可随机访问(只能顺序),增删数据复杂度低
数组 | 链表 | |
---|---|---|
读改 | O(1) | O(n) |
增删 | O(n) | O(1) |
根据互相特性,选择合适的方式,如频繁增删用链表,反之用数组
复杂度:O(n^2)
遍历n 个元素选择 最小/大的,遍历n-1个元素选择 最小/大的
类比:套娃 :call_me_hand:
性能和易读不可兼得
避免死循环!
尾递归可以解决部分性能问题
递归调用栈是性能降低的原因,遵循FIFO
核心:分而治之divide and conquer,快排只是其中的一个应用
思想:递归的一种应用
快排(递归)是一种函数式编程
快排通过基准值(可以选第一个元素)进行分而治之
实现方式:数组,非链表,检索值key类似数组的下表,可直接访问value
应用:DNS,阻止重复数据(类set集),作缓存(服务器端)
复杂度 | 散列平均 | 散列最糟 | 数组 | 链表 |
---|---|---|---|---|
查找 | 1 | n | 1 | n |
插入删除 | 1 | n | n | 1 |
装填因子(0.4)=散列元素(4)/位置总数(10)
避免冲突:1.良好的散列函数(均匀分布) 2.较低的装填因子(<0.7)
将满时候:1.申请两倍于原来的 新空间 2.hash所有元素到新空间
冲突解决:
广度优先搜索breadth first search,解决无加权最短路径问题之一
应用:国际跳棋,拼写检查,人际关系网络
正加权有向无环图的解决算法
解决环:
负加权:bellman ford algorithm
每步最优–>全局最优,得到近似正确的结果
列出所有可能
树解决了二分查找中,插入删除O(n)降低到O(log n),但是降低了随机访问能力
树包括:二叉树,平衡二叉树,B树 B+树,,红黑树
反向索引:散列表,用于创建搜索引擎—>应用:傅里叶变换
并行算法,单机并行or分布式,应用:mapreduce,map->映射 ,reduce->归并
布隆过滤器:庞大的散列表(如谷歌的上亿条),通常使用redis实现,是一种概率型数据结构(偶尔出错),使用理由,存储空间少
hyperLogLog:类似布隆,是个日志
SHA算法
线性规划:simplex算法