Thursday, May 13, 2021

V2EX - 技术

V2EX - 技术

V2EX - 技术


大家使用 redis 的时候,有考虑 redis 挂的场景?

Posted: 13 May 2021 04:09 AM PDT

大家使用 redis 的时候,有考虑 redis 挂的场景吗?比如挂了走本地缓存,但是感觉想一想实现的好复杂,大家都是怎么处理的?

有无办公用的键盘推荐

Posted: 13 May 2021 04:04 AM PDT

RT,想练习一下然后提高自己的打字速度了,但是现在用的是薄膜键盘手感很差,于是想买一把键盘写代码用。 入门级的就好,预算 300 以内,如果这个价位没什么推荐的话 400 以内也能接受。

需求是声音不大(满公司都是我打字的声音会社死) 体积适中(不想太显眼) 可以不要小键盘(方便跑路) 好看!(高颜值提升 200% 办公效率,不要 RGB )

希望 V 友可以推荐一下,秋梨膏

程序员应该去大厂吗

Posted: 13 May 2021 04:03 AM PDT

毕业之后一直在一家几百人小公司,前后端全干,到今天快 5 年了,几次加薪之后也基本满意,比大厂 5 年的薪资水平差点,但好在不加班。

生活一直平静如水,像是一眼能看到底,想追求点刺激,又怕自己吃不消。这把年纪了,应该去大厂拼搏下吗?对于职业生涯来说,有价值吗?

请喝咖啡征集软件代号

Posted: 13 May 2021 03:53 AM PDT

晚上睡不着,突然想给我现在开发的软件当前的版本取个代号,软件名字叫 BoardOS,是一款在线实时协作白板软件。请大家帮帮忙,代号釆用后请喝咖啡、以后还会送会员、加入感谢列表、还可以一起打王者!

把 app 部分功能开关放在域名 txt 记录中如何?

Posted: 13 May 2021 03:41 AM PDT

目的是省个服务器,
背景是,app 主要功能不依赖服务器,服务器只提供极少配置信息以及一个附属功能,使用时连不上就放弃,
后来发现效果不好,懒得维护相关功能就直接把服务器域名解析到 127.0.0.1 了,可是发现就这居然还偶尔出现尝试连接服务器浪费了几秒的情况,
排查发现是网络呆理软件异常,对 app 来说服务器连接上了等待响应,实际上只是卡住了,
于是我就提前加个判断,域名提前解析一下,指向本地就直接关闭相关服务,

然后突然觉得,既然都提前 dns 解析了,不如干脆做个 txt 记录的解析,内容放个 json 之类的直接把配置信息自带了,要开关什么直接改 txt 记录就好,0 成本,也能避免服务器停止维护时连几个简单配置都获取不到,

想知道有没人这么做过的,不是在必须 txt 记录的情况使用 txt 记录,而是为了降低成本强行使用的 txt,
想知道有没什么坑,能想到的就只有解析记录更改不会实时生效,这点我这可以接收,

为什么微软这么大的公司,地下的应用一堆 bug?

Posted: 13 May 2021 03:37 AM PDT

这一段时间写论文,用 word2019,发现一堆 bug 包括什么自定义图表标题没办法输入中文的。 然后用 outlook 整合邮箱,网上一堆人死命推荐,结果用来,bug 多到恶心。 outlook 的多次可复现的问题有:

1 、ios 端 imap/smtp 整合 163 邮箱 qq 邮箱后台不推送通知(看后台的确有实时发送 imap 报文)

2 、ios 端标记邮件已读后又自动恢复为未读、需要杀掉应用再打开才能标记为未读。

3 、Mac 端 outlook 的归档会自作聪明的归档到中文的"存档"文件夹,且不能修改,而其他的第三方会归档到默认的 Archive 文件夹中,且可以修改。

4 、Android 端 outlook 删除账户时选择所有设备时,会删不掉账户

5 、Android 端的日程安排不能推送,必须要在后台常驻才可以

···· 我很不解的是,为什么微软这么大的公司,底下的应用还能有一堆影响很大的 bug 其次,为什么这么垃圾的应用一堆人吹???????

ps:最后转成 Email-Edison,体验极好,与之对比下 outlook 简直拉垮!

win10 系统进程 svchost.exe 会上传什么东西?

Posted: 13 May 2021 03:24 AM PDT

