国内的新冠肺炎(COVID-19)疫情得到控制后,经常光顾的咖啡店不提供单品咖啡(手冲或虹吸)了。老板让我自己冲煮,并建议使用爱乐压。就这样,硬是开启了手冲咖啡之旅。参考了网上的经验分享,整理了这个“贴地”(廉价)手冲入门套装。

参考文章:
1)最便宜的手冲咖啡设备入门【银河系喝咖啡指南】小白入门必看
https://zhuanlan.zhihu.com/p/104174674

2)【一分钱攻略】手冲咖啡入门指北,在家也能喝出咖啡bar的格调
https://www.ecentime.com/article/comment-preparer-pull-over-coffee-chez-soi

装备清单:
1)手摇磨豆机:泰摩 栗子C。
当前价格:150rmb~250rmb。优点是便宜、钢芯、出粉还算OK。缺点是相对较重、摇杆与盖子一体、接粉杯与机身不好拧上。在价格面前,这些缺点都可以接受了。另外国产有几品牌的手磨都是比较适合入门:匿名、汉匠等。

2)滤杯:树脂V60 01。
某宝或拼夕夕入手一个树脂材质V60 01,即一到两人份量版。价格15rmb~20rmb。正如人家说,反正是照抄别人的模具,入门就图个便宜。优点是预热和保温的效果都比较好、大师级比赛也会用这个。缺点是相对比较占地方。旅行的话,可以考虑弹簧版,日本那边比较流行。但是弹簧的没什么保温了,出品确实会差点。

3)滤纸:随便买的。
要对应滤杯版本,即V60 01。40片,10rmb。要看看评价,尽量选没有异味的。

4)分享壶:用杯子代替。
一般只有自己喝的话,可以不考虑这个。家里有个容量220ml左右的迷你保护壶(不锈钢材质),刚好够我一次的份量。也可以冲好咖啡,拿到公司再喝。这个保温壶售价50rmb左右,我的是礼品,算是免费了。另外,后来有时会跟同事分享,也要做冷泡咖啡,就入手了个带盖子、有刻度的玻璃水杯,容量350ml,10rmb~20rmb。

5)细口壶、手冲壶:找便宜的买。
网上很多,容量250ml,304不锈钢材质,15rmb~25rmb。最好选带盖子的,更好控制水流。有大师建议买那种直接烧水的手冲壶。因为烧好的热水再倒进手冲壶,会降低水温和浪费时间。这里追求便宜的,就不考虑了。

6)电子秤:普通厨房电子秤。
做烘培时,入手了个称材料用的电子秤,精确到g,25rmb。入门级的,也不追求什么。除了用来称咖啡豆,也可以用来控制注入的水量。当然,预算充足的话,建议买专用的咖啡秤,精确到0.1g,且自带计时功能。

7)温度计:探针型温度计。
买了明高et598,25rmb,凑合用的。优点:便宜。缺点:插进细口壶时不能固定,要手拿着。一般手冲的水温是90°C左右。

8)水:过滤后的自来水。
家里有碧然德滤水壶,可以过滤自来水。热水是用普通家用烧水壶烧开的。反正没有用桶装水之类。一般水不要太硬就行。另外,滤水壶,即使在平常生活,也推荐。过滤后的水,水垢明显减少。

9)咖啡豆:网上或咖啡店购买。
最最最重要的,当然是咖啡豆!刚好公司附近有家咖啡店自己烘培豆子。新鲜烘培出来的豆子香气非常强烈,是手冲的动力来源。某宝有店铺也出售新鲜烘培的咖啡豆,说是下单后才炒豆的,也可以。

总结:
最后,说下成本。以前上馆子喝一壶手冲咖啡(240~300ml),一般是30rmb。自己手冲的话,成本主要在咖啡豆。目前一次13g 豆,冲出208ml左右的咖啡,一般豆子成本是3rmb~7rmb,巨便宜!上面那些一次性投入的装备(除了滤纸,不过滤纸也不贵),在多次手冲后,其实都不算什么了。

