如何获得一盘酥脆多汁的炸鸡

前言

因为疫情,现在已经被困在家里接近一个月了,虽然家里老妈每天都能做出不重样的食物,但是果然还是想吃肥宅快乐鸡,没有炸鸡的陪伴就不是一个完整的死宅,于是我跟老妈提出了申请,把家里面的一袋子鸡翅拿出来,准备生成一盘炸鸡翅。

效果演示

原材料

  • 鸡翅「翅中,翅根,琵琶腿等均可」
  • 面粉
  • 淀粉
  • 姜「用姜粉效果更好」
  • 蒜「用蒜粉效果更好」
  • 料酒
  • 胡椒粉
  • 辣椒粉

上面这些东西都有了的话,就可以开始操作了。当然具体需要放多少我也没量,而且也没必要说,喜欢吃就多放就成。

制作过程

  • 先让冷冻鸡翅自然解冻,解冻后用清水冲洗,洗掉冰水,血水,和杂质
  • 找一把刀,在鸡翅身上划两下,方便入味
  • 葱姜蒜切末「如果使用调味粉则可以跳过」
  • 找一个盘子,把鸡翅放进去,分别放入盐,胡椒粉,辣椒粉,葱末,姜末,蒜末,最后加上料酒和少量的水
  • 揉搓鸡翅,让鸡翅上均匀的沾满各种调料后,腌制3-6小时「至少3小时,否则很难入味」
  • 找个容器,里面放入少量淀粉和少量面粉,淀粉和面粉的比例约为1:5,之后在加入少许的盐,胡椒粉,喜欢辣可以再加辣椒粉,将他们均匀混合
  • 再找一个容器,放进去少许混合粉,同时加入少量的水,将混合粉打成糊状
  • 将腌制好的鸡翅取出,先在混合粉内均匀裹粉,裹好后轻轻敲打,抖掉多余的粉,然后将鸡翅放入另一个容器内的糊中,裹上一层糊后,再次放回混合粉内,均匀裹粉,之后抖掉多余的粉
  • 烧一锅油,油温约为170度,大概就是油面可以看到一些波纹的样子
  • 把裹好粉的鸡翅依次下锅,转中火炸制,过程中可以用筷子移动防止粘连,鸡翅大约需要炸5分钟,翅根和琵琶腿要更久些
  • 把鸡翅捞出来,控一下油「到这一步已经可以吃了」
  • 如果想要更加酥脆色泽更好看,就等一下再烧热油下去复炸30秒捞出即可

整个流程核心就是三步,腌制,裹粉,油炸。

腌制的时候不要腌制太久,不然鸡肉容易变质,有条件可以放冰箱冷藏室里面腌制。

裹粉的时候可以用手指按压几下,这样裹得更牢固,不容易散。面糊不要太干,不然容易裹得太厚,口感变差。

油炸过程中火不用开的很大,火太大容易导致外面快糊了里面还没熟。

总结

结果味道和口感都比较满意,虽然比不了KFC,但是和市场炸鸡基本没太大区别了,如果有在家出不门,又想吃炸鸡的小伙伴,真的可以尝试一下。

而且做出来这么一盘炸鸡,吃的爽的同时,还会有一股莫名的成就感。

毕竟这可是你亲手做的肥宅快乐鸡。

参考资料

  1. 【回形针PaperClip】如何做出令人欲罢不能的炸鸡?
  2. 【上班族的便当】肯德基炸鸡方子,如何上粉炸出鳞片,百分百成功!
为macOS打造一个防污染的本地DNS

Cover: 華如桃李 - 豆の素@Pixiv

前言

家里这边DNS劫持是在是有点严重,非常影响开发速度,所以我就使用dnsmasqdnscrypt-proxy搭建了一个防污染防劫持的本地DNS。

效果演示

搭建过程

如果网络有问题,建议先执行以下指令追加hosts

sudo sh -c 'sync && echo "199.232.4.133 raw.githubusercontent.com">>/etc/hosts'
sudo sh -c 'sync && echo "199.232.4.133 raw.github.com">>/etc/hosts'

首先要安装Homebrew,这个绝大多数用macOS的人应该都安装了吧,官网https://brew.sh/,安装指令如下。

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

然后就是安装dnsmasqdnscrypt-proxy两大组件了。

brew install dnsmasq
brew install dnscrypt-proxy

装好之后,编辑配置文件,首先是dnsmasq的配置,文件路径/usr/local/etc/dnsmasq.conf