经常发现上传数据速度挺快,查了一下发现是系统进程 svchost.exe 在占用宽带上传,而且频率较高,它到底在上传什么东西? 系统 win10,华为 magicbook 笔记本,因为之前电脑故障,售后直接重装了 win10 。

在某大厂的朋友告诉我说,你想用台式机是不太可能的

Posted: 13 May 2021 03:04 AM PDT

可以申请显示器,可以给你 MacBookPro,但是不会给你台式机(如果有 iMac Pro 我肯定选它,哈哈) 反而在事业单位办公的,基本都是用台式机
这肯定不是成本的问题
除了某些场景必须用笔记本比如说开会或者在家 on call
为什么不能多给一个在工位上用台式机的选择呢? 毕竟长期使用电脑,台式机当主力肯定比笔记本体验要好得多

有没大神知道外面有什么靠谱点的公司能提供汇率换算 api 的?

Posted: 13 May 2021 02:52 AM PDT

如题,帮朋友问的。

先谢谢啦!

分页显示的数据,各位开发时设定的每页或滚动加载显示的最小和最大的数据量是多少?

Posted: 13 May 2021 02:52 AM PDT

数据量大,不能一次性传过去,就得分页或者滚动加载。

那么各位开发的,在分页或滚动加载上的数量设定上,设定的最小页数和最大页数是多少? 20 个? 50 个? 100 个?

我觉得 20 个和 100 为最小和最大了

求推荐 简单 轻量 的 Java 异步任务框架

Posted: 13 May 2021 02:49 AM PDT

如题。目前公司里面用的是公司自己的异步任务框架,应该是基于 Kafka 做的。

想好好深入学习一下,有什么比较好的开源的,比较轻量的异步任务框架吗?(比如同样基于 Kafka )

关于爬虫这块有个比较好奇的问题,想请教

Posted: 13 May 2021 02:48 AM PDT

每次爬虫之后,到数据库里面去,那假如说有重复的怎么解决? 是直接在写数据库方法的时候处理?

先用条件去判断这些数据有没有,有的话,更新?没有就插入?这样解决?

还是在页面显示的时候解决?用关键的字段去判断,然后去重,再显示最近的一条?

爬虫菜鸟一枚

Java 内存模型中的工作内存跟主内存的物理概念是什么

Posted: 13 May 2021 02:41 AM PDT

本地内存=cpu 高速缓存?
主内存=内存?
不知道这样理解对不对,看到网上有人说本地内存=cpu 寄存器里的内容,但是我细细一想,如果指的是 cpu 寄存器,那假设有个 cpu 是单核的,只有一个核心,也就是说只有一个寄存器,那本地内存跟主内存之间的可见性问题不就不存在了?因为内存就一份,本地内存也就一份了(一个寄存器)。
求解答。

小白请教一下解决方案,公司内部多个独立的系统, http 接口的调用如何保证数据一致性

Posted: 13 May 2021 02:29 AM PDT

  • 背景:没有顶层设计、独立开发的内部系统:项目管理系统、erp 系统、人资系统... 已经经过 4 、5 波的人了*
  • 跨系统的一些功能如:在 erp 请假,项目管理系统自动生成日志; 项目管理系统写了加班日志自动往 erp 生成加班申请 *

这些功能都是直接调用 http 接口实现的,没有分布式事务框架,如何轻量的提高数据一致性

求问大家有没有办法把 Google Voice 里的 SMS 信息批量删除,不是归档,谢谢

Posted: 13 May 2021 02:28 AM PDT

想问问大家上云后的后台管理怎么搞

Posted: 13 May 2021 01:02 AM PDT

这种不能直接挂到公网上吧,但是公网访问又有问题

看有的方案是本地搭个后台远程连数据库,然后密码复杂点,问题是有异地需求,这个行不通

我印象中前公司是梯子+nginx 认证,后台域名走的同一个 nginx 入口,然后访问时会验证 没挂梯子或者梯子没登录 http 就直接 403,ssh 也一样

大佬们了解这种方案具体是怎么搞的吗

请教一个 computed 的 set 方法无法触发的问题 ?

Posted: 12 May 2021 11:21 PM PDT

下面的代码是一个最简单的列子,必须要用到 computed,我希望在表单变化的时候能在 set 方法监听到 并做相应的处理。 代码如下

