家用wifi全覆盖无缝漫游

我家一直在用电信办宽带送的光猫/路由器一体机,但是这玩意不但配置选项少还总是出毛病,主要是无线网经常突然地不能用了,然后重启又好了,另外由于房子墙比较多,也有很多角落覆盖不到。最近无线网故障越来越频繁,准备换一个路由器或者无线接入点,于是研究了一下如何把一个大面积的场所都覆盖到WIFI。

为了扩大wifi的覆盖范围,通常采用添加AP(无线接入点)的方法,可以用的技术有很多,比如中继、桥接、中继桥接、客户端桥接,这些名词非常混乱而且可能不同的厂商对于同一个词的解释还不同,但是其实本质上只有两种:开启DHCP(局域网)功能的和不开启DHCP的。开启DHCP,那么这时候的AP其实相当于自己独立有一个小的局域网,有自己的ip段。不开DHCP,这时ip由上级路由器分配。

胖AP和瘦AP的区别在于,胖AP可以独立使用,而瘦AP必须配合AC使用。要实现wifi漫游,对于胖AP来说,需要把各个AP的SSID和密码设置成一样的,然后终端主动去切换,一般是在当前连接的AP信号不佳主动断开之后重新连接信号更好的那个。同一个AC下的瘦AP可以当成同一个胖AP,按道理说同一个AC的瘦AP之间应该可以无缝切换的,但是由于许多AC不支持802.11k/v/r标准,切换也可能需要重新验证之类的。

还有一种很直接的方法,从根本解决问题,不需要多个AP。同一个AP通过馈线和功分器,将天线布置在各个角落,简单粗暴。

Java中SimpleDateFormat类的parse()方法是如何处理不完整的日期字符串的