孩子在国庆长假报了魔方培训班(练字班送的课程)。为了辅导孩子,到B站自学了魔方的入门教程。这个教程不是最快的,也没有说明原理,但是比较容易操作和记忆。整理下来,方便以后再用吧。

教程视频:

【三阶魔方】记忆量最少、方法最简单的入门教程
https://www.bilibili.com/video/BV15i4y187qU?p=1

魔方示意图:

左面左边中间右边右面
3LT3MT3RT 上面(黄色面)
3LL3L3M3R3RR正面,第3层
2LL2L2M2R2RR正面,第2层
1LL1L1M1R1RR正面,第1层
1LB1MB1RB 底面(白色面)

基本定位:

第2层中间黄色,朝上。同时,第2层中间白色,朝底。

基本操作:

  1. 推:右手把正面3个层的右边往上面推,或者左手把正面3个层的左边往上面推。
  2. 回:右手把正面3个层的右边往底面推,或者左手把正面3个层的左边往底面推。
  3. 拨:右手把正面第3层往左面拨,或者左手把正面第3层往右面拨。
  4. 扭:右手把正面整个面往左面扭,或者左手把正面整个面往右面扭。

操作步骤:

1)基础操作:
1.1)黄色面造白色兰花。把黄色面3M、2L、2R、1M,都弄成白色,且不用考虑是否对齐。
1.2)转成白色面十字架。黄色面朝上,随便找一面为正面,拨动第3层,使3M与2M同色,左手或右手“扭”两次。

2)还原第1层(包括底层,白色面)
2.1)此时所有正面的2M与1M同色。
2.2)若3RR白色,拨动第3层成3R与2M同色,然后右手“推拨回”。3L的同理。
2.3)若3RT白色,拨动第3层成3R与2M同色,然后右手“推拨拨回”,再重复2.3。3L的同理。

3)还原第2层
3.1)此时所有正面的2M与第1层同色。
3.2)拨动第3层,找3M、2M、第1层同色(呈倒T)且3M的上面不是黄色。若3M要到2R去,右手“拨推拨回”。若3M要到2L去,左手“拨推拨回”。再按2.2操作。

4)还原上面(只是黄色面)
4.1)此时所有正面的第2层与第1层同色。以下操作需注意方向,但不用考虑正面第3层的颜色。
4.2)上面(黄色面)出现以下黄色组合时,操作:左扭,右推拨回,左拨,右扭。直到出现4.3的图案,再按4.3操作。

  • 反L:3M,2L,2M
  • 一横:2L,2M,2R

4.3)上面(黄色面)出现以下黄色组合时,注意方向但不用考虑正面第3层的颜色,右手“推拨回拨推拨拨回”。不断重复此步骤,直到上面全为黄色。

  • 十字:3M,2L,2M,2R,1M
  • 金鱼:3M,2L,2M,2R,1L,1M
  • 坦克:3M,3R,2L,2M,2R,1M,1R
  • 蝴蝶:3M,3R,2L,2M,2R,1L,1M

5)还原第3层
5.1)拨动第3层,找到一个正面只有3M不同色的,放在左面,执行操作:右推拨回,左拨,右回,左扭,右推推,左拨,右回,左拨,右推拨回,右扭。
5.2)此时有一面完整的,作为背面。左手“推拨回拨推拨拨回”,再执行4.3,完成。

以前一直不知道,原来茶是可以冷泡的。做法简单,非常适合夏天饮用。网上整理的资料如下:

茶叶与水的比例:
茶叶:水 = 1g:100ml

茶叶品种与冲泡时间:
白茶/绿茶,4 ~ 6 小时
乌龙茶,8 ~ 10 小时
红茶,20 ~ 24 小时
发酵程度高的茶,20 ~ 24 小时

冲泡方法:
选不要比较浓的茶,用凉白开、矿泉水、直饮水等,按比例放好后放到冰箱冷藏。到达泡茶时间后,过滤茶叶,再放到冰箱,可以冷藏一到三天。

另外,有些茶叶的外包装会详细说明该茶叶的冷泡方法,可以参考。