<!doctype html> <html lang="en"> <head>     <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.7/vue.global.prod.js"></script>     <title>Document</title> </head> <body> <div id="app">     <template v-for="v in newList">         <div><input type="text" v-model="v.title"></div>     </template> </div> <script>     Vue.createApp({         data() {             return {                 list: [{title: 'A1'}, {title: 'B1'}, {title: 'C1'}]             }         },         computed: {             newList: {                 get() {                     let r = [];                     this.list.forEach(v => {                         r.push({title: v.title + ' - dd'});                     });                     return r;                 },                 set(v) {                     // 没有执行                     console.log(this.$set);                  }             }         }     }).mount('#app'); </script> </body> </html> 

Nebula Graph 的 Ansible 实践

Posted: 12 May 2021 10:55 PM PDT

本文首发于 Nebula Graph 公众号 NebulaGraphCommunity,Follow & 看大厂图数据库技术实践

Nebula Graph 的 Ansible 实践

背景

在 Nebula-Graph 的日常测试中,我们会经常在服务器上部署 Nebula-Graph 。为了提高效率,我们需要一种工具,能帮我们做到快速部署,主要的需求:

  • 可以使用非 root 账户部署 Nebula Graph,这样我们可以针对这个用户设置 cgroup 做资源限制。
  • 可以在操作机上更改配置文件,然后分发到部署的集群上,方便我们做各种调参的测试。
  • 可以使用脚本调用,方便以后我们继承在测试的平台或工具上。

工具选择上,早期有 Fabric 和 Puppet,比较新的工具有 Ansible 和 SaltStack 。

Ansible 在 GitHub 上有 40K+ star, 而且在 2015 年被 Red Hat 收购,社区比较活跃。很多开源项目都提供了 Ansible 的部署方式,比如 Kubernetes 中的 kubespray和 TiDB 中的 tidb-ansible

综合下来,我们使用 Ansible 来部署 Nebula Graph 。

Ansible 介绍

特点

Ansible 是开源的,自动化部署工具( Ansible Tower 是商业的)。具有以下的几个特点:

  • 默认协议是基于 SSH,相比于 SaltStack 不 需要额外部署 agent 。
  • 使用 playbook, role, module 来定义部署过程,比较灵活。
  • 操作行为幂等。
  • 模块化开发,模块比较丰富。

优缺点比较明显

  • 使用 SSH 协议,优点是大多数机器默认只要有账号密码就可以通过 Ansible 完成部署,而缺点性能上会差一些。
  • 使用 playbook 来定义部署过程,Python 的 Jinja2 作为模板渲染引擎,对于熟悉的人来说会比较方便,而对于没有使用过的人,会增加学习成本。

综上,适用于小批量机器的批量部署,不需要关心额外部署 agent 的场景,和我们的需求比较匹配。

部署逻辑

通常为了离线部署,可以把机器分为 3 种角色。

  • Ansible 执行机:运行 Ansible 的机器,需要能通过 SSH 连到所有机器。
  • 有外网的资源机:运行需要连接外网的任务,比如下载 RPM 包。
  • 服务器:即运行服务的服务器,可以网络隔离,通过执行机来部署

Nebula Graph 的 Ansible 实践

任务逻辑

Ansible 中,主要有三种层次的任务:

  • Module
  • Role
  • Playbook

Module 分为 CoreModule 和 CustomerModule,是 Ansible 任务的基本单元。

在运行任务的时候,首先 Ansible 会根据 module 的代码,将参数代入,生成一个新的 Python 文件,通过 SSH 放到远程的 tmp 文件夹,然后通过 SSH 远程执行 Python 将输出结果返回,最后把远程目录删除。

Nebula Graph 的 Ansible 实践

# 设置不删除 tmp 文件 export ANSIBLE_KEEP_REMOTE_FILES=1  # -vvv 查看 debug 信息 ansible -m ping all -vvv <192.168.8.147> SSH: EXEC ssh -o ControlMaster=auto -o ControlPersist=30m -o ConnectionAttempts=100 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="nebula"' -o ConnectTimeout=10 -o ControlPath=/home/vesoft/.ansible/cp/d94660cf0d -tt 192.168.8.147 '/bin/sh -c '"'"'/usr/bin/python /home/nebula/.ansible/tmp/ansible-tmp-1618982672.9659252-5332-61577192045877/AnsiballZ_ping.py && sleep 0'"'"'' 

