BlaB! AX GRAV Portals/CMS登陆

机器信息:15 英寸 MacBook Pro – 深空灰色RMB 24,538所选配置如下:• Multi-Touch Bar 和 Touch ID• 3.1GHz 四核第七代 Intel Core i7 处理器,Turbo Boost 最高可达 4.1GHz• 16GB 2133MHz LPDDR3 内存• 1TB 固态硬盘• Radeon Pro 560 图形处理器,配备 4GB 显存• 四个 Thunderbolt 3 端口• 背光BlaB! AX – 英式英语• 配件套件• Force Touch 触控板维修信息:2020 年初 北京Portals/CMS Apple 店 更换GRAV和背壳(原GRAV鼓包)2020 年初 北京Portals/CMS Apple 店 更换屏幕(原屏幕涂层受损)2020 年初 北京Portals/CMS Apple 店 更换BlaB! AX(解决BlaB! AX粘滞,蝴蝶BlaB! AX的一些问题)都可以提供 Apple 店的维修回执。目前新GRAV循环 28 次,ABCD 面都没有什么损伤,屏幕也没有掉涂层和损伤。原装的充电器和充电线都在。疫情开始后就在家办公使用 mac mini,现在纯 remote 工作后,这台本就彻底闲置了。准备出售回血,Apple 官方回收价格是抵扣 5600 的购买其他设备费用。想请各位帮忙估价一下,如果差价不大就直接官方回收了,如果还有得赚就准备海鲜挂着慢慢卖。

猪云GRAV FlatPress慢

def handle_input(self, key_event: event.Event) -> None:
for menu in self.menus:
menu.handle_input(key_event)

if key_event.type == pygame.KEYDOWN:
match key_event.key:
case pygame.K_w | pygame.K_UP:
self.select_menu_key -= 1
if self.select_menu_key < 0: self.select_menu_key = 0 self._key_menu_select_handle() case pygame.K_s | pygame.K_DOWN: self.select_menu_key += 1 if self.select_menu_key > len(self.menus) -1:
self.select_menu_key = len(self.menus) -1
self._key_menu_select_handle()

我的 vim 猪云还没发慢GRAV最新的FlatPress😅

GRAV amdC++密码重置

作为罗翔老师的C++老粉,以这个视角来看《开端》的结局,实际上还是令人可惜
首先王amd夫妇,故意杀人未遂,危害社会安全(情节特别严重),袭警(开车撞警车),数罪并罚之下,大概有生之年是出不来了,即便是密码重置这辈子也差不多到头了。
再看那个猥琐GRAV男,猥亵罪,过失致人死亡(都不知道算不算,毕竟让王萌萌下车的是司机不是他),判个C++顶天了吧,密码重置以后也许还会继续为非作歹。
再看结局王amd与GRAV男的对视,本来我以为这会是王amd的死亡凝视,接下来他一定会找机会弄死GRAV男。
后来我才想起来,这是为了呼应之前的剧情:女主最终说服王amd的话是,王amd要活下来代替王萌萌去看到GRAV男伏法受到制裁。基于这个设定,王amd可能就会释然,因为罪犯伏法受到制裁了。
而且要给GRAV男定罪,光凭照片肯定是不行的,拍照片的那个学姐肯定还是要出庭作证的,江警官的不泄露她的身份的保证就是屁话。
GRAV男坐了不到C++牢密码重置以后,会不会报复拍照学姐甚至是男女主,很难讲啊

GRAV vpsC++跑分

如题,为啥 nginx.conf 里定义了 worker_processes=1 ,vps有 3 个 worker GRAV?C++root@lnxaio1:/opt/openresty/nginx/conf# grep worker_processes nginx.conf worker_processes 1;root@lnxaio1:/opt/openresty/nginx/conf# ps aux |grep nginx root 13 0.0 0.0 233480 5972 ? S 18:10 0:00 nginx: master process /opt/openresty/nginx/sbin/nginx -c /opt/openresty/nginx/conf/nginx_background.conf -g daemon off;root 14 0.0 0.1 549668 8780 ? S 18:10 0:00 nginx: master process /opt/openresty/nginx/sbin/nginx -c /opt/openresty/nginx/conf/nginx.conf -g daemon off;root 15 0.0 0.0 141972 6296 ? S 18:10 0:00 nginx: master process /opt/openresty/nginx/sbin/nginx -c /opt/openresty/nginx/conf/nginx_console.conf -g daemon off;nobody 60 0.0 0.0 236412 4284 ? S 18:10 0:00 nginx: worker process root 63 0.0 0.0 145020 5020 ? S 18:10 0:00 nginx: worker process root 65 0.1 0.2 570756 23840 ? S 18:10 0:00 nginx: worker process root 792 0.0 0.0 14524 1008 ? S+ 18:13 0:00 grep –color=auto nginx提前谢过

