// filename cjs.js module.exports = 'exported by cjs'
在cjs中使用import:
import
import('./cjs.js').then(console.log)
在esm中使用require:
require
import { createRequire } from 'module' const require = createRequire(import.meta.url) console.log(require('./cjs'))
https://jimmywarting.github.io/you-might-not-need-typescript/
一篇讨伐typescript的雄文😂
里面用到了vscode的编辑器:https://github.com/microsoft/monaco-editor
效果还挺好的:https://jimmywarting.github.io/you-might-not-need-typescript/wrong/ts.html
gitlab 支持指定push不触发pipeline:
Skip a pipeline To push a commit without triggering a pipeline, add [ci skip] or [skip ci], using any capitalization, to your commit message. Alternatively, if you are using Git 2.10 or later, use the ci.skip
git push -o ci.skip
nodejs v18 增加了 fetch 这个全局对象,实现了 https://developer.mozilla.org/en-US/docs/Web/API/fetch 的 API
fetch
在这个 PR 里,还支持了使用代理:
import { ProxyAgent } from 'undici' const proxyAgent = new ProxyAgent('http://127.0.0.1:49655') const res = await fetch('https://ipip.viegg.com', { dispatcher: proxyAgent }) console.log(await res.json())
https://stats.uptimerobot.com/MAkyPU2A40
建了个监控页面来监控 viegg.com 的在线状况
https://docs.docker.com/engine/reference/builder/#add
If is a local tar archive in a recognized compression format (identity, gzip, bzip2 or xz) then it is unpacked as a directory.
example:
FROM scratch ADD alpine-minirootfs-20230208-x86_64.tar.gz / CMD ["/bin/sh"]
https://docs.docker.com/desktop/troubleshoot/known-issues/
Docker Desktop uses the HyperKit hypervisor in macOS 10.10 Yosemite and higher
https://bb.viegg.com/p/773 之前提到过五子棋有多么小众,顶尖选手的微博粉丝才几百个,扫雷也不例外,鞠帝,世界上扫雷最快的人,也才1691个b站粉丝。。
今天跟进了一下扫雷届的最新进展,发现高级记录已经进30秒了(26.59)
各种记录都被同一个人统治了,而且他破纪录的时候才12岁。。离大谱😢
而且他连盲扫(不按右键)都能做到三十秒出头,这尼玛。。
另外还发现了一个牛逼的录像播放器:https://github.com/hgraceb/flop-player
这个也挺有意思:基于概率分析的智能AI扫雷程序秒破雷界世界纪录
心血来潮找了下记忆中的一句台词「爱情就像烟花,四分五裂才最美啊」
原来出自 Clanned 第二季第六集,字幕是
https://www.bilibili.com/bangumi/play/ep21439?t=180
刚发现MDN上的Browser compatibility已经没有IE了。。以前好像是有的?不知道什么时候去掉了😇
Browser compatibility
葛立恒数的最后n位
To connect to the remote Engine API, you might need to provide the location of the Engine API for Docker clients and development tools.
Mac and Windows WSL 2 users can connect to the Docker Engine through a Unix socket: unix:///var/run/docker.sock.
unix:///var/run/docker.sock
If you are working with applications like Apache Maven that expect settings for DOCKER_HOST and DOCKER_CERT_PATH environment variables, specify these to connect to Docker instances through Unix sockets.
DOCKER_HOST
DOCKER_CERT_PATH
For example:
$ export DOCKER_HOST=unix:///var/run/docker.sock
Docker Desktop Windows users can connect to the Docker Engine through a named pipe: npipe:////./pipe/docker_engine, or TCP socket at this URL: tcp://localhost:2375.
npipe:////./pipe/docker_engine
tcp://localhost:2375
For details, see Docker Engine API.
socketPath: '//./pipe/docker_engine'
// For Mac OS X: // socat -d -d unix-l:/tmp/docker.sock,fork tcp:<docker-host>:4243 // DOCKER_SOCKET=/tmp/docker.sock npm test // For Windows: // https://github.com/apocas/dockerode/issues/290#issuecomment-276393388 // socketPath: '//./pipe/docker_engine' var socket = process.env.DOCKER_SOCKET || isWin ? '//./pipe/docker_engine' : '/var/run/docker.sock';
https://docs.docker.com/engine/security/protect-access/
https://alf.nu/ReturnTrue
终于找到这网站了。。
当时好像是卡在这一题:
var rand = Math.random(); function random4(x) { return rand === x; }
要让你填x的值,使得 random4(x) 返回 true
x
random4(x)
true
var o = (function () { var obj = {a: 1, b: 2} return function (k) { return {get: function () { return obj[k] }} } })() Object.defineProperty(Object.prototype, 'my_random_key', { get() { this.a = 233 } }) console.log('before', o('a').get()) // 1 o('my_random_key').get() console.log('after', o('a').get())// 233
先来看一段 JavaScript 代码:
const record = await query(`select * from data order by id desc limit 100`) const flag = Date.now() - 1000 * 60 * 3 // 3 min ago return record.filter(v => (new Date(v.ctime)).getTime() > flag)
其中:
query
id
ctime
`ctime` timestamp NULL DEFAULT CURRENT_TIMESTAMP;
值得一提的是其实 mysql 官方(Oracle)也有个 mysql-connector-nodejs,但是 star 数只有一百多。。就很离谱😅
这段代码的意思是找到 data 表里最近 100 条数据里所有 ctime 在 3 分钟以内的记录,看上去没问题对吧?
但实际上如果运行环境的系统时区和 mysql 的时区设置不一样的话,就有大问题了。这里面涉及的东西有点多,而且比较绕,先来补充点背景知识。
根据 mysql 官方文档 https://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html,存储 TIMESTAMP 类型的数据需要占用 4 bytes(以及可能的fractional seconds storage),无语的是文档里竟然没说是 4 字节的整数还是什么。。
fractional seconds storage
不过 https://stackoverflow.com/a/1563551/3469145 有提到是 4 字节的整数,但是它里面的官方文档链接已经过期了,点进去会自动跳转到最新的8.0版文档。。
于是继续顺藤摸瓜,在这里 https://dev.mysql.com/doc/refman/5.7/en/datetime.html 找到了另一句话:
The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.
结合一下 4 字节整数的表示范围 (-2147483648) to (2147483647) 也就是
(-2147483648) to (2147483647)
// 4 bytes = 32 bits, 再去掉一个符号位,就是31 console.log(2 ** 31) // 2147483648 console.log(new Date(1000 * (2147483648 - 1))) // Tue Jan 19 2038 11:14:07 GMT+0800 (中国标准时间)
所以我们可以得出结论了:MySQL 内部存储 TIMESTAMP 类型的数据用的是 4 字节整数,其数值等于从 UTC 时间 1970 年 1 月 1 日 0 点距今过去的秒数(一般称这个数值为时间戳,也就是 timestamp)。
timestamp
那么问题来了,既然存的是秒数,那么时区什么的应该不影响啊,不管你在哪个时区,TIMESTAMP 表示的都是一个绝对时间,也就是说,你在不同时区的同一时刻,把 CURRENT_TIMESTAMP 存入 MySQL 数据库中,其内部存储的 4 字节整数理论上都是一致的。
CURRENT_TIMESTAMP
那么时区到底是怎么发挥作用的呢?
在 MySQL 中,我们可以这样查看当前时区设置:
show variables like "%time_zone%";
也可以这样进行修改:
set time_zone = '+8:00'; set global time_zone = '+8:00'; flush privileges;
那么它是怎样影响 TIMESTAMP 类型的数据的呢?
根据官方文档 https://dev.mysql.com/doc/refman/5.7/en/datetime.html:
MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval.
也就是说,MySQL 在存储 TIMESTAMP 类型的数据时,会根据时区设置把它转成 4 位整数,而运行 select 语句时,会反过来根据存储的秒数和当前时区来算出表示时间的字符。
select
那么 MySQL 是怎么表示 TIMESTAMP 类型的呢?根据 https://dev.mysql.com/doc/refman/5.7/en/datetime.html:
A DATETIME or TIMESTAMP value can include a trailing fractional seconds part in up to microseconds (6 digits) precision. In particular, any fractional part in a value inserted into a DATETIME or TIMESTAMP column is stored rather than discarded. With the fractional part included, the format for these values is 'YYYY-MM-DD hh:mm:ss[.fraction]'
YYYY-MM-DD hh:mm:ss 也就是我们最常见的时间表示方法了,比如当前时间是:
YYYY-MM-DD hh:mm:ss
dayjs().format('YYYY-MM-DD HH:mm:ss') // '2023-01-04 15:51:57'
这样表示时间的好处是非常直观,人类友好,坏处是它不是一个绝对时间,因为它丢失了时区信息,程序一般会根据运行环境所在时区来算出时间戳。
mysqljs/mysql 让这个问题藏得更深了一点,它对于 select 出来的原始数据,会再进行一次包装:
var dt = new Date(dateString); if (isNaN(dt.getTime())) { return originalString; } return dt;
这里面的 dateString,就是丢失了时区信息的 YYYY-MM-DD hh:mm:ss,JavaScript 运行 new Date(dateString) 的时候,就会根据当前系统的时区,来算出时间戳。
dateString
new Date(dateString)
所以如果系统的时区和 MySQL 时区设置不一样,就会出问题了。我遇到的就是这种情况,我的系统时区是Asia/Shanghai,也就是 UTC+8,而 MySQL 是 UTC 时间。
Asia/Shanghai
举例来讲,如果某条数据的 ctime 为 2022-01-01 16:00:00(北京时间),那么它内部存储的时间戳就是 1641024000
2022-01-01 16:00:00
1641024000
new Date('Sat Jan 01 2022 16:00:00 GMT+0800 (中国标准时间)') / 1000 // 1641024000
而 select 出来的则是 2022-01-01 08:00:00(MySQL 用的是 UTC 时间,比北京时间少8个小时)
2022-01-01 08:00:00
那么再运行到 new Date('2022-01-01 08:00:00') 时,JS 引擎用的是系统时区,也就是北京时间,就这么一来一去,ctime 平生生减去了 8 个小时。
new Date('2022-01-01 08:00:00')
顺便一提,如果数据库连接的配置中设置了 dateStrings: true,那么它就不会把 TIMESTAMP 包装成 Date 对象了,而是直接返回 dateString。
dateStrings: true
Date
github 可以对比任意两次commit的变化: 假设老commit id是 aaa ,新commit id 是 bbb
aaa
bbb
那么直接构造网址 https://github.com/your/repo/compare/aaa...bbb
https://github.com/your/repo/compare/aaa...bbb