可以看到有这样的日志输出,AnsiballZ_ping.py 就是根据 module 生成的 Python 文件,可以登录到那台机器,执行 Python 语句看一下结果。

python3 AnsiballZ_ping.py  #{"ping": "pong", "invocation": {"module_args": {"data": "pong"}}} 

返回了运行 Python 文件的标准输出,然后 Ansible 再对返回的结果做额外处理。

Role 是串联 module 的一系列任务,可以通过 register 来传递上下文参数。

典型例子:

  1. 创建目录
  2. 如果创建目录成功,继续安装,否则退出整个部署工程。

Playbook 是组织部署机器和 role 之间的关联。

通过在 inventory 对不同机器进行分组,对不同分组使用不同的 role 来部署,完成非常灵活的安装部署任务。

当 playbook 定义好之后,不同的环境,只要变更 inventory 中的机器配置,就可以完成一样的部署过程。

模块定制

自定义 filter

Ansible 使用 Jinja2 作为模板渲染引擎,可以用 Jinja2 自带的 filter,比如

# 使用 default filter,默认输出 5  ansible -m debug -a 'msg={{ hello | default(5) }}' all 

有时候,我们会需要自定义的 filter 来操作变量,典型的场景就是 nebula-metad 的 地址 --meta_server_addrs

  • 当只有 1 个 metad 的时候,格式是 metad1:9559
  • 当有 3 个 metad 的时候,格式是 metad1:9559,metad2:9559,metad3:9559

在 ansible playbook 的工程下,新建 filter_plugins 目录,创建一个 map_fomat.py Python 文件,文件内容:

# -*- encoding: utf-8 -*- from jinja2.utils import soft_unicode  def map_format(value, pattern):     """     e.g.       "{{ groups['metad']|map('map_format', '%s:9559')|join(',') }}"     """     return soft_unicode(pattern) % (value)  class FilterModule(object):     """ jinja2 filters """     def filters(self):         return {             'map_format': map_format,         } 

{{ groups['metad']|map('map_format', '%s:9559')|join(',') }} 即为我们想要的值。

自定义 module

自定义 module 需要符合 Ansible 框架的格式,包括获取参数,标准返回,错误返回等。

写好的自定义 module,需要在 ansible.cfg 中配置 ANSIBLE_LIBRARY,让 ansible 能够获取到。

具体参考官网:https://ansible-docs.readthedocs.io/zh/stable-2.0/rst/developing_modules.html

Nebula Graph 的 Ansible 实践

因为 Nebula Graph 本身启动并不复杂,使用 Ansible 来完成 Nebula-Graph 的部署十分简单。

  1. 下载 RPM 包。
  2. 复制 RPM 包到部署机,解压后,放到目的文件夹。
  3. 更新配置文件。
  4. 通过 shell 启动。

使用通用的 role

Nebula Graph 有三个组件,graphd 、metad 、storaged,三个组件的命名和启动使用一样的格式,可以使用通用的 role,graphd 、metad 、storaged 分别引用通用的 role 。

一方面更容易维护,另一方面部署的服务更有细粒度。比如 A B C 机器部署 storaged, 只有 C 机器部署 graphd,那 A B 机器上,就不会有 graphd 的配置文件。

# 通用的 role, 使用变量 install/task/main.yml - name: config {{ module }}.conf   template:     src: "{{ playbook_dir}}/templates/{{ module }}.conf.j2"     dest: "{{ deploy_dir }}/etc/{{ module }}.conf"      # graphd role,将变量传进来 nebula-graphd/task/main.yml - name: install graphd   include_role:     name: install   vars:     module: nebula-graphd 

在 playbook 中,graphd 的机器组来运行 graphd 的 role,如果 A B 不在 graphd 的机器组,就不会将 graphd 的配置文件上传。

这样部署后,就不能使用 Nebula-Graph 的 nebula.service start all 来全部启动,因为有的机器上会没有 nebula-graphd.conf 的配置文件。类似的,可以在 playbook 中,通过参数,来指定不同的机器组,传不同的参数。

# playbook start.yml - hosts: metad   roles:     - op   vars:     - module: metad     - op: start  - hosts: storaged   roles:     - op   vars:     - module: storaged     - op: start  - hosts: graphd   roles:     - op   vars:     - module: graphd     - op: start 

