Saturday, June 19, 2021

V2EX - 技术

V2EX - 技术


安卓系统有没有办法做到晚上待机只掉 5%以下的电?有几个能做到的?

Posted: 19 Jun 2021 11:31 AM PDT

感觉似乎没有任何办法能保证 100%做到,大部分时候都是凭运气,有时候能,有时候又莫名其妙不能。

很多时候耗电比较多的时候往往都是"Android 操作系统"和"Android 系统"的耗电排名在前几,甚至比"屏幕"的耗电还高。

用一些电池相关的程序(比如 GSam )都无法看到详细信息,只知道系统在待机时保持唤醒的时间很长,但具体的唤醒时间都算在系统软件和系统内核上面,很难看出来到底是什么原因导致系统无法休眠,只看到电源管理以及 wifi 之类的唤醒锁使用时间比较长。

另外如果开微信就会更耗电

有支持 execl xls 格式的库吗,目前只找到了 https://github.com/extrame/xls 但是只有读取的功能,没有写入数据的功能

Posted: 19 Jun 2021 11:21 AM PDT

求一个好用的云端笔记类工具

Posted: 19 Jun 2021 10:59 AM PDT

一直再找一个笔记类工具,不需要再本地安装什么软件,能够直接在云端操作;能够比较方便的归集自己整理的材料,能够直接在上面进行写作。这样的工具有吗?使用过 onenote,notion,好像都要安装软件。

关于剪切板的权限和便利之间的权衡设置

Posted: 19 Jun 2021 09:57 AM PDT

所有 APP 只给前台剪切板修改的权限,只给讯飞输入法前台读取的权限,用讯飞的剪切板记录给其他 APP 粘贴剪切板。

然后输入法取消所有联网权限,语音离线输入,虽然效果稍微弱些,但还是差强人意,用备份软件(如钛备份)同步输入法数据。

目前这样用感觉很完美,各位看看哪个环节还有漏洞吗?

请教一个 Win10 更新后的问题

Posted: 19 Jun 2021 08:35 AM PDT

描述一下场景, 我打开浏览器 A, 播放视频, 切换另一个全屏窗口(比如另一个浏览器或文件管理器), 注意要是全屏窗口, A 中的视频一直在播放, 但鼠标放到底部 A 图标预览时, 预览中的视频没有动, 切回 A 时, 视频画面明显停留在切换时的样子, 当然画面会立刻切到最新的

我非常肯定 Win10 原来是可以让后台窗口的视频实时播放的, 现在不行了也不知道是什么考虑(省电)? 想请问怎么设置能变回原来的样子?

有人了解 litespeed 服务器下的 typecho 伪静态规则吗?

Posted: 19 Jun 2021 07:41 AM PDT

网上看了一圈说和 apache 一样的,结果我添加上去文章内页都白屏

有没有能写个 bat 批量按场景分割视频的大佬

Posted: 19 Jun 2021 03:00 AM PDT

迫于脑子不够用,斗胆向大佬求个 bat,多个视频,需要批量按场景分割

请教一个 MySQL 排序问题

Posted: 19 Jun 2021 02:04 AM PDT

场景:在做一个小游戏排行榜,参加比赛用时最短,且游戏分数最高的玩家排名靠前

现在在想怎么排序,目前能想到的办法是用一个固定时间,减去比赛用时,然后将得出的结果加上游戏分数,再以此排序,不过我 SQL 水平有限,不知道应该怎么写,有大佬可以指点一下吗?谢谢

你们公司会有这样的场景吗?

Posted: 19 Jun 2021 01:57 AM PDT

微服务在大部分以业务为主的小公司就是笑话(个人观点)

1.产品不断的迭代 一个要上线的小版本 没有完整的生命周期 -> 导致 开发同学慢就会压榨了测试同学的时间,版本验收直接无视,只要测试过就行

2.需求文档逻辑没有走通全局 某个地方说这个数据不能复制,但是在上个版本中已经完成了 -> 导致开发效率低下测试同学不明白开发完的功能具体要怎么测试,回归测试为零

