路由器梅林clash下载地址
https://github.com/zusterben/plan_c
路由器关闭关键字检测
sed -i ‘s/\tdetect_package/\t# detect_package/g’ /jffs/softcenter/scripts/ks_tar_install.sh
https://github.com/zusterben/plan_c
sed -i ‘s/\tdetect_package/\t# detect_package/g’ /jffs/softcenter/scripts/ks_tar_install.sh
原来服务是稳定运行的,加了一个子进程功能后,服务器经常无法访问。
1 | 85 [info] 2022-09-19 02:14:02.6 [ApiInterceptor] 126ms 61.165.44.200: 1184582: GET: /api/video: {"current":"1","pageSize":"20","orderBy":"id","order":"DESC","isProfessional":"true","isFake":"false"}: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (K HTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 |
1 | 328 [info] 2022-09-18 03:30:02.0 [KeywordMonitorCommunityCron] 收到close事件,子进程收到信号 256120 |
1 | 94 [info] 2022-09-17 03:30:02.1 [KeywordMonitorCommunityCron] 收到close事件,子进程收到信号 145279 |
没有发现问题
确认连接池问题
有一段代码循环使用 sql,导致连接池被用尽。
1 | const value = await PromiseTools.queue(list, async (item) => { |
如果 list 过多,会导致连接池全部使用完,无法释放。
PromiseTools.queue 代码逻辑有问题
1 | static async queue<T, K>(dataList: T[], callBack: (item: T, index: number) => Promise<K> | K, spliceLength = 5): Promise<K[]> { |
尝试优化代码
1 | static async queue<T, K>(dataList: T[], callBack: (item: T, index: number) => Promise<K> | K, spliceLength = 5): Promise<K[]> { |
解决一些特定问题的方法,并总结起来,给一个名字。
在面向对象软件设计过程中针对特定的问题简洁而优雅的解决方案。
找出程序中变化的地方,并将变化封装起来
如果它走起路来像鸭子,叫起来也是鸭子,那么它就是鸭子。
同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果。换句话说,给不同的对象发送同一个消息的时候,这些对象会根据这个消息分别给出不同的反馈。
1 | class Duck {} |
1 | const makeSound = function (animal: Animal) { |
多态最根本的作用就是通过把过程化的条件分支语句转化为对象的多态性,从而消除这些条件分支语句
考虑你的设计中哪些地方可能变化,这种方式与关注会导致重新设计的原因相反。它不是考虑什么时候会迫使你的设计改变,而是考虑你怎样才能够在不重新设计的情况下进行改变。这里的关键在于封装发生变化的概念,这是许多设计模式的主题
基于原型链
保证一个类仅有一个实例,并提供一个访问它的全局访问点
代理模式是为一个对象提供一个代替品或占位符,以便控制对他的访问
顺序访问一个聚合对象的元素,而不需要暴露对象的内部表示。
基本不需要自己实现,大部分语言内置了迭代器
对象间的一对多的依赖关系,当一个对象的状态发生改变时,所以依赖于他的对象都能接受到通知
命令是对命令的封装,每一个命令都是一个操作,请求方发出请求,接收方接收请求,并执行操作。命令模式解耦了请求方和接收方,命令模式属于行为型模式
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结
在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。
定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
计算绩效
1 | const calculateBonus = function ( |
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 ‘1’。
输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 ‘1’。
输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 ‘1’。
输入必须是长度为 32 的 二进制串 。
如果多次调用这个函数,你将如何优化你的算法?
1 | // 自己写的 0ms 2mb |
1 | // 构造32位蒙版(只有一个1),进行与操作 |
1 | // count_one 方法 可以直接获取数量 |
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入:strs = [“flower”,”flow”,”flight”]
输出:”fl”
示例 2:
输入:strs = [“dog”,”racecar”,”car”]
输出:””
解释:输入不存在公共前缀。
提示:
1 | impl Solution { |
尝试着去分享更多的东西
起码留下点什么
加油
为众人抱薪者,不可使其冻毙于风雪;
为大众谋福利者,不可使其孤军奋战;
为自由开路者,不可使其困顿于荆棘。
如果天空是黑暗的,那就摸黑生存;如果发出声音是危险的,那就保持沉默;如果自觉无力发光,那就蜷伏于墙角。但是,不要习惯了黑暗就为黑暗辩护,也不要为自己的苟且而得意,不要嘲讽那些比自己更勇敢的人。我们可以卑微如尘土,但不可扭曲如蛆虫
原来,有你陪着已经这么开心
房间里,没有你,这么空旷
一边流泪,一边收拾衣服的感觉确实不好
有点怀疑,自己为什么会劝你回到哪里
我果然是个傻逼
一直在身边的,才是最容易被忽视的。
有一天突然不见了。
原来是这么难受。
嗯。
有些不知所措
跟自己想的那种情况 不太一样
哭成了傻逼
我以为我能很平静的接受这件事
回到家里,看着熟悉的房间,总是感觉她在那里
还没有离开
一边写 一边哭
不写了
给定一个正整数 n ,输出外观数列的第 n 项。
「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。
你可以将其视作是由递归公式定义的数字字符串序列:
要 描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。
- 1
- 11
- 21
- 1211
- 111221
第一项是数字 1
描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 “11”
描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 “21”
描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 “1211”
描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 “111221”
输入:n = 1
输出:”1”
解释:这是一个基本样例。
输入:n = 4
输出:”1211”
解释:
countAndSay(1) = “1”
countAndSay(2) = 读 “1” = 一 个 1 = “11”
countAndSay(3) = 读 “11” = 二 个 1 = “21”
countAndSay(4) = 读 “21” = 一 个 2 + 一 个 1 = “12” + “11” = “1211”
普通做法
1 | function countAndSay(n: number): string { |
递归做法
感觉性能会比较差