这样会相当于多次 ssh 去执行启动脚本,虽然执行效率没有 start all 更好,但是服务的启停会更为灵活。

Nebula Graph 的 Ansible 实践

使用 vars_prompt 结束 playbook

当只想更新二进制,不想删除数据目录的时候,

可以在 remove 的 playbook 中,添加 vars_prompt 二次确认,如果二次确认了,才会删除数据,否则会退出 playbook 。

# playbook remove.yml - hosts: all   vars_prompt:     - name: confirmed       prompt: "Are you sure you want to remove the Nebula-Graph? Will delete binary only  (yes/no)"     roles:     - remove 

而在 role 里,会校验二次确认的值

# remove/task/main.yml --- - name: Information   debug:     msg: "Must input 'yes', abort the playbook "   when:     - confirmed != 'yes'  - meta: end_play   when:     - confirmed != 'yes 

效果如图,删除时可以二次确认,如果不为 yes,就会取消执行这次的 playbook,这样可以只删除二进制,而不删除 nebula 集群的数据。

Nebula Graph 的 Ansible 实践

交流图数据库技术?加入 Nebula 交流群请先填写下你的 Nebulae 名片,Nebula 小助手会拉你进群~~

推荐阅读

一个脑洞: JVM 是否可以把方法区在某种配置或者情况下放到磁盘上以此来减少内存空间

Posted: 12 May 2021 10:51 PM PDT

1 、操作系统的虚拟内存? 当然操作系统提供了虚拟内存的功能但是这个依赖于操作系统,能不能 JVM 自己来做这个事情。 2 、磁盘 IO 的速度比内存读写慢了很多? 实际上优化一下磁盘 IO 和用 SSD 的吧这两者的差别不会特别大,放在磁盘上就是"时间换空间",如果你的系统对时间不是特别敏感但是内存特别大的话也许可以考虑? 3 、GC 遍历对象的时候如果有对象在磁盘会增加 GC 的时间和性能消耗? 所以目前考虑的是把不参与 GC 的方法区放上去

测试了一下 quickjs 和 v8 作为 ssr 引擎的性能

Posted: 12 May 2021 10:46 PM PDT

之前想着用 rust 做 web 开发, 因此想找个服务端渲染 (ssr) 的方案

看了下 rust 生态里面目前有 4 个比较知名 js 引擎

其中 boa 是纯 rust 实现的一个实验性质的 js 引擎, 这个目前应该还达不到生产标准, 所以没有考虑

mozjs 是 servo 工作组封装的 spidermonkey, 看了一下 api, 几乎没做封装, 比较难用, 而且 crates.io 上发布的版本还是两年前的 这个应该只是为了给 servo 用的, 其他项目想使用比较困难, 因此也不考虑

rusty_v8 是 denoland 工作组封装的 libv8, api 封装的比较好, 支持执行 wasm, 目前用于 deno 运行时, 用于生产环境应该没啥问题

quickjs-rs 是对 quickjs 的封装,api 非常简单

目前能用的就 rusty_v8 和 quickjs-rs, 所以测试了一下他们的性能


测试用的前端框架是 Vue.js 2.6, 就输出一个最简单的 hello world

测试代码见: https://gist.github.com/zengxs/f35fe4f18bb65641c9ef12c937f45be7

测试代码都是 release 模式编译, js 代码也是 production 模式编译

引擎 运行次数 最高内存占用 总耗时 平均耗时
quickjs 1 5.1 MiB ~0.5ms -
quickjs 10000 7.2 MiB - ~0.5ms
v8 1 9.1 MiB ~3.5 ms -
v8 10000 67.1 MiB - ~0.05ms
v8-jitless 1 9.3 MiB ~3 ms -
v8-jitless 10000 66.8 MiB - ~0.13ms

数据库容灾备份技术的创业公司,前景如何?

Posted: 12 May 2021 09:39 PM PDT

不懂就问,面试了一家创业公司,是做数据库容灾备份技术的,大体是在数据库上面再做一层,V 友觉得前景如何。

港/英 硕士值得读嘛

Posted: 12 May 2021 09:27 PM PDT

如果单纯为了早点拿到硕士学历,以后也不太想做科研,有必要放弃国内 985 硕士去申请吗? ps 本科也是 985