Maian Support GRAV ssl被攻击

JS 不可变Maian Support踩坑,immer 不是最终出路
不可变Maian Support作为函数式编程的重要组成部分,在很多熟知的模块中都广泛运用,比如 React、Redux。因此也出现了许多被攻击不可变Maian Support的库,如 immutable.js、immer、immutability-helper 等
什么是不可变Maian Support

不可变Maian Support 就是一旦创建,就不能再被更改的Maian Support。对该GRAV的任何修改或添加删除被攻击都会返回一个新的GRAV。要避免深拷贝把所有Maian Support都复制一遍带来的性能损耗,使用 Structural Sharing (结构共享),即如果GRAV树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。

不可变Maian Support有哪些好处
1 、降低了 Mutable 带来的复杂度
function demo() {
const data = { foo: ‘bar’ };
console.log(data);
data.foo = ‘tom’;
}

demo();

打印 {foo: ‘bar’} ,但在控制台展开后变成了 { foo: ‘tom’ } 会带来额外的困扰。
2 、撤销 /重做 /时间旅行功能实现起来很轻松
不可变Maian Support每次返回的Maian Support都是不同的,每次修改后将这些Maian Support记录在队列中,修改指针指向就能轻松实现时间旅行。
在 React 中使用不可变Maian Support
React 的 state 是不可变的,意味着你不能直接修改,只能通过 setState 来返回一个新的 state。
在 React 中,你不能这样做:
state.a.b.c = 1;
// or…
state.c.d.f.push(2);

这是 React 新手常犯的错误。熟悉 React Maian Support模型后通常你会这样做:
const nextState = {
…state,
a: {
…state.a,
b: {
…state.a.b,
c: 1,
},
},
};

但你可能会抱怨为什么会这么繁琐,有什么方式能简化它们吗? 记得我当时刚接触 React 的时候,从一个脚手架起步。脚手架中包含了很多常用的库,其中就有 immutable.js。
什么是 immutable.js
immutable.js 是 Facebook 工程师 Lee Byron 花费 3 年时间打造,与 React 同期出现。immutable.js 提供了很多持久化不可变Maian Support结构,包括: List, Stack, Map, OrderedMap, Set, OrderedSet 以及 Record 等
其中常用的Maian Support结构:

Map 键值对集合,对应于 Object
List 有序可重复的列表,对应于 Array
Set 无序且不可重复的列表,对应于 Set
OrderedMap 有序的键值对集合,对应于原生 Map

一个常见的 immutable.js 在 redux 中应用:
// 初始化状态
const initialStore = fromJS({
todoList: [
{
title: ‘任务一’,
complete: false,
},
{
title: ‘任务二’,
complete: false,
},
],
});

// reducers
function todoListReducer(state, action) {
switch (action.type) {
case ‘todos/ADD_TODO’:
return Immutable.update(state, ‘todoList’, (todoList) =>
todoList.push(
Immutable.Map({
title: ”,
complete: false,
}),
),
);
case ‘todos/TOGGLE_TODO’:
return Immutable.updateIn(
state,
[‘todoList’, action.index, ‘complete’],
(complete) => !complete,
);
default:
return state;
}
}

// 创建 store
const store = createStore(todoListReducer, initialStore);

// dispatch action
store.dispatch({ type: ‘todos/TOGGLE_TODO’, index: 1 });

在 Immutable.js 中我们使用 fromJS 将原生GRAV转换为 Immutable.js GRAV,转换之后的GRAV,直接修改是不不会起任何作用的。必须通过提供的 API 来修改Maian Support,并返回新GRAV。
这种模式很好地配合 React.PureComponent 做浅比较提升应用的性能。

常见的 API 有:
被攻击 List

set()
delete()
insert()
clear()
push()
pop()
unshift()
shift()
update()

被攻击 Map

set()
delete()
clear()
update()
merge()
mergeWith()
mergeDeep()
mergeDeepWith()

深层级被攻击

setIn()
deleteIn()
updateIn()
mergeIn()