#忽略本机DNS解析结果
no-resolv
#增加配置文件夹
conf-dir=/usr/local/etc/dnsmasq.d
#设置上游服务器为dnscrypt-proxy
server=127.0.0.1#5300

然后是dnscrypt-proxy的配置,文件路径/usr/local/etc/dnscrypt-proxy.toml

#本地监听5300端口
listen_addresses = ['127.0.0.1:5300']
#防劫持DNS使用NestDNS
server_names = ['nextdns']
#设置容错DNS为114DNS
fallback_resolvers = ['114.114.114.114:53']

配置好了之后,重启两个组件的服务。

sudo brew services restart dnsmasq
sudo brew services restart dnscrypt-proxy

之后再把网络设置里的DNS地址修改为127.0.0.1,应用之后就可以享受无污染的DNS了。

执行过上面修改hosts的指令的话建议执行这个清除hosts

sudo sed -i "" "s/199.232.4.133 raw.githubusercontent.com//g" /etc/hosts
sudo sed -i "" "s/199.232.4.133 raw.github.com//g" /etc/hosts

国内白名单

虽然DNS没有了污染,但是国内网站DNS全都变慢了,这个肯定不能接受,所以我们接入dnsmasq-china-list项目,来优化本地的DNS。

mkdir /usr/local/etc/dnsmasq.d
WORKDIR="$(mktemp -d)"
curl https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf -o "$WORKDIR/accelerated-domains.china.conf"
curl https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/bogus-nxdomain.china.conf -o "$WORKDIR/bogus-nxdomain.china.conf"
curl https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/google.china.conf -o "$WORKDIR/google.china.conf"
curl https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/apple.china.conf -o "$WORKDIR/apple.china.conf"
sudo cp -f "$WORKDIR/accelerated-domains.china.conf" /usr/local/etc/dnsmasq.d/accelerated-domains.china.conf
sudo cp -f "$WORKDIR/bogus-nxdomain.china.conf" /usr/local/etc/dnsmasq.d/bogus-nxdomain.china.conf
sudo cp -f "$WORKDIR/google.china.conf" /usr/local/etc/dnsmasq.d/google.china.conf
sudo cp -f "$WORKDIR/apple.china.conf" /usr/local/etc/dnsmasq.d/apple.china.conf
rm -rf "$WORKDIR"

OK大功告成。

一键安装脚本

项目地址:https://github.com/mouyase/mac_dnscrypt_installer

脚本使用:

git clone https://github.com/mouyase/mac_dnscrypt_installer
cd mac_dnscrypt_installer
./install.sh
「技术」打造一个漂亮的Android标题栏

Cover: 仮想都歌姫 - [email protected]

前言

最近因为正在做新坑Pixiu,本身的计划是照着Pivision做一个UI几乎没区别的复刻版,但是苦于已经好久没有正经开发过安卓App了,很多UI自己根本不会做,一个滑动的题图卡了我一天的时间,不过最后总算是连抄带蒙的做出来了,而且实际上也很简单,所以就写一个日志来记录一下。

效果演示

开发过程

整个效果实现需要三部分的工作,分别解决三个问题

  • StatusBar透明化
  • 带图片可滑动的ToolBar
  • 图片延伸到StatusBar

StatusBar透明化

首先需要在style.xml里添加如下的style,名字随便起。

<style name="AppTheme.NoActionBar.TranslucentStatusBar" parent="AppTheme.NoActionBar">
	<item name="android:windowTranslucentStatus" tools:targetApi="KITKAT">true</item>
	<item name="android:statusBarColor" tools:targetApi="lollipop">
		@android:color/transparent
	</item>
</style>

首先需要先继承NoActionBar,否则会带上默认的ActionBar,就没办法实现效果。

其次中间有一个tools:targetApi="KITKAT",这个android:windowTranslucentStatus就是设置是否开启透明StatusBar的参数,这个是从Android4.4,也就是Kitkat开始加入的参数,如果不这么写,在value-19里的style.xml写也是可以,不过我比较偷懒,这么写就不用做很多的value文件夹了。

而另一个参数则是Android5.0后加入的,设置StatusBar颜色的参数,这个把他设置成透明的就可以了。

最后则是把目标的Activity设置上这个新的主题。

<activity
	android:name=".view.MainActivity"
	android:theme="@style/AppTheme.NoActionBar.TranslucentStatusBar" />