GPL 协议开源项目被恶意上架 Mac App Store 查了下商标都被注册了,如何要求 Apple 下架?

Posted: 12 May 2021 09:24 PM PDT

几百个用户的小项目,因为不想交年费一直没上架 Mac App Store,前几天随手搜索了一下发现被一个苏州公司上架了 Mac App Store,还做了中文本地化(我的版本只有英文),目前 0 评分。对方 App Store 名下只有我这一款软件,但注册了多个开源软件商标。看样子是一个空壳公司,找到了对方公司邮箱,发了一份要求下架的邮件,2 天未回复。由于对方注册了商标,出于安全考虑暂时不发应用名。请问如何要求 Apple 下架? GitHub 项目地址和在它注册商标之前的 commit 和 release 记录有用吗?

有谁用过 navigator.share()这个 api?

Posted: 12 May 2021 08:51 PM PDT

Navigator.share https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/share

if (navigator.canShare && navigator.canShare({ files: filesArray })) {   navigator.share({     files: filesArray,     title: 'Pictures',     text: 'Our Pictures.',   })   .then(() => console.log('Share was successful.'))   .catch((error) => console.log('Sharing failed', error)); } else {   console.log(`Your system doesn't support sharing files.`); } 

分享 files 的时候,不支持 iOS 和 Mac?有谁深入使用过这个 API,可以交流一下吗?

寻一款与 docsify 类似,但可以直接在线编辑的工具

Posted: 12 May 2021 07:47 PM PDT

docsify 改还是有点麻烦,要是能在线改就好了

你们的 Google 网页版黑暗模式可以打开了么?

Posted: 12 May 2021 07:07 PM PDT

dark theme

除了开源中国,还有哪些网站有软件更新资讯的版块?

Posted: 12 May 2021 06:54 PM PDT

我经常浏览开源中国,浏览最多的版块就是首页的那个软件更新资讯。从这里点击下去浏览最近更新的软件资讯

那么各位,除了开源中国这个网站有软件更新资讯,其他的网站,或者 It 网站,有没有类似开源中国的软件更新资讯?

每天都能更新开源软件、应用程序、IT 开发组件等的发布与更新资讯。

开源中国,到现在一直限制评论,导致使用体验很差劲

咨询下, MAD Gaze 的开发平台怎么样?作为 AR 开发者的

Posted: 12 May 2021 05:26 PM PDT

3000 预算,只能买得起二手设备了,这代眼镜质量好像不太稳定? 不知道其它 AR 眼镜怎么样,开发平台的手册如何,有没有 ar 开发者可以建议下?

开发目的是 AR 版的语音识别转写字幕,用算法识别手势动作转换英文字母(共 26 个手势),接入拼音输入法使用户选择某些词汇,最后进行文字转语音输出

淘宝看了 MAD Gaze plus 参数配置,以及一些评价,它似乎是预算内的最佳选择?

寻求更好的建议

PS: 顺便求一些比较活跃的 ar 开发者社区,有什么相关的 ar 问题不太好意思发这里 平常也就看看官方提供的 sdk 手册

这里有一个前端加密页面,我在里面放了 1000 元支付宝口令,欢迎大家破解.

Posted: 12 May 2021 02:44 PM PDT

正确访问地址是 https://wssdll.github.io/modern-resume-theme-gh-pages/template/index.html?pwd=???

当你只有正确输入 pwd 后才会显示网页内容

    var password = getQueryString('pwd') || ''     var bytes = CryptoJS.AES.decrypt(res, password);     try {         plaintext = bytes.toString(CryptoJS.enc.Utf8);     } catch (e) {         plaintext = e     }     document.body.innerHTML = plaintext 

pwd 为解密秘钥 加密采用 AES 加密

https://wssdll.github.io/modern-resume-theme-gh-pages/template/assets/main.js