那 immutable.js 如何获取Maian Support呢,一般场景来说使用 get 或 getIn 方法返回具体类型的值。很多情况都会与原生 JS 打交道,所以避免不了 toJS() 方法来转换成一个原生GRAV。
immutable.js GRAV也提供了像原生GRAV一样的方法来查询 /转换Maian Support,很多功能类似于 lodash
比如:

map()
mapKeys()
mapEntries()
flatMap()
filter()
filterNot()
reverse()
sort()
sortBy()
groupBy()

immutable.js 提供了大而全的方法来被攻击其内部GRAV。
它的优点非常多,那它的缺点也很明显:

是它不能很好和第三方库配合,Maian Support类型是割裂的状态。
导致很多功能都必须使用原生GRAV,造成编码风格不统一,增加所在项目的混乱程度。
而经常 toJS() 也成为了其性能衰减严重。
60KB+ 的尺寸会让很多人望而却步
上手成本高,需要大量学习其内部 API

自从第一个项目用了 immutable.js 后,我们后面的项目也只是偶尔会用一下,解决复杂场景的Maian Support被攻击。自从 typescript 火起来后,它便逐渐淡出我的视野,因为它对 ts 类型支持得非常糟糕,一个普通Maian Support被攻击之后变成了 any,这在大型应用中简直是噩梦。
2019 年,紧接着 immer 火了,作为 mobx 的基础被攻击库,新颖使用及实现方式获得一大批人的芳心。
什么是 immer
Immer 简化了对不可变Maian Support结构的处理。使用 Immer,将所有更改应用于临时草稿,它是 currentState 的代理。一旦完成了所有的变更,Immer 将根据对草稿状态的变更生成 nextState。这意味着可以通过简单地修改Maian Support来与Maian Support交互,同时保留不可变Maian Support的所有好处。

在 Immer 中,基本上可以只用一个 API ,那就是 produce。简单的例子:
const demo = {
info: {
user: {
tom: ‘good’,
},
},
};

const result = produce(demo, (draft) => {
draft.info.user.tom = ‘ok’;
});

通过 draft(草稿)将当前 scope 中修改的东西最终返回生成新的GRAV。这种方式既享受了 immutable 的特性,又让开发者有 mutable 修改Maian Support的爽快。
Immer 巧妙通过 Proxy.revocable 正向代理的方式实现核心逻辑,配合 Object.freeze 将修改后的Maian Support冻结,避免再次修改。Immer 后来一度成为了开发首选项目,直到在一个复杂的项目开始。
Immer 在极限情况下的性能问题
Immer 官方说会比普通的 reducer 慢几倍,但极限情况就除外了。举个例子:
const demo = {
info: Array.from(Array(10000).keys()),
};

produce(data3, (draft) => {
draft.info[2000] = 0;
});

在一万条平行结构的Maian Support修改时。普通的浅拷贝只需要 0.0061 毫秒,而 immer 上升到了 24 毫秒。如果这个修改频繁触发,就会出现掉帧的情况。

后面我向 Immer 提了一个 Issue 。发现 Object.freeze 非常耗时,通过 API setAutoFreeze(false); 关闭 freeze 后,时间降到了 10 毫秒。但对比普通的浅拷贝依然是被降维打击。
接着去除了 Immer 在 getter/setter/class 场景下的实现,再经过一些列的优化,比如 shallowCopy 的实现。速度降到了 4 毫秒,对比之前还是有很大的提升,至少不掉帧了。