最近一直在做冷泡茉莉绿茶,加上蜂蜜,就是茉莉蜜茶了。虽然相比某品牌的茉莉茶饮料,会有明显的茶涩味,但是无添加,更健康。

关于如何把手机改装成无电池运行,已经研究好久了。当时的想法是,无电池运行的手机,可以长期使用外部供电而不怕内部电池损坏,从而实现很多的玩法。例如迷你服务器、录像监控等。但是实现后,发现还是那个经验教训:做得到不一定能做好,专业的事情还是交给专业的设备。Anyway,还是记录一下实现的过程。

首先,以下操作具有一定的危险性!锂电池包装破损的话,一接触到空气就会着火。

总的来说,实现方法有两个,但原理都是一样。具体可以参考这两个文章:

1)手机改装无电池工作(法拉电容替代电池)[教程]
https://luoji.men/2020/12/%e6%89%8b%e6%9c%ba%e6%94%b9%e8%a3%85%e6%97%a0%e7%94%b5%e6%b1%a0%e5%b7%a5%e4%bd%9c%e6%b3%95%e6%8b%89%e7%94%b5%e5%ae%b9%e6%9b%bf%e4%bb%a3%e7%94%b5%e6%b1%a0%e6%95%99%e7%a8%8b/

2)手机改装无电池工作(5V适配器替代电池)[教程]
https://luoji.men/2020/11/%e6%89%8b%e6%9c%ba%e6%94%b9%e8%a3%85%e6%97%a0%e7%94%b5%e6%b1%a0%e5%b7%a5%e4%bd%9c/

原理都是把手机电池(不管是可拆卸的或不可拆卸的),分解为电池保护板和锂电池两部分,然后用外部电源代替锂电池。注意接线的正负极不要接反。

方案一:用超级电容代替锂电池,手机充电口再接5V 2A以上的充电器。

所需电容: 法拉电容组合型5.5V 1.0F(可给手机亮屏续航4秒)
https://item.taobao.com/item.htm?id=622910347656

优点:电容可以在手机断电时,保持一定的亮屏时间。

缺点:每次开机前,手机要接上充电器,先给电容充电(起码30秒)。另外,手机充电口接上充电器,就不能接外部设备了(但是有的手机可以接扩展接头)。

方案二:用5V 2A以上的充电器代替锂电池。

优点:开机快,接电就能开机。而且手机充电口空出来,可以接其它设备。

缺点:充电器一定要接稳,线一松就会断电,手机关机。

最后,对于目前的手机,最好还是使用5V 3A以上的充电器充电,否则会导致不能开机,或者死机。

这个周末,把N年前买的,都是基于ESP8266的小板子(ESP-01和基于ESP-12E的NodeMCU)拿出来玩了下,发现还有可玩性。主要是刷上MicroPython,就带来更多玩法。以前写过相关的Blog文,现在看着,觉得没用,于是重写一篇。

1. ESP8266硬件

可以简单理解为支持2.4GHz WiFi的廉价、低功耗芯片。详细的特点,参考官方文档:
https://www.esp8266.com/wiki/doku.php?id=feature_set

官方Wiki,基本想了解的都可以在这里找到:
https://www.esp8266.com/wiki/doku.php?id=start

ESP8266的硬件家族介绍:
https://www.esp8266.com/wiki/doku.php?id=esp8266-module-family

有人做了个对比:
ESP8266 module comparison: ESP-01, ESP-05, ESP-12, ESP-201, Test Board and NodeMCU
https://blog.squix.org/2015/03/esp8266-module-comparison-esp-01-esp-05.html

简单来说,一般入门的,推荐购买NodeMCU或者D1 Mini这种带USB转TTL芯片的,接上电脑就可以开发了。像ESP-01这种简单且廉价的,最好作为硬件项目的模块来用,普通玩家不要像我这样贪便宜去购买。因为开发时,ESP-01需要USB转TTL来连电脑,实际使用时也需要3.3V的电源来启动。

NodeMCU开发板官网:
https://www.nodemcu.com/index_cn.html

D1 mini官方文档:
https://www.wemos.cc/en/latest/d1/d1_mini.html