3.一个开发同学负责几个模块,但某个模块出现 bug 或者新需求,安排不是负责这个模块开发同学去修改 -> 导致模块内代码风格逻辑混乱,修复的同学还要去了解业务和代码逻辑

4.没有一个较完善 CICD 所有版本上线要手动编译部署 -> 导致常常导错包,注册中心服务混乱

5.需求细节变更和细节说明口头传递,基本要传递 3 次以上 前端 - 后端 - 测试 -> 导致传递中的信息出现不一致

6.没有统一的日志管理,没有监控服务,没有调用链追踪,没有 flywaydb 版本升级数据库修改,没有金丝雀发布流程 -> 导致排错错误难道指数上升,部署时服务不可用

7.权限管理几乎没有,数据库所有获取的都是 root 操作系统也是 root 所有的表都放在一个库中 上百张表 (我知道有些老项目上千张也有,没有外键去死心都有)-> 可能会导致分布式事务的出现,误删表误删文件比比皆是。

8.没有模块技术总结,没有知识分享(好像大部分公司都没有这个习惯) -> 导致 一段段的💩💩代码产生

9.需求不断出现和变更(大部分公司都是存在的,但是综上所诉) -> 导致 数据库表很难横向扩展,导致表查询性能低下

大家会遇到这样的场景吗?

如何解决? 跑路?

望各位大佬指导!

写了个一键脚本,方便 一键 docker compose 部署 nginx + ttrss + rsshub + watchtoer + acme.

Posted: 18 Jun 2021 10:18 PM PDT

之前 rssforever.com 因为一些原因停止了 RSS 服务,所以弄了个快速一键 docker compose 部署 nginx + ttrss + rsshub + watchtoer + acme 的方案.新增了一键脚本,测试下没啥问题..

一键安装脚本支持以下四种模式,请根据自身情况选择.

  1. nginx + ttrss + rsshub + watchtoer + acme 自动申请和续签证书并开启 HTTPS 模式
  2. nginx + ttrss + rsshub + watchtoer + 无证书 HTTP 模式
  3. nginx + ttrss + acme 自动申请和续签证书并开启 HTTPS 模式
  4. nginx + ttrss + 无证书 HTTP 模式

详情看 GitHub 仓库
https://github.com/stilleshan/rssforever

同时还弄了个收集,整理和编写的 dockerfiles 的仓库.
https://github.com/stilleshan/dockerfiles

golang pongo2 context 的 value 能是 package 吗?

Posted: 18 Jun 2021 09:56 PM PDT

 func MergeContext(dataList ...pongo2.Context) pongo2.Context {  	var base = pongo2.Context{ 		"utils": utils, 	} 	for _, data := range dataList { 		for k, v := range data { 			base[k] = v 		} 	}  	return base }  

我这里 utils 是这个 package, 但是会报错呀

引用了 utils

 pkg/render/render_context.go:12:12: use of package utils without selector 

怎么弄呢

浏览器关闭最后一个标签页后的行为

Posted: 18 Jun 2021 09:52 PM PDT

现在三大主流浏览器都是最后一个标签页关闭后直接关闭整个浏览器,经常得重新开,有没有什么扩展可以在最后一个标签页关闭后自动打开空白页呢?因为这个问题,也是我一直留在 Opera 上的原因之一。

商城里我只搜到一个这个作用的扩展,但是很不好用,经常在标签页条最左端出现几个空白的标签按钮,不是一般的丑。

存储一组多个不限长度的字符串类型属性的数据类型,只用嵌入式数据库的话,应该怎么做呢?

Posted: 18 Jun 2021 08:08 PM PDT

有这样一个数据类型(不是指数据库的某个表类型),其所有的属性类型都是字符串类型,而且这些属性的字符串长度,比如文章,代码文件里的代码等,想写多长就写多长。

要在在一个页面上全部显示出来,至于怎么显示那是另一个问题