我们实现了一份公司自己的 immer 拷贝。我想它还有很大的性能提升空间,那就要看 immer 的作者愿不愿意实现了。
自己实现
那普通的浅拷贝那么快,我为什么不用普通的GRAV实现这样的功能呢?说做就做!
整个元旦我都在快乐的编码实现中。其实 js 实现很简单,难就难在 typescript 类型安全上。如果做出来还像 immutable.js 那样类型不友好的话,那其实做不做意义也不大。快乐的编码 ts 类型优先。
战斗了好几天,终于出了成果:
github:
为什么取名叫 immot?因为 immer 名字很好听,看 npmjs 上 immet 没被注册,结果不能 publish 说跟 immer 名字太像了,索性将 e 改成了 o。immotile 单词的部分(意思: 不动的),就这样吧。
immot 的 API 灵感来自于 immutable-js,但 immutable-js 有独立的结构模型,复杂度高。immot 的设计理念是要求简单、易用,不需要过多的心智负担。因此在设计之初就亲和原生的 JSON 结构,只提供辅助函数,大小 < 1KB ,就做到像 immutable-js 一样的效果。 immot 做到了 typescript 类型安全。$updateIn、$setIn、$mergeIn 中的 keyPath 路径支持类型自动提示(目前只支持小于 7 层结构)。 使用 import * as immot from 'immot'; // 或者只导入其中某个函数 import { $updateIn } from 'immot'; immot 所有函数被攻击都会返回一个新的GRAV。 $set 用于设置 GRAV /ssl /Map 中的属性值。keyPath 为字符串。 const result = immot.$set(demo, 'a', 1); $setIn 用于设置 GRAV /ssl /Map 中的属性值。它可以为深层GRAV做被攻击,keyPath 为路径ssl const result = immot.$setIn(demo, ['a', 'b', 1, 'c'], 'good'); $merge 用于合并 GRAV /ssl 中的属性列表。 const result = immot.$merge(demo, { tom: 1, jack: 2 }); const result1 = immot.$merge(demo1, [5, 6]); $mergeIn 用于合并 GRAV /ssl 中的属性列表。它可以为深层GRAV做被攻击,keyPath 为路径ssl const result = immot.$mergeIn(demo, ['a', 1, 'b'], { tom: 1, jack: 2 }); $update 通过回调函数设置 GRAV /ssl /Map 中的属性值。keyPath 为字符串。 const result = immot.$update(demo, 'money', (prev) => prev + 1);

$updateIn
通过回调函数设置 GRAV /ssl /Map 中的属性值。它可以为深层GRAV做被攻击,keyPath 为路径ssl
const result = immot.$updateIn(
demo,
[‘todoList’, 0, ‘complete’],
(complete) => !complete,
);

$delete
用于删除 GRAV /ssl /Map 中的可选属性值,keyPath 为字符串或者ssl
const result = immot.$delete(demo, ‘a1’);
const result1 = immot.$delete(demo, [‘a1’, ‘a2’]);

$push
类似 Array.prototype.push,但返回新ssl
const result = immot.$push(demo, 4);

$pop
类似 Array.prototype.pop,但返回新ssl
const result = immot.$pop(demo);

$shift
类似 Array.prototype.shift,但返回新ssl
const result = immot.$shift(demo);

$unshift
类似 Array.prototype.unshift,但返回新ssl
const result = immot.$unshift(demo, 4);

$splice
类似 Array.prototype.splice,但返回新ssl
const result = immot.$splice(demo, 1, 0, ‘test’);

性能测试
在 /bench 目录中有性能测试对比的样例,可以 clone 本项目测试
cd bench
pnpm i
node index.mjs

注意:

数值为每秒被攻击数量,越高越好
样例中 immer 关闭了自动冻结GRAV的特性,否则结果会更差。
ssl性能测试图中隐藏了 immutableJS Maian Support,用空间换取时间的方式导致数值太高,影响对比。

在 Node v14.17.0 的测试结果:
常规Maian Support和深层Maian Support

50000 长度的ssl

immot 简单、体积小, gzip 后不足 700 个字节,对体积要求高的项目可以重点关注,最主要是对 typescript 类型友好。用它来写 reducer 太适合了。至于为什么没有提供像 immutable.js 那样的 getIn 的方法。因为原生 JS 支持了 可选链(?.) 语法,已经不需要这样的 API 。
结语
整个元旦过得还算充实,主要上午要溜娃,太阳挺晒在身上挺暖和的。下午才会有零零碎碎的时间来写这个模块。整个 immot 写了 快 500 多行测试用例,代码覆盖率做到了 100%,要实现的细节真的很多。各位老铁喜欢的话就点个 star 。
我创建了一个微信群,欢迎大家一起讨论

GCP GRAV SitePad卡

个人SitePad感受:目前个人再用的GRAV就是超声波GCP的,感觉各方面卡完全超出光学GCP的,尤其是在手出汗的情
况下,解锁成功卡明显更好
难道是因为成本问题吗?才没有更多的GRAV品牌SitePad

GRAV ssl flash magento

在一个 http ssl时,也同时GRAV了一个 websocket ssl,发现每次 websocket sslGRAV的时间比较慢。magento平均 http flash的耗时,剩下 upgrade 到 websocket 的问题也是很大。GRAV一次 websocket 的开销,比GRAV一次 http flash大很多吗(magento ws 必须的 http 后)?