2. 选择固件(Firmware)

还是先看官方WiKi的介绍:
Loading new firmware onto an ESP8266
https://www.esp8266.com/wiki/doku.php?id=loading_firmware

能玩的固件,有3个:

1)AT命令固件(AT-Command firmware),适合ESP-01这种作为模块嵌入到硬件项目。其它硬件使用AT命令操控ESP8266来使用WiFi联网。

2)NodeMCU固件,基于Lua语言的,NodeMCU官方网站有简单介绍。另外,其固件需要从定制网站选择模块,build完后,会发Email并提供下载。

NodeMCU固件定制网站
https://nodemcu-build.com/

3)MicroPython,基于Python3语法作为开发语言的固件。一般需要2MB以上空间,NodeMCU板基于ESP-12E,内部空间(flash)是4MB,可以刷最新版本。ESP-01内部空间只有1MB,能刷v1.12或以下的版本,或者刷定制针对1MB的定制版。但是ESP-01运行MicroPython不稳定,网上有说是硬件的问题。所以ESP-01最好不要刷MicroPython。

MicroPython官网:
https://micropython.org/

MicroPython源码:
https://github.com/micropython/micropython

MicroPython针对ESP8266的资料,包括刷机和开发文档:
MicroPython - Quick reference for the ESP8266
https://docs.micropython.org/en/latest/esp8266/quickref.html

MicroPython针对ESP8266的固件下载:
MicroPython Firmware for Generic ESP8266 module
https://micropython.org/download/esp8266/

3. 刷入固件

不管刷什么固件,都是一样的操作。先下载固件文件,再安装刷机工具。刷固件前,先擦除所有数据,再刷固件。网上有很多教程,包括不同操作系统,图形化工具或者命令行操作。下面以Ubuntu为例,默认连接在/dev/ttyUSB0,使用esptool.py作为工具操作。

sudo apt update
sudo apt install python3-pip
sudo pip3 install esptool #安装esptool.py
sudo esptool.py --port /dev/ttyUSB0 erase_flash #擦除所有数据
sudo esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 firmware_file_name.bin #刷入固件

4. 调试系统

命令行调试的话,Windows上可以用PuTTY(需要装对应TTY驱动),Linux(例如Ubuntu)上可以用minicom或者screen命令连上去。

screen命令的格式是screen -S 名称 /dev/接口名称 波特率,其中名称是方便暂时断开后再进入,即如下:

sudo screen -S esp /dev/ttyUSB0 115200

minicom命令,可以设置参数,直接连上,如下:

sudo minicom -D /dev/ttyUSB0 -b 115200

也可以不设参数,直接使用sudo minicom,进去后设置。具体操作是
-> 按[Ctrl] + [A]
-> 按[Z]
-> 按[O],即选择“cOnfigure Minicom..O”
-> 选“Serial port setup”
-> 弹出菜单按如下设置:

+-----------------------------------------------------------------------+
| A -    Serial Device      : /dev/ttyUSB0                              |
| B - Lockfile Location     : /var/lock                                 |
| C -   Callin Program      :                                           |
| D -  Callout Program      :                                           |
| E -    Bps/Par/Bits       : 115200 8N1                                |
| F - Hardware Flow Control : No                                        |
| G - Software Flow Control : No                                        |
|                                                                       |
|    Change which setting?                                              |
+-----------------------------------------------------------------------+

-> 选“Save setup as dfl”,回车
-> 选“Exit”,回车
然后就进入控制台了。

5. 开发工具

一般推荐ESPlorer,基于Java的开源图形化开发工具。该工具比较全面,三个固件都支持,可以用来做调试,也可以做开发,上传文件。本来想写下一些基本测试代码,比如连上WiFi之类,但是该工具都提供了对应的按钮,啥都不用写了。

ESPlorer官网:
https://esp8266.ru/esplorer/

ESPlorer源码:
https://github.com/4refr0nt/ESPlorer

XDA论坛上看了很久,Android 11就只有crDroid有官方支持。加上Resurrection Remix OS用得真不爽,主要是自动杀进程,而且不分前后台。于是五一假期狠下心刷上crDroid,用了一段时间,很爽!流畅、不杀进程、支持国产支付app的指纹,续航还行。