这样咱们就获得了一个没有标题栏,而且也是透明的,还可以在里面放控件的Activity了。

带图片可滑动的ToolBar

这一步我玩了一上午,但是只是实现一个这样的简单效果并没有多难,只是我坑踩太多。

打开咱们Activity的布局文件,例如这里是activity_main.xml,把根布局换成CoordinatorLayout,然后在里面塞一个AppBarLayout,AppBarLayout里再塞一个CollapsingToolbarLayout,最后在CollapsingToolbarLayout里再分别塞一个ImageView,和一个ToolBar。最后把咱们的主要的布局放在CoordinatorLayout下面,这里放了个LinearLayout

<androidx.coordinatorlayout.widget.CoordinatorLayout
	android:layout_width="match_parent"
	android:layout_height="match_parent">

	<com.google.android.material.appbar.AppBarLayout
		android:layout_width="match_parent"
		android:layout_height="wrap_content">

		<com.google.android.material.appbar.CollapsingToolbarLayout
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
			app:titleEnabled="false">

			<ImageView
				android:id="@+id/iv_title/cover"
				android:layout_width="match_parent"
				android:layout_height="wrap_content"
				android:scaleType="centerCrop"
				app:layout_collapseMode="pin"/>

			<androidx.appcompat.widget.Toolbar
				android:id="@+id/tb_main"
				android:layout_width="match_parent"
				android:layout_height="wrap_content"
				app:layout_collapseMode="pin"
				app:title="@string/app_name" />

		</com.google.android.material.appbar.CollapsingToolbarLayout>

	</com.google.android.material.appbar.AppBarLayout>

	<LinearLayout
		android:layout_width="match_parent"
		android:layout_height="match_parent"
		android:orientation="vertical"
		app:layout_behavior="@string/appbar_scrolling_view_behavior">

	</LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

这里解释一下各个细节,首先是这种滑动变化的布局,必须在CoordinatorLayout里进行,所以说根布局要换成这个,不过如果这个只是页面UI一部分的话,外面也是可以再套其他布局的。

因为要做有多种元素还能滚动的复杂TitleBar,所以要用AppBarLayout包裹ToolBar,这样才能配合CoordinatorLayout实现滚动。

CollapsingToolbarLayout则是相当于一个高级的ToolBar,需要包裹ToolBar才能实现效果。参数中的app:layout_scrollFlags代表了这个控件的可滑动状态。这个参数一共有五种,可以共存,分别是。

参数 功能
scroll 代表这个控件可以被滚动
enterAlways 代表这个控件会被优先滚动,需要和scroll共用
enterAlwaysCollapsed 代表这个控件会被分段滚动,首先先滚动会显示最小高度,到达滚动边界后再完全显示,需要和enterAlways共用
exitUntilCollapsed 代表这个控件会被保留最小高度,不会完全滚动出窗口,需要和scroll共用
snap 代表这个控件滚动时会有边缘吸附效果,需要和scroll共用

因为咱们的控件属于保留最小高度,同时有吸附效果,所以最后需要的是scroll|exitUntilCollapsed|snap

至于app:titleEnabled则是代表是否使用系统自带的标题,这里因为要用ToolBar,所以关了就好。

接下来是ToolBar中的,app:layout_collapseMode,这个参数是开启了滚动后才会生效的效果,这个有三种参数。

参数 功能
none 代表这个控件会被滚出屏幕
pin 代表这个控件不会被滚出屏幕
parallax 代表这个控件滚动时会有滚动差

最后是LinearLayout中的app:layout_behavior,behavior就是在CoordinatorLayout中负责处理各种效果的工具,这里使用了一个系统默认的参数@string/appbar_scrolling_view_behavior,效果为跟随appbar滚动,所以这个控件就相当于咱们整个窗口中的根布局了,其他控件放这里就好。

这样咱们就有了一个具有带图片可滑动的ToolBar,而且StatusBar也是透明的Activity了。

图片延伸到StatusBar

这一步卡的时间最久,因为我改了好多布局的方案,最后图片总是不能好好地显示到StatusBar上,要么是不显示,要么是UI错位,最后发现最简单的办法就是给ToolBar设置一个顶部padding,大小为StatusBar的高度,就可以完美实现了。