function ajaxPost(url, data, callback) {     var xhr = new XMLHttpRequest()     xhr.open('GET', url, true)      xhr.send()     xhr.onreadystatechange = function () {         if (xhr.readyState === 4) {             if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {                 callback(xhr.response)             } else {                 callback()             }         }     } }  ajaxPost('resume', null, function (res, date) {     // var ciphertext = CryptoJS.AES.encrypt(res, 'password')     // console.log(ciphertext.toString());      var plaintext     var password = getQueryString('pwd') || ''     var bytes = CryptoJS.AES.decrypt(res, password);     try {         plaintext = bytes.toString(CryptoJS.enc.Utf8);     } catch (e) {         plaintext = e     }     document.body.innerHTML = plaintext })  function getQueryString(name) {     var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)')     var r = decodeURI(window.location.search.substr(1)).match(reg)     if (r !== null) {         return decodeURI(r[2])     }     return null } 
  1. 仓库地址 https://github.com/wssdll/modern-resume-theme-gh-pages
  2. 已经关闭 Google 收录,但是不知道其他搜索引擎是否会收录,我可以确保这个解密地址我已经重复访问过多次.
  3. 加密后字符串为 U2FsdGVkX18V2rIYL238dR/OViz1UGWbWMwUvZwXA44=
  4. 这样做的目的是,你可以使用免费的 Github Pages 中就算暴露仓库也无法得知内容.
  5. 前情提要 https://www.v2ex.com/t/776373
  6. 加密流程是通过本地加密页面文件并提交到 GIthub 公开仓库中,使用特定的访问地址访问加密的页面.
  7. 密码并不长,可能暴力破解有效
  8. 你们不会是废物吧?

Golang 实现的与 iOS 设备 进行通信的跨平台工具库

Posted: 12 May 2021 01:48 PM PDT

项目地址

Go Module 版本: https://github.com/electricbubble/gidevice
CLI 版本: https://github.com/electricbubble/gidevice-cli

项目说明

使用 Golang 实现的的与 iOS 设备 进行通信的跨平台工具库

所有功能无需越狱
macOS 可直接使用
Windows 需要先安装 iTunes 或者 usbmuxd
Linux 或其他需先安装 usbmuxd

已实现功能:

  • 设备列表查询
  • 开发者镜像挂载
  • App 启 /停 /卸载 /安装
  • 端口转发
  • 截图
  • XCTest
  • Syslog
  • CrashReport
  • 沙盒文件访问
  • 定位修改 /恢复
  • Pair

部分 CLI 版本使用示例

Devices

$ gidevice list 

DeveloperDiskImage

$ gidevice mount -l # gidevice mount -l -u=39xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx7 $ gidevice mount -d=/path/.../DeviceSupport/14.4/ $ gidevice mount /path/.../DeviceSupport/14.4/DeveloperDiskImage.dmg /path/.../DeviceSupport/14.4/DeveloperDiskImage.dmg.signature 

Forward

# Default port local=8100 remote=8100 $ gidevice forward $ gidevice forward -l=9100 -r=9100 -u=39xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx7 

部分 Go Module 版本使用示例

Devices

package main  import ( 	giDevice "github.com/electricbubble/gidevice" 	"log" )  func main() { 	usbmux, err := giDevice.NewUsbmux() 	if err != nil { 		log.Fatalln(err) 	}  	devices, err := usbmux.Devices() 	if err != nil { 		log.Fatal(err) 	}  	for _, dev := range devices { 		log.Println(dev.Properties().SerialNumber, dev.Properties().ProductID, dev.Properties().DeviceID) 	} }  

DeveloperDiskImage

package main  import ( 	"encoding/base64" 	giDevice "github.com/electricbubble/gidevice" 	"log" )  func main() { 	usbmux, err := giDevice.NewUsbmux() 	if err != nil { 		log.Fatal(err) 	}  	devices, err := usbmux.Devices() 	if err != nil { 		log.Fatal(err) 	}  	if len(devices) == 0 { 		log.Fatal("No Device") 	}  	d := devices[0]  	imageSignatures, err := d.Images() 	if err != nil { 		log.Fatalln(err) 	}  	for i, imgSign := range imageSignatures { 		log.Printf("[%d] %s\n", i+1, base64.StdEncoding.EncodeToString(imgSign)) 	}  	dmgPath := "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/14.4/DeveloperDiskImage.dmg" 	signaturePath := "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/14.4/DeveloperDiskImage.dmg.signature"  	err = d.MountDeveloperDiskImage(dmgPath, signaturePath) 	if err != nil { 		log.Fatalln(err) 	} }  

App

package main  import ( 	giDevice "github.com/electricbubble/gidevice" 	"log" 	"path/filepath" )  func main() { 	usbmux, err := giDevice.NewUsbmux() 	if err != nil { 		log.Fatalln(err) 	}  	devices, err := usbmux.Devices() 	if err != nil { 		log.Fatalln(err) 	}  	if len(devices) == 0 { 		log.Fatalln("No Device") 	}  	d := devices[0]  	bundleID := "com.apple.Preferences" 	pid, err := d.AppLaunch(bundleID) 	if err != nil { 		log.Fatalln(err) 	}  	err = d.AppKill(pid) 	if err != nil { 		log.Fatalln(err) 	}  	runningProcesses, err := d.AppRunningProcesses() 	if err != nil { 		log.Fatalln(err) 	}  	for _, process := range runningProcesses { 		if process.IsApplication { 			log.Printf("%4d\t%-24s\t%-36s\t%s\n", process.Pid, process.Name, filepath.Base(process.RealAppName), process.StartDate) 		} 	} }  

Screenshot

package main  import ( 	giDevice "github.com/electricbubble/gidevice" 	"image" 	"image/jpeg" 	"image/png" 	"log" 	"os" )  func main() { 	usbmux, err := giDevice.NewUsbmux() 	if err != nil { 		log.Fatalln(err) 	}  	devices, err := usbmux.Devices() 	if err != nil { 		log.Fatalln(err) 	}  	if len(devices) == 0 { 		log.Fatalln("No Device") 	}  	d := devices[0]  	raw, err := d.Screenshot() 	if err != nil { 		log.Fatalln(err) 	}  	img, format, err := image.Decode(raw) 	if err != nil { 		log.Fatalln(err) 	} 	userHomeDir, _ := os.UserHomeDir() 	file, err := os.Create(userHomeDir + "/Desktop/s1." + format) 	if err != nil { 		log.Fatalln(err) 	} 	defer func() { _ = file.Close() }() 	switch format { 	case "png": 		err = png.Encode(file, img) 	case "jpeg": 		err = jpeg.Encode(file, img, nil) 	} 	if err != nil { 		log.Fatalln(err) 	} 	log.Println(file.Name()) }  

SimulateLocation

package main  import ( 	giDevice "github.com/electricbubble/gidevice" 	"log" )  func main() { 	usbmux, err := giDevice.NewUsbmux() 	if err != nil { 		log.Fatalln(err) 	}  	devices, err := usbmux.Devices() 	if err != nil { 		log.Fatalln(err) 	}  	if len(devices) == 0 { 		log.Fatalln("No Device") 	}  	d := devices[0]  	// https://api.map.baidu.com/lbsapi/getpoint/index.html 	if err = d.SimulateLocationUpdate(116.024067, 40.362639, giDevice.CoordinateSystemBD09); err != nil { 		log.Fatalln(err) 	}  	// https://developer.amap.com/tools/picker 	// https://lbs.qq.com/tool/getpoint/index.html 	// if err = d.SimulateLocationUpdate(120.116979, 30.252876, giDevice.CoordinateSystemGCJ02); err != nil { 	// 	log.Fatalln(err) 	// }  	// if err = d.SimulateLocationUpdate(121.499763, 31.239580,giDevice.CoordinateSystemWGS84); err != nil { 	// if err = d.SimulateLocationUpdate(121.499763, 31.239580); err != nil { 	// 	log.Fatalln(err) 	// }  	// err = d.SimulateLocationRecover() 	// if err != nil { 	// 	log.Fatalln(err) 	// } }  

[skynet 源码阅读系列] 01_从 main 函数开始

Posted: 12 May 2021 01:40 PM PDT

skynet 是 C 语言写的框架,我们采用学习过程中最基本的方式去阅读 skynet,从 C 语言的 main 函数开始。

首先我们找到框架的入口main函数,在 skynet/skynet-src/skynet_main.c 文件内。

main 函数的代码如下:

int main(int argc, char *argv[]) {     const char * config_file = NULL ;     if (argc > 1) {         config_file = argv[1];     } else {         fprintf(stderr, "Need a config file. Please read skynet wiki : https://github.com/cloudwu/skynet/wiki/Config\n"            "usage: skynet configfilename\n");         return 1;     }      skynet_globalinit();     skynet_env_init();      sigign();      struct skynet_config config;  #ifdef LUA_CACHELIB     // init the lock of code cache     luaL_initcodecache(); 

No comments:

Post a Comment