1. 相关下载

1.1. crDroid ROM

当前版本是7.5。注:目前此ROM版本处于无人维护状态!
官网不仅可以下载ROM,还提供小米官方固件(欧版MIUI)、Recovery、OpenGapps等的链接:
https://crdroid.net/picasso/7

1.2. 欧版MIUI

目前最新版是12.1.8,据说今年6月会推出12.5适配。当然,这不是重点。下载地址:
xiaomi.eu_multi_HMK305G_V12.1.8.0.RGICNXM_v12-11.zip
https://sourceforge.net/projects/xiaomi-eu-multilang-miui-roms/files/xiaomi.eu/MIUI-STABLE-RELEASES/MIUIv12/

1.3. Recovery

crDroid推荐的Recovery是OrangeFox。界面跟Twrp非常不同,感觉更像是文件管理器,但功能还是一样。
OrangeFox-picasso-stable@R11.1_1.7.zip
https://orangefox.download/zh-CN/device/picasso

1.4. Margisk

目前几乎是获取root权限的唯一方案。下载地址:
https://github.com/topjohnwu/Magisk/releases

要注意,从Margisk 22开始,root安装包和root管理工具,都合并为一个apk文件。root系统时,只需用Recovery刷入该apk文件。

1.5. Gapps

由于OpenGapps的Android 11版还没正式发布(当前处于测试),所以我选用NikGApps。下载链接:
https://nikgapps.com/downloads.html#downloads

一般选在Core版就可以了。值得注意的是,如果要开启Google Assistant(Google助手),需要把Google Velvet(即Google搜索)安装为系统App。NikGApps提供了对应的Addons(文件名为:NikGapps-Addon-11-Velvet-signed.zip),可以通过Recovery直接刷入系统。

2. 刷机过程

2.1. 解锁及刷Recovery

都是常识性操作。刷Recovery后,最好先备份当前系统。

2.2. 备份数据

钛备份不再更新了,推荐使用OAndBackupX备份App及数据。可通过F-Droid安装:
https://f-droid.org/en/packages/com.machiav3lli.backup/

还有联系人和短信的备份,不再赘述。

2.3. 刷机步骤

按刷机顺序排列,crDroid的方案是:OrangeFox -> 欧版MIUI -> crDroid -> Margisk -> OpenGapps。我的方案只是用NikGApps替换OpenGapps。另外,最好先“双清”再开刷。

3. 初始设置

3.1. 去掉WiFi和信号出现“x”符号

需要使用adb执行以下命令:

adb shell settings put global captive_portal_mode 0
adb shell settings put global captive_portal_https_url https://www.google.cn/generate_204

命令执行成功后,手机开启飞行模式,然后关闭飞行模式,即可解决。
参考:https://www.uso.cn/post/view/47990

3.2. 开启Google Assistant(可选)

初次进入系统后,不插入SIM卡,语言选English(US)。安装Google Assistant并设置开启。成功后,再插入SIM卡,并设语言为中文。


更新 2023-06-22

1. 针对此机的crDroid 9(Android 13)终于有人维护。

详见:https://crdroid.net/picasso/9

刷机时注意:

  • 需要“双清”数据后全新刷入。
  • 需要更新对应的Firmware和Recovery。

2. GMS耗电的问题。

原因:可能是Android的安全补丁一直没更新,Google Play服务会不断尝试后台下载更新,但非Pixel手机会下载失败。

3. ROOT方案。

旧的ROOT方案是使用Magisk。隐藏ROOT是开启Zygisk,再安装Shamiko模块(Shamiko发布地址)。缺点是容易被应用检测到,导致不能适应,例如国内的各大银行app。

新的ROOT方案是使用KernelSU。内核集成ROOT功能,只需安装KernelSU管理应用即可使用(KernelSU发布地址)。缺点是需要内核支持,可玩模块也没那么多。优点是隐蔽性强,几乎不被检测到。

4. system_server高占用CPU。