ToolBar tb_main = findViewById(R.id.tb_main);
ViewGroup.LayoutParams toolbarParams = tb_main.getLayoutParams();
ViewGroup.MarginLayoutParams toolbarMarginParams;
if (toolbarParams instanceof ViewGroup.MarginLayoutParams) {
	toolbarMarginParams = (ViewGroup.MarginLayoutParams) toolbarParams;
} else {
	toolbarMarginParams = new ViewGroup.MarginLayoutParams(toolbarParams);
}
toolbarMarginParams.setMargins(0, ViewSize.getStatusBarHeight(this), 0, 0);
tb_main.setLayoutParams(toolbarMarginParams);

里面的ViewSize.getStatusBarHeight(Activity activity)如下。

public static int getStatusBarHeight(Activity activity) {
	int statusBarHeight = 0;
	int resourceId_status = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
	if (resourceId_status > 0) {
		statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId_status);
	}
	return statusBarHeight;
}

这样就可以给ToolBar设置上padding了,我们的布局也终于正常了。

结语

于是我终于可以开发其他模块了233。

部署一个Django的项目

准备

首先准备好最新版本的Python

rm -rf /usr/local/python3
./configure --prefix=/usr/local/python3/
make && make install
rm -rf /usr/local/bin/python3
ln -s /usr/local/python3/bin/python3 /usr/local/bin/python3
rm -rf /usr/local/bin/pip3
ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip3

因为我用的是宝塔环境,宝塔自带了Nginx和Supervisor,所以不用单独安装了

然后把代码上传到opt目录,我的上传到了YojigenAPI目录下

这里我是使用了PyCharm的自带Deployment功能进行代码上传

首先打开PyCharm的菜单栏的Tools –> Deployment –> Configure

在里面添加一个新的服务器,我添加的服务器命名为AliyunHK,输入好服务器的登陆信息

然后到Mappings页面,添加一下文件夹对应的路径配置,我这里是将代码放到了服务器的/opt/YojigenAPI目录下

最后到Excluded Paths页面,添加一个Local Path,忽略掉本地的venv虚拟环境文件夹

最后点击PyCharm的菜单栏的Tools –> Deployment –> Upload to AliyunHK,就可以将代码推送到服务器上了

环境配置

ssh登陆到服务器,来到项目目录下,先创建一个虚拟环境

virtualenv -p /usr/local/bin/python3 --no-site-packages venv

然后进入到虚拟环境里

source venv/bin/activate

之后恢复pip的包

pip install -r requirements.txt

注意这里安装了gunicorn,默认的Django项目是不会安装的

包都装完了,就可以退出虚拟环境了

deactivate

服务配置

先测试一下服务启动命令,10000是监听端口

venv/bin/gunicorn YojigenAPI.wsgi -b 0.0.0.0:10000

结果发现报错了,The SECRET_KEY setting must not be empty.,这个错误是项目配置文件找不到了,实际上是因为需要设置一下配置文件的环境变量才行,所以只要运行

venv/bin/gunicorn YojigenAPI.wsgi -b 0.0.0.0:10000 -e DJANGO_SETTINGS_MODULE="YojigenAPI.settings.prod"

之后再启动,如果没错那就没问题了

然而我又报错了,SQLite 3.8.3 or later is required (found 3.7.17).,这个问题是因为我用的是CentOS,系统自带的sqlite3版本太老,升级一下就可以了

./configure --prefix=/usr/local
make & make install

编译好了之后,执行一下这个,把/usr/local/lib添加到系统的链接库中

echo "/usr/local/lib" >> /etc/ld.so.conf
/sbin/ldconfig

之后再运行应该就可以正常启动了,然后配置更新一下数据库,以及转存一下静态文件

venv/bin/python manage.py migrate --settings=YojigenAPI.settings.prod
venv/bin/python manage.py createsuperuser --settings=YojigenAPI.settings.prod
venv/bin/python manage.py collectstatic --settings=YojigenAPI.settings.prod

接下来就是配置Supervisor守护进程了,因为我用了宝塔,宝塔里面有现成的Supervisor管理器,这里就直接使用宝塔的管理器了

填写进去启动信息,保存即可

最后就是大家都熟悉的Nginx配置反向代理了,反向代理到对应的域名上就可以了,不过这里有个坑,是关于静态文件的,宝塔默认的配置里包含了css和js的相关配置,要去给他删了才行

location /
{
	proxy_pass http://127.0.0.1:10000;
	proxy_set_header Host api.yojigen.tech;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_set_header REMOTE-HOST $remote_addr;
	add_header X-Cache $upstream_cache_status;
}