我编写了如下的代码以供测试:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo {

	public static void main(String[] args) {
		SimpleDateFormat MMdd = new SimpleDateFormat("MM-dd");
		SimpleDateFormat yyyy = new SimpleDateFormat("yyyy");
		SimpleDateFormat full = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		Date date = null;
		try {
			date = MMdd.parse("10-01");
			System.out.println(full.format(date));
			date = yyyy.parse("2020");
			System.out.println(full.format(date));
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}

}

得到如下的输出:

1970-10-01 00:00
2020-01-01 00:00

看起来SimpleDateFormat的parse()方法是以1970年1月1日零点的时间为基础,将我们提供的日期直接“加上去”然后再返回给我们的。

解决WordPress的上传文件大小限制

之前给wordpress换了服务器之后发现上传文件突然有大小限制了,其实这个大小限制并不是wordpress本身决定的,而是由php和nginx(我使用的nginx作为web服务器)的配置决定的。

首先弄个phpinfo,在web服务器目录下新建一个文本文件,写入以下内容:

<?php
echo phpinfo();

保存为phpinfo.php,然后在浏览器访问这个文件即可看见phpinfo,CTRL+F搜索“Loaded Configuration File”找到php-fpm的配置文件位置,我这里是“/etc/php/7.3/fpm/php.ini”。

打开这个文件,修改两个参数的值:

upload_max_filesize=1024M
post_max_size=1024M

cd进入/etc/init.d/文件夹,找到类似php-fpm的文件,然后用这个文件重启php:

/etc/init.d/php7.3-fpm restart

做到这一步,wordpress就会显示允许上传1G大小的文件了,但是它会在文件传输结束以后报错“从服务器收到预料之外的响应。此文件可能已被成功上传。请检查媒体库或刷新本页。”,这是因为nginx还限制了请求体大小,需要在nginx的虚拟机配置文件中添加:

client_max_body_size 50m;

重启nginx:

service nginx restart

Linux和Windows中时间的不同

最近在自己电脑上安装了一个archlinux组了双系统,切换回win以后发现科学上网不行了,排查了一圈发现是时间不对了(用v2ray科学上网必须保证时间和服务器时间误差在一分钟之内)。我就纳闷了,两边设置的时间和时区都是一样的,为什么切换系统时间会变?

查找了资料后发现Linux会将CMOS中的时间看作UTC时间,而Windows则会将其看作本地时间,这就导致了问题。archlinux wiki提供了一行命令,通过修改注册表,让windows将CMOS时间看作UTC时间:

reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /d 1 /t REG_DWORD /f

另外发现一个有趣的事情,CMOS记录的时间竟然是按照“年月日时分秒”,这种格式记录的(参考文章),我一直以为java中的System.currentTimeMillis()是从CMOS时间换算过来的,但是CMOS时间最小单位竟然是秒。而从“从UTC1970年1月1日0时0分0秒起至现在的秒数”是叫UNIX时间,但是这种时间最小单位也是秒。

Google Cloud Compute Engine 启用root账户并开启SSH

谷歌这个云服务器啊,后台搞得太晦涩难懂了,研究个怎么添加root账户的密钥都研究了老半天,现在记录一下设置过程。

首先实例创建以后会自动创建一个普通账户,名字根据你谷歌账户的名字生成,并且配置两个密钥,这两个密钥是无法看见的,这两个密钥的公钥可以在项目的Cloud Engine控制台-元数据-SSH密钥中管理。事实上谷歌云官方不推荐手动管理这些密钥,官方推荐使用OS Login或者直接用谷歌云的网页控制台,详情可以查看官方文档。但是学习这个OS Login又要花费一定的学习成本,我这样懒的人当然是不会去学的啦。

要想手动为账户添加密钥需要先打开网页控制台:

在控制台中使用

sudo vi /etc/ssh/sshd_config

编辑ssh配置文件,将

PermitRootLogin=no

改为

PermitRootLogin=yes

,然后reboot重启或者单独重启ssh。

在元数据-SSH密钥界面,点击编辑后即可添加ssh公钥。

公钥的添加格式为 <ssh协议> <公钥> <要添加的用户> ,如 ssh-rsa 公钥 root 。

保存,然后便可以使用ssh密钥登录root账户了。

PixivCrawler——爬取P站上的高清小姐姐

虽然互联网上已经有很多Pixiv爬虫被开源免费发布了,但是大部分不支持爬榜单,并且基本上都是Python写的,作为一名Java程序员,我决定自己动手写一个爬榜单的Java爬虫。


图片来源于:pixiv 作者:RK@お仕事募集中

目前爬虫程序已经被我开源发布,感兴趣的朋友可以去看看:https://github.com/R-Josef/PixivCrawler

File Transfer——一款点对点直接传输文件的软件

我一直在寻找一款通过互联网点对点(Point-to-Point,非peer-to-peer)传输文件的软件,按道理来说两台计算机之间只要有任何一个拥有公网的ip他们就能互相传输数据,令我不解的是这样的软件却少之又少。

我了解到的此类软件有国内开发的飞鸽传书、飞秋,但是这两款软件有些臃肿不够简洁且很久没有更新了,界面看上去就像10年以前的qq,并且只是局域网传输工具,并不适用于广域网;国外的软件有Dukto、Feem,前者已经很久没有更新了后者则是一个订阅形式的付费软件,并且他们也只专注于局域网,Dukto虽然可以通过ip广域网传输文件,但是接收文件的一方必须有独立的公网ip。

最后我终于在SourceForge找到了这款符合我要求的软件——File Transfer,通过它可以连接到朋友的计算机,点对点安全的直接传输文件,没有任何中间服务器,只要两台计算机中的任意一台拥有一个可以开放监听端口的公网ip即可进行文件传输。

我试用并制作了一个图片介绍:

软件打开以后都会默认作为服务器监听一个端口,需要确定一个拥有公网ip的电脑作为服务器。然后客户端需要在Settings内的出站连接设置里,把ip地址和端口设置成服务器的ip地址和服务端软件内,入站连接设置的端口,点击OK保存,在主界面的右上角点击Connect就能进行连接操作了。

附上官网提供的使用说明:

使用方法——为了使用此程序连接两台计算机,需要在每台计算机上运行“File Transfer”。以下是使传输正常进行的步骤:

步骤1:确定两台计算机中的哪台将是服务器,哪台是客户端。根据哪台计算机具有公共IP(可以由另一台计算机直接访问的IP)来选择哪一台。注意:如果您不知道公共IP的含义,请尝试两种可能性:首先,一台计算机是服务器,另一台是客户端,如果不起作用,请尝试相反的方法。如果任何设置都不起作用,则意味着任何一台计算机都没有公共IP,或者防火墙阻止了该端口(默认情况下,端口为14567)。
步骤2:设置客户端。您唯一需要设置的就是客户端。打开客户端上的“设置”窗口,然后在“直接连接IP”编辑​​框中键入服务器的IP地址。您必须在客户端上插入的IP在状态窗口中显示在服务器上。

例如,如果在服务器上的状态窗口中显示以下行:“服务器已启动。正在侦听84.174.101.189:14567(TCP)…”,则必须在客户端设置中键入的IP是服务器之前的数字。冒号,在此示例中为84.174.101.189。

 

多线程与单线程,异步与同步

多线程指多个程序线程并发执行,而单线程指单个线程执行。

异步表示执行任务a时,可以同时执行任务b而不被阻塞;同步则相反,同步表示执行任务a时执行任务b,此时任务a不能继续执行下去,必须等待任务a完成。

多线程既可以异步又可以同步,但是异步必须由多线程完成。

单线程不能异步。设想如果有一个线程能在不同的任务之间来回切换,那么这和多线程没有区别,多线程本身也是cpu的物理线程切换不同的程序线程,对于单核单线程cpu来说,同一时间也只有一个线程在运行。JavaScript号称单线程异步,其实是将要异步的程序交给了浏览器的其他线程,然后js主线程继续执行接下来的代码,等浏览器执行完异步任务后,会把结果放入列队,然后js再去处理这个列队。