在crdroid 9.10到9.12都出现,直接导致手机电量消耗过快,而且偶然出现。目前只能通过重启系统解决。

5. 卡屏。

一般是切换应用时“卡屏”,就是屏幕画面不变,且不接收任何输入。一般等几秒就恢复。“阿里系”的应用,例如“支付宝”、“淘宝”,切换时最容易出现。

Eclipse虽老,但仍然好用,特别是对于老Java码农来说。

1. 版本选择

一般Java的Web开发,选择Eclipse IDE for Enterprise Java and Web Developers。官方下载链接如下:
https://www.eclipse.org/downloads/packages/

2. 实用的初始化设置

1)修改默认字符集为UTF-8

windows -> Preferences -> General -> Workspace -> Text file encoding -> 选UTF-8

2)修改默认字体,改善中文显示太小

windows -> Preferences -> General -> Appearance -> Colors and Fonts -> Basic -> Text Font -> Edit -> 选Courier New

3)代码自动提示功能失效的解决方法

Window -> Preferences -> Java -> Editor -> Content Assist -> Advanced -> Select the proposal kinds contained in the 'default' content assist list -> 勾选"Java Non-Type Proposals"、"Java Proposals"、"Java Type Proposals"三个选项

4)在输错方法后仍然出现代码自动提示

Window -> Preferences -> Java -> Editor -> Content Assist -> Auto Activation triggers for java -> 改为.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

5)禁用Language Servers,提高Eclipse性能

Window -> Preferences -> Language Servers -> 取消所有勾选

6)安装插件Quick Bookmarks plugin,快速的标记和访问书签

  • 安装:Help -> Eclipse Marketplace -> 搜“Quick Bookmarks plugin”并安装
  • 使用:Alt+[数字],标记书签。Alt+Shift+[数字],跳转到书签。

工作上遇到需要在浏览器展示PDF文件,于是找到了Mozilla开发的PDF.js。玩了一下,结论是,直接使用其自带的示例是简单的方法。

PDF.js的官网:https://mozilla.github.io/pdf.js/
github项目页面:https://github.com/mozilla/pdf.js

主要是没找到有用的开发文档,而自己也不会Node.js的开发。所以尝试自己写的页面,只能利用HTML 5的canvas展示PDF内容。官方自带的示例,会把PDF转换成HTML,并且有显示目录、缩略图、打印、等各种实用的功能,媲美很多完整的PDF阅读软件。

这里记下写过的页面,可以翻页、放大缩小:

<h4>显示PDF</h4>
<p>
    <button id="prePage">上一页</button> <input type="text" id="curPage" value="" readonly /> <button id="nextPage">下一页</button>
    <br />
    <button id="zoomIn">+</button> <input type="text" id="zoomScale" value="1" readonly /> <button id="zoomOut">-</button>
</p>
<p>
    <canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
</p>

<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="/js/pdfjs/pdf.js"></script>
<script>
//加载PDF按钮
pdfjsLib.GlobalWorkerOptions.workerSrc = '/js/pdfjs/pdf.worker.js';//自己的路径

var loadingTask = pdfjsLib.getDocument('/pdfjs/docker.pdf'); 
var pdfDoc = null;
var totalpage = 0;
var curPage = $("#curPage");
var zoomScale = $("#zoomScale");

loadingTask.promise.then(function (pdf) {
    //加载指定界面(第一页)
    pdfDoc = pdf;
    totalpage = pdfDoc.numPages;
    getPage(1);
});

function getPage(pageNum) {
    if(pageNum < 1) {
        pageNum = 1;
    } else if(pageNum > totalpage) {
        pageNum = totalpage;
    }
    setCurPageNum(pageNum);
    pdfDoc.getPage(pageNum).then(function (page) {
        //var scale = 1;
        var viewport = page.getViewport({ scale: getZoomScale() });
        var canvas = document.getElementById('the-canvas');
        var context = canvas.getContext('2d');
        canvas.height = viewport.height;
        canvas.width = viewport.width;
        var renderContext = {
            canvasContext: context,
            viewport: viewport,
        };
        page.render(renderContext);
    });
}