location /static/ 
{
	alias /opt/YojigenAPI/static/;
}

到此配置全部完成,代码成功上线啦。

家乡,硬座火车,和那些社会底层的人民

因为过年回家,我坐上了这列行驶时长25个小时的绿皮硬座火车。

我的家乡很偏僻,在黑龙江的北部,又是一个小地方,所以从北京通往我的家乡的火车只有这一班。于是票就非常的难买,卧铺票可遇不可求,最后我也只能是买到一张硬座的票。

手里拿着票,穿过了密密麻麻的人群,我坐到了自己的座位上。行李架已经放满了,我就只能把自己的背包放在座位下面。

车上挤满了人,人群从车厢一边的门延伸到另一边,每次列车员来卖货都要从人群中挤出一条通道,还得慢慢的避开过道上的人的脚。

因为昨天晚上收拾东西,没睡好,所以我在车开后没多久就睡着了。

然后我就冻醒了。

醒过来的时候,已经是深夜,我摸了摸暖气,凉的。我想把外衣取下来穿上,但是发现外衣已经和窗户冰在一起了。但是虽然我已经被冻醒,腿已经冻的几乎没有知觉,车厢里的其他乘客似乎并没有像我一样在乎暖气很冷这件事,也许是他们已经习惯了这种冰冷的列车,也许是他们没有“当出头鸟”的决心,也许他们都很累,累到已经感受不到这些。

但是我的身体没有说谎,它正用那种麻痹的感觉告诉我这趟列车真的很冷。

于是我叫来了乘务员,质问他为什么没有开暖气。乘务员表示车厢里没有人说冷,所以他们就关掉了。最后在我的强烈要求下,乘务员打开了暖气。我回到座位,守着暖气继续睡了起来。果然人类还是离不开热源。

再醒过来,就已经是白天了,车厢里充满了清晨的阳光,聊天的声音,和泡面的味道。我也拿出了我的泡面,打了点热水泡了起来。

吃着热乎乎的泡面,耳边就听着车上的人们闲聊。

身后的这些人,他们在聊赵本山和范伟。

「赵本山的徒弟们赚了钱都得被他收走一大半」「他那个徒弟,小损样的那个,现在也根本不出来」「他太贪,别人都没钱拿,范德彪都不跟他干了」

总觉得这些说不上是不是「传言」的传言,和现在的时代挺脱节的。赵本山自从2014年彻底退出春晚之后,几乎已经完全是幕后人的存在了,在《乡村爱情》系列里面出演戏份也不是很多,感觉已经很难听到关于他的一些正面或者负面的消息了。至于范伟,早也已经不知道拿了几个影帝和最佳角色的奖杯。

吃完了面,身体热乎了起来,于是掏出了NS,准备打几把太鼓达人。

打到一半的时候,对面的小哥对NS投过来了好奇的目光,我看到他欲言又止,可能是想和我交流一下游戏的事情,不过他可能是看到我正在激烈的按键,所以并没有追问一些什么。

又过了许久,无聊的我和对面小哥聊起了工作和经济,聊着聊着,身后一个大哥可能是听到我说人民币汇率波动,突然就非常自信的说:「人民币不可能贬值,贬值都是人家老美贬值,人民币只会涨」。或许民族自信确实非常的强,大家都不相信自己的国家会在经济上落后,虽然人民币贬值也并不代表经济就是衰落的。

火车就这样开了25个小时,载着想要回到家乡的我,载着这些和我一样,想要回到家乡的人民,开进了终点火车站。

车停了,我拎着行礼下了火车,回到了生活了二十年的家乡,我大口的吸着PM2.5只有个位数的新鲜空气,是熟悉的家乡的味道,虽然冷,但是似乎有点甜。北京的空气真的太差,虽然这么多年已经习惯了,但是还是想念家乡的味道。

家乡还是老样子,总会给人一种时间凝固了的感觉,虽然这些年新盖起来不少的楼房,但是总觉得和记忆中的样子没有差太多。而且也不知道为什么,记忆中的家乡总是没有滤镜的,就像是相册中的老照片,虽然感觉颜色暗淡,但是印象依旧深刻。

我的家距离火车站很近,出站只要步行十分钟就走能进家门。我还没登上楼,母亲就已经把门打开等待着我的归来。又是一年没见,母亲一定非常想念我吧。

“儿子,回来了?”

“嗯”