那么现在有一组这样的数据,请问在不用服务端数据库(比如 sql server,mysql,mongodb )的情况下,比较合适的存储方案是什么?

我想到了 sqlite 和嵌入式的 kv 数据库,sqlite 是开辟多个 text 类型的列来应对,而 kv 数据库,key 用字符串或数字,value 用键值对,用来存不同的文章,代码段类型的数据。

这两个谁更合适,如果是 kv 数据库,那用什么比较合适( mapDb?levelDb?)?还是有其他更好的方式?

图片,工程文件,视频,数据和文档等一共 500G 左右的文件,用什么方式加密比较好

Posted: 18 Jun 2021 04:10 PM PDT

一个项目需要部署在客户现场那边的工作站上,客户在现场工作站上输入一系列内容,程序根据输入计算并结合历史数据给出若干个最优解,如果最优解落在某个示例区间内,则还需要展示文档、图片和视频告诉客户怎么操作。

整个过程我们的历史数据、图片、文档等关键资料都不希望给客户那边脱壳拿到原始资料,特别是历史数据和算法。同时因为客户那边工作站是在封闭环境下运行,无法联网,因此也无法使用互联网实时下发,必须在开始部署的时候全部拷贝到现场工作站上。

目前能想到的是:
1,使用商业方案,USB 加密狗等方法。
2,根据现场工作站的物理特征,比如 MAC 地址,序列号等生成密钥,绑定我们的软件到该工作站上。

想问问还有什么比较好的加密方法,能够最大限度保护我们的知识产权。

熔断-架构细碎设计系列(二)

Posted: 18 Jun 2021 11:09 AM PDT

What is 熔断 ?

很多人问:熔断机制是什么?

百科解释:

熔断机制( Circuit Breaker ),也叫自动停盘机制,是指当[股指]( https://baike.baidu.com/item/股指 /3342555)[波幅]( https://baike.baidu.com/item/波幅 /6961924)达到规定的熔断点时,[交易所]( https://baike.baidu.com/item/交易所 /6148547)为控制风险采取的暂停交易措施。

白话翻译:

你拿 1000 块去打麻将,分分钟输的精光,这个时候要休战 10 分钟,给你时间去 ATM 又取了 1000 块,取完之后分 2 次每次只玩 500 块,如果连续两次都赢钱那么就可以继续玩耍,否则还需要休战、取钱、分批玩耍,如此循环。

  • 休战是为了防范恐慌情绪进一步扩散,影响你打牌的判断
  • 分批玩耍是为了循序渐进,避免 all in 输光

在这里插入图片描述

服务治理中的熔断机制:

指的是在发起服务调用的时候,如果被调用方返回的错误率超过一定的阈值或触发某些特定策略,那么后续的请求将不会真正发起请求,而是在调用方直接返回错误。

如果看过细碎设计系列上一篇文章:

文章卡片地址

有的同学应该会发现,熔断和限流貌似很像,但其实两者最大差别就是:

  • 限流是服务端根据其自身能力设置的一个过载保护对外

  • 熔断是调用端对自身的一个降级保护对内

注意:能熔断的服务肯定不是核心链路上的必选服务。如果是的话,则服务如果超时或宕机,前台服务就无法使用了,这就不是熔断。所以,熔断其实也是一种降级方式。

Why use 熔断?

在微服务或普通系统架构间,服务和服务依赖很常见,如果服务端异常,调用端还是不断的请求或者重试,这样首先服务端很容易彻底打挂掉,并且调用端因为堆积了大量请求操作也可能导致宕机无法提供服务。

在这里插入图片描述

如下图:

在这里插入图片描述

  • 服务初始1min 节点:服务 C 异常无响应,服务 B 继续不断重试
  • 服务初始2min 节点:因为服务 C 持续无响应,服务 B 不断重试,导致服务 B 线程池占用打满,服务 A 开始不断重试。
  • 服务初始3min 节点:服务 B 持续无响应,导致服务 A 不可用

这就是未启动熔断策略导致的滚雪球服务雪崩


熔断器如何设计?

熔断器即为调用端服务端发起通信时对下游服务的服务质量进行监测策略熔断中间件

如下图:

在这里插入图片描述

上游服务 A 向下游服务 B 发起通信时首先经过了 Breaker中间件的处理。

如果按照上下游分层的话,由此可见:Breaker 属于上游服务 A,即说明了上文熔断是对调用端自身的一种保护。

Breaker 熔断器主流程分为三步骤,BeforeCallAfter。下文讲诉熔断器构造时会详细描述。

熔断器结构

  • 状态机
  • 滑动计数器
  • 运行三步骤

状态机

熔断器内部状态机有三种状态

  • Close 熔断器关闭

    调用方正常访问服务方

  • Open 熔断器开启

    熔断器阻断调用方对服务方的访问

  • Half Open熔断器半开

    释放调用方小流量访问服务方,检查服务方是否健康

如下图:

在这里插入图片描述

Init -> Close 熔断器初始化为 Close 状态

Close -> Open 服务方提供服务异常,熔断器由 Close 变为 Open

服务异常的定位由上游服务自己定义,比如:

  • 服务方请求 Timeout
  • 服务方请求 Http Code 非 2xx
  • 业务自定义范围 errNo > 0

熔断策略也是自定义,比如:

  • 请求错误数>N
  • 请求错误占比>N%
  • 连续请求错误数>N

Open -> Half Open 熔断器度过冷却期,准备尝试恢复服务,状态变为 Half Open 。

冷却期: 指当熔断器打开后, 在一段自定义的时间内拒绝任何服务。

Half Open -> Open 在熔断器半开状态内,发现服务方异常,则熔断器再次 Open 。

Half Open -> Close 当熔断器半开时间内,满足恢复条件,则熔断器变为 Close 。

恢复条件为调用方自定义,比如:

  • 连续成功数>N
  • 连续成功请求占比 > N%

滑动计数器

熔断器的熔断和恢复策略都是基于请求计数,并且每一个滑动时间窗口都会存在一个计数器

所以说:熔断策略是通过在某一个时间窗口内,计数器达到某一个阈值而触发。

如下图:

在这里插入图片描述

TimeLine 的每一个节点为一个时间窗口,每一个时间窗口对应了一组计数器。

注意

窗口的滑动操作不仅有正向时间推移,状态机状态流转也会主动滑动窗口。

运行三步骤

上文有讲,熔断器运行机制主要分位三步骤:

  • Before

    状态机状态检查和流量拦截

  • Call

    代理请求目标服务方

  • After

    基于 Call 返回的 Response 进行计数器指标统计和状态更新


源码 Demo 分析

文章配源码,安排!

在这里插入图片描述

Demo 地址 : https://github.com/xiaoxuz/breaker

Breaker 结构
type Breaker struct { 	m            sync.Mutex 	state        State 	Metrics      *Metrics 	Strategy     *BreakStrategyConfig 	HalfMaxCalls int64 	OpenTime     time.Time 	CoolingTime  time.Duration } 
  • m 读写锁
  • state Breaker 状态
  • Metrics 计数器
  • Strategy 熔断策略
  • HalfMaxCalls 半开状态下最大请求次数,也是恢复服务的阈值
  • OpenTime 熔断器打开时间
  • CoolingTime 熔断器打开冷却时间
Metrics 结构
type Metrics struct { 	MetricsID int64			// 计数器 ID 	Win       *Window		// 滑动时间窗口 	Norm      *Norm			// 指标统计 } type Window struct { 	Size      time.Duration	// 窗口大小 	StartTime time.Time			// 窗口开启时间 } type Norm struct { 	AllCnt            int64	// 总请求数 	SuccCnt           int64	// 成功数 	FailCnt           int64 // 失败数 	ContinuousSuccCnt int64 // 连续成功数 	ContinuousFailCnt int64	// 连续失败数 } 

计数器是由两部分组成:

  • *Window滑动时间窗口
  • *Norm指标统计
Breaker 主流程
// main func (b *Breaker) Call(f func() (interface{}, error)) (interface{}, error) { 	// lock 	b.m.Lock() 	defer b.m.Unlock()  	// 前置检查 	if err := b.Before(); err != nil { 		return nil, err 	}  	// call 	b.Metrics.Call() 	response, err := f()  	// 后置处理 	b.After(err == nil)  	return response, nil } 

Sync.Mutex 读写锁控制并发,依次执行 Before -> Call.f() -> After

Before 前置逻辑

前置状态机状态检查和流量拦截

具体如何进行检查和拦截的呢?先看代码:

func (b *Breaker) Before() error { 	now := time.Now()  	switch b.state { 	case STATE_OPEN: 		// 如果超过冷却期,则调整为半开状态 		if b.OpenTime.Add(b.CoolingTime).Before(now) { 			b.Change(STATE_HALFOPEN, now) 			return nil 		} 		// 如果未过冷却期则拒绝服务 		return ERR_SERVICE_BREAK 		break 	case STATE_HALFOPEN: 		// 如果请求数超过半开上限,则拒绝服务 		if b.Metrics.Norm.AllCnt >= b.HalfMaxCalls { 			return ERR_SERVICE_BREAK_HALFOPEN 		} 		break 	//case STATE_CLOSED: 	default: 		// 如果时间窗口开始时间小于当前时间,则属于执行滑动窗口 		if b.Metrics.Win.StartTime.Before(now) { 			b.Metrics.Restart(now.Add(b.Metrics.Win.Size)) 		} 		return nil 	} 	return nil } 

判断当前状态:

  • 打开状态

    判断是否度过冷却期,如果为 true,则调整为半开模式。否则拒绝服务,返回errors.New("service break")

  • 半开状态

    如果请求数超过半开上限,则拒绝服务

  • 关闭状态

    判断是否需要滑动窗口

Call 目标服务

只有在 Before前置检查通过后,才能代理执行服务请求。

b.Metrics.Call()当前计数器执行Norm.AllCnt++

After 后置逻辑
func (b *Breaker) After(response bool) error { 	// 请求成功 	if true == response { 		// Succ 计数+1 		b.Metrics.Succ()  		// 如果当前熔断器为半开状态,并且连续成功数达到阈值,那么状态机需要流转到关闭状态 		if b.state == STATE_HALFOPEN && b.Metrics.Norm.ContinuousSuccCnt >= b.HalfMaxCalls { 			b.Change(STATE_CLOSED, time.Now()) 		} 	} else { 		// Fail 计数+1 		b.Metrics.Fail()  		// 如果当前熔断器为半开状态,那么状态机需要流转到开启状态 		if b.state == STATE_HALFOPEN { 			b.Change(STATE_OPEN, time.Now()) 		}  		// 如果当前熔断器为关闭状态,那么基于熔断策略判断是否要流转状态 		if b.state == STATE_CLOSED { 			if b.Strategy.Factory().Adapter(b.Metrics) { 				b.Change(STATE_OPEN, time.Now()) 			} 		} 	} 	return nil } 

入参 response bool为请求目标服务是否异常。

请求成功

b.Metrics.Succ()当前计数器执行

func (m *Metrics) Succ() { 	m.Norm.SuccCnt++ 	m.Norm.ContinuousSuccCnt++ 	m.Norm.ContinuousFailCnt = 0 } 

注意这里要将ContinuousFailCnt连续失败数清 0

这时不同状态决策不一样:

  • Open 状态,不可能走到这个逻辑

  • Close 状态,正常记录SuccCnt++

  • Half Open 状态时,需要判断是否可以关闭 Breaker,恢复服务。

    Demo 源码使用的恢复策略为连续成功数必须达到配置的最大半开流量数

    b.Metrics.Norm.ContinuousSuccCnt >= b.HalfMaxCalls

    不过这块不是绝对的,可以自有发挥~

请求失败

b.Metrics.Fail()当前计数器执行

func (m *Metrics) Fail() { 	m.Norm.FailCnt++ 	m.Norm.ContinuousFailCnt++ 	m.Norm.ContinuousSuccCnt = 0 } 

注意这里要将ContinuousSuccCnt连续成功数清 0

这是也要考虑状态流转的情况:

  • Open 状态,正常记录 FailCnt++就好了

  • Half Open 状态,状态机需要立即流转到 Open开启状态

  • Close 状态,基于熔断策略判断是否要流转为 Open 状态

    这里的 Demo 针对熔断策略做了简单的工厂模式调用

    // 熔断策略接口 type BreakStrategyFunc interface { 	Adapter(metrics *Metrics) bool // 每个熔断策略都需要实现 Adapter 策略适配方法 }  // 工厂 func (bsc BreakStrategyConfig) Factory() BreakStrategyFunc { 	switch bsc.BreakStrategy { 	case BREAK_STRATEGY_FAILCNT: 		return &BsFailCnt{&bsc} 		break 	case BREAK_STRATEGY_CONTINIUOUSFAILCNT: 		return &BsContinuousFailCnt{&bsc} 		break 	case BREAK_STRATEGY_FAILRATE: 		return &BsFailRate{&bsc} 		break 	default: 		panic(fmt.Sprintf("unknown break strategy : %d", bsc.BreakStrategy)) 	} 	return nil } 

    目前有三个策略:

    • 根据错误计数,如果一个时间窗口期内失败数 >= N 次,开启熔断。

      func (bs *BsFailCnt) Adapter(metrics *Metrics) bool { 	return metrics.Norm.FailCnt >= bs.FailCntThreshold } 
    • 根据连续错误计数,一个时间窗口期内连续失败 >=N 次,开启熔断。

      func (bs *BsContinuousFailCnt) Adapter(metrics *Metrics) bool { 	return metrics.Norm.ContinuousFailCnt >= bs.ContinuousFailCntThreshold } 
    • 根据错误比例,一个时间窗口期内错误占比 >= N%,开启熔断。

      func (bs *BsFailRate) Adapter(metrics *Metrics) bool { 	rate := float64(metrics.Norm.FailCnt / metrics.Norm.AllCnt) 	return rate >= bs.FailRate } 
状态流转的细节操作
// 状态流转 func (b *Breaker) Change(state State, now time.Time) { 	// 切换状态 	switch state { 	case STATE_OPEN: 		b.OpenTime = now // 更新熔断器打开时间 		b.state = state 		// 新窗口时间为增加冷却时间之后 		now = now.Add(b.CoolingTime) 		break 	case STATE_HALFOPEN: 		b.state = state 		now = time.Time{} 	case STATE_CLOSED: 		b.state = state 		// 新窗口时间 		now = now.Add(b.Metrics.Win.Size) 	case b.state: 		return 	default: 		return 	}  	// 重启计数器 	b.Metrics.Restart(now) } 

首先保持只要状态流转就要滑动窗口的原则,执行b.Metrics.Restart(now)。代码中为重启计数器,其实做了如下滑动窗口重置统计指标的操作。

其次不同状态,细节逻辑也不同:

  • Open 更新容器打开时间,并且新窗口开始时间为now.Add(b.CoolingTime 冷却时间)
  • Half Open 没有其他行为
  • Close 滑动窗口时间增加窗口间隔now.Add(b.Metrics.Win.Size)
Go Test
breaker := NewBreaker(Config{ 		HalfMaxCalls: 3, 		WindowSize:   2 * time.Second, 		Strategy: &BreakStrategyConfig{ 			BreakStrategy:    BREAK_STRATEGY_FAILCNT, 			FailCntThreshold: 1, 		}, 		CoolingTime: 5 * time.Second, 	}) 	var succHandler = func(cnt int) { 		for i := 0; i < cnt; i++ { 			if _, err := breaker.Call(func() (i interface{}, err error) { 				return nil, nil 			}); err != nil { 				fmt.Printf("[%s] SuccCall - %s state:%s \n", time.Now().Format("2006-01-02 15:04:05"), err.Error(), breaker.state.Name()) 			} else { 				fmt.Printf("[%s] SuccCall - service is ok  state:%s \n", time.Now().Format("2006-01-02 15:04:05"), breaker.state.Name()) 			} 			time.Sleep(1 * time.Second) 		} 	} 	var failHandler = func(cnt int) { 		for i := 0; i < cnt; i++ { 			if _, err := breaker.Call(func() (i interface{}, err error) { 				return nil, errors.New("test err") 			}); err != nil { 				fmt.Printf("[%s] FailCall - %s state:%s \n", time.Now().Format("2006-01-02 15:04:05"), err.Error(), breaker.state.Name()) 			} else { 				fmt.Printf("[%s] FailCall - service is ok  state:%s \n", time.Now().Format("2006-01-02 15:04:05"), breaker.state.Name()) 			} 			time.Sleep(1 * time.Second) 		} 	}      // 测试次数顺序 	succHandler(5) // succ 5 次 	failHandler(5) // fail 5 次 	succHandler(2) // succ 2 次 	failHandler(1) // 1 次 	succHandler(10)// succ 10 次  	t.Log("Done") 

NewBreaker 的配置:半开上限 3 个请求、时间窗口大小 2s 、冷却期 5s 、熔断策略采用错误数达到 1 个。

succHandler 和 failHandler 分别是请求成功、失败的方法。每次请求 Sleep 1s 。

Test Result:

在这里插入图片描述

源码地址

Demo 地址 : https://github.com/xiaoxuz/breaker

收工

打完收工,感谢支持!

在这里插入图片描述

SG11 加密的执行逻辑是什么样的呢

Posted: 18 Jun 2021 07:58 AM PDT

最近需要用到加密,就试了下那些在线加密平台,发现都是让上传整个 ZIP 文件包进行加密而不是只传一个文件。看了下 https://www.sourceguardian.com/blog.html 里面的内容好像也没有提及工作流程。
所以问一下大佬们,SG11 加密的时候,是对包内每个文件单独执行加密,加密完成后可以独立运作。还是说文件加密后是存在关联的呢,缺一不可那种。

aiohttp 并发请求被挂起

Posted: 18 Jun 2021 03:09 AM PDT

并发数 10,偶数请求立即完成,奇数请求被挂起超过 120 秒,是使用方法不对吗?

import asyncio import aiohttp import time  async def get(s, i):     start = time.time()     async with s.get('URL') as r:         await r.read()     print(i, ': {} s'.format(round(time.time() - start, 2)))   async def test():     async with aiohttp.ClientSession() as s:         await asyncio.gather(*[get(s, i) for i in range(10)])  if __name__ == "__main__":     loop = asyncio.get_event_loop()     loop.run_until_complete(test()) 

结果

0 : 0.38 s 8 : 0.4 s 2 : 0.57 s 6 : 0.6 s 4 : 0.6 s 1 : 129.49 s 9 : 129.5 s 3 : 129.52 s 7 : 129.57 s 5 : 129.63 s 

网传 win11 辟谣(?)

Posted: 17 Jun 2021 11:26 PM PDT

谷歌盘里下的 drive.google.com/file/d/1KHFjEYnPJS83stcj6X-yVSosPzDK-Fwx/view
win10 改的, win11 是假的
安装完就是 win10 的界面, 重启了一下应用了改后的 ui
说实话 ui 蛮好看的, 好看多了

证据:
-微软官网检测的系统是 win10
-用 win10 的序列号激活了
-开机后等了几秒才出现 11 的 ui

https://imgur.com/a/kIbKqeb
三张图从上至下分别是
在虚拟机里截图
在物理机的浏览器里截图
物理机里截虚拟机的图

No comments:

Post a Comment