function makeThumb(page) {
    // draw page to fit into 96x96 canvas
    var vp = page.getViewport(1);
    var canvas = document.createElement("canvas");
    canvas.width = canvas.height = 96;
    var scale = Math.min(canvas.width / vp.width, canvas.height / vp.height);
    return page.render({canvasContext: canvas.getContext("2d"), viewport: page.getViewport(scale)}).promise.then(function () {
        return canvas;
    });
}

function loadThumb() {
    var pages = []; while (pages.length < pdfDoc.numPages) pages.push(pages.length + 1);
    return Promise.all(pages.map(function (num) {
        // create a div for each page and build a small canvas for it
        var div = document.createElement("div");
        document.body.appendChild(div);
        return pdfDoc.getPage(num).then(makeThumb).then(function (canvas) {
            div.appendChild(canvas);
        });
    }));
}

function getCurPageNum() {
    return parseInt(curPage.val());
}
function setCurPageNum(pageNum) {
    return curPage.val(pageNum);
}
function getZoomScale() {
    return parseFloat(zoomScale.val());
}
function setZoomScale(scale) {
    return zoomScale.val(scale);
}
$("#prePage").click(function(){
    var pageNum = getCurPageNum() - 1;
    getPage(pageNum);
})
$("#nextPage").click(function(){
    var pageNum = getCurPageNum() + 1;
    getPage(pageNum);
})
$("#zoomIn").click(function(){
    var scale = getZoomScale();
    scale = Math.round((scale + 0.2) * 100) / 100;
    scale > 2 && (scale = 2);
    setZoomScale(scale);
    getPage(getCurPageNum());
})
$("#zoomOut").click(function(){
    var scale = getZoomScale();
    scale = Math.round((scale - 0.2) * 100) / 100;
    scale < 0.6 && (scale = 0.6);
    setZoomScale(scale);
    getPage(getCurPageNum());
})
</script>

最近接触了两款开源、跨平台、支持多种SQL数据库的数据库管理工具,值得记录一下。

DBeaver
官网:https://dbeaver.io/
2020年疫情期间,在家办公,想找个数据库管理工具,可以在Linux上访问SQL Server数据库,于是遇到DBeaver。界面像Eclipse,容易上手;基于Java,可以跨平台使用;使用JDBC,几乎支持所有数据库。在Linux上,几乎是万能的数据库管理工具了。

HeidiSQL
官网:https://www.heidisql.com/
在Windows上安装MariaDB 10.4.12时,发现自带了HeidiSQL数据库管理工具。界面及操作都跟MySQL Workbench相似,清晰明了,而且支持各种SQL数据。比较意外的是,其基于Delphi开发,所以Linux上需要利用Wine运行。

顺德双皮奶,作为代表家乡的特色甜品小吃,一直深受本人喜爱,只是会吃不会做。近来几乎每天都买水牛奶给孩子补充营养,于是尝试做一下,原来也很简单。主要是以前错误以为第一层奶皮需要技巧弄上去,实际是物理原理,脂肪会浮在水面上。所以,只要弄到水牛奶,再简单弄一下就能吃到双皮奶了。

材料(两碗份量):

  • 水牛奶:250g
  • 蛋清:50g(大概一只鸡蛋的蛋清)
  • 糖:12g(可根据口味增减)

做法:

  • 1,水牛奶煮开,平均倒入两个碗内。放凉,让第一层奶皮形成。
  • 2,轻轻拨开奶皮,倒出牛奶,并让奶皮留在碗里。
  • 3,鸡蛋分离出蛋清和蛋黄。倒出的牛奶,加入蛋清和糖,搅拌均匀至混合。
  • 4,牛奶和蛋清混合物,用筛网过滤一下(去除杂质,让口感更滑),再平均倒回两个碗里。
  • 5,碗上盖上小碟子(或者保鲜膜、锡纸之类,还是小碟子比较环保)。待蒸锅水沸后,放上去蒸7到10分钟(我是8分钟)。
  • 6,蒸好后,放凉到接近体温再食用。夏天可以放冰箱冷藏后食用。