解决一道智力题

今天被问了一道题,是这样的:
求解:一筐鸡蛋:
1个1个拿,正好拿完
2个2个拿,还剩1个
3个3个拿,正好拿完
4个4个拿,还剩1个
5个5个拿,还差1个
6个6个拿,还剩3个
7个7个拿,正好拿完
8个8个拿,还剩1个
9个9个拿,正好拿完
问筐里最少有多少鸡蛋
能算出这道题的智商不一般!求答案?有高手没,算算吧!
”5个5个拿,是还差1个“,也就是还剩下4个,这是这个题目的一个小陷阱…
我第一反应想到的是这个数一定是63的倍数,但是后来就没有什么想法了。
再后来,我想到了一个残暴的方法,穷举法:
1 | int i = 1; |
执行后正确答案是1449;
能被7整除,能被9整除,所以肯定是63的倍数
如果利用63的倍数来做写的话:
1 | int i = 1; |
答案依旧是1449,稍微显得动了点头脑,但还是穷举法,有什么高大上的解法么???在下默默献上膝盖!
IntelliJ IDEA 插件开发

说明
我现在用的这个插件时ECTranslation,是用于做中英文翻译的,可以在看文档和注释的是方便的使用,然而近期变得不好用了
- 翻译的内容有时能出来,有时出不来,有时甚至没有反应
- 查看了该款插件的源代码,发现是调用的有道翻译的API接口,而且在代码里写死了APIkey和KeyFrom
- 调用了有道的API,加上上面作者提供的Key,再传入翻译的文本内容,发现返回值居然是请求次数过多,被封禁了…..
- 明白了,很多使用这个插件的开发者都是用的作者提供的默认Key,默认情况下1小时请求的限制次数是1000次
- 肯定是次数超了
- 但是他的配置信息是写在代码里的,能配置到IDEA的面板上供使用者自己配置就好了
- 于是我有了自己动手的想法
开始项目
第一步创建IDEA插件项目:
第二步目录结构如下图所示:
项目配置
plugin.xml
看代码,相信能看懂的:
1 | <idea-plugin> |
只有一个action ,调用的类是ECTranslation,快捷键设置的ctrl + NumPad 0
最后
代码都是人家的,我就没好意思往IDEA的仓库里上传了…
更新(2023-08-02)
最近发现有道 API 的接口不能用了,无法返回翻译数据,于是重新修改了下插件,发布最新版本
地址: https://github.com/JoyLau/joylau-translation/releases/tag/V2
目前有个问题就是,现在的有道 API 是收费的,刚开始注册送 50 元,不过很快会用完的, 到时再换其他的翻译 API 吧
Redis主从复制 --- 实现读写分离

配置
1 | ################################# REPLICATION ################################# |
参数解释
slaveof: Slave库配置Master的ip地址和端口号masterauth:如果Master配置了密码,那么这里设置密码slave-serve-stale-data: 如果Master宕机了,Salve是否继续提供服务slave-read-only: Slave 是否是只读模式,默认为是
部分配置项解释
1 | daemonize yes #是否以后台进程运行,默认为no |
原理
- 如果设置了一个Slave,无论是第一次连接还是重连到Master,它都会发出一个SYNC命令;
- 当Master收到SYNC命令之后,会做两件事:
a) Master执行BGSAVE,即在后台保存数据到磁盘(rdb快照文件);
b) Master同时将新收到的写入和修改数据集的命令存入缓冲区(非查询类); - 当Master在后台把数据保存到快照文件完成之后,Master会把这个快照文件传送给Slave,而Slave则把内存清空后,加载该文件到内存中;
- 而Master也会把此前收集到缓冲区中的命令,通过Reids命令协议形式转发给Slave,Slave执行这些命令,实现和Master的同步;
- Master/Slave此后会不断通过异步方式进行命令的同步,达到最终数据的同步一致;
- 需要注意的是Master和Slave之间一旦发生重连都会引发全量同步操作。但在2.8之后版本,也可能是部分同步操作。
部分复制
- 2.8开始,当Master和Slave之间的连接断开之后,他们之间可以采用持续复制处理方式代替采用全量同步。
Master端为复制流维护一个内存缓冲区(in-memory backlog),记录最近发送的复制流命令;同时,Master和Slave之间都维护一个复制偏移量(replication offset)和当前Master服务器ID(Master run id)。当网络断开,Slave尝试重连时:
a. 如果MasterID相同(即仍是断网前的Master服务器),并且从断开时到当前时刻的历史命令依然在Master的内存缓冲区中存在,则Master会将缺失的这段时间的所有命令发送给Slave执行,然后复制工作就可以继续执行了;
b. 否则,依然需要全量复制操作; - Redis 2.8 的这个部分重同步特性会用到一个新增的 PSYNC 内部命令, 而 Redis 2.8 以前的旧版本只有 SYNC 命令, 不过, 只要从服务器是 Redis 2.8 或以上的版本, 它就会根据主服务器的版本来决定到底是使用 PSYNC 还是 SYNC :
如果主服务器是 Redis 2.8 或以上版本,那么从服务器使用 PSYNC 命令来进行同步。
如果主服务器是 Redis 2.8 之前的版本,那么从服务器使用 SYNC 命令来进行同步。
同步机制
全量同步
Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下:
1)从服务器连接主服务器,发送SYNC命令;
2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
增量同步
Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。
增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
Redis主从同步策略
主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。
最后
SpringCloud --- 构建开发环境

来个简单的小例子
2个项目先来测试一下:
- eureka-server
- eureka-service
eureka-server
pom 配置
1 | <?xml version="1.0" encoding="UTF-8"?> |
application.properties
1 | server.port=8080 |
EurekaServerApplication
1 | package cn.joylau.cloud.eureka.server; |
eureka-service
pom 配置
1 | <?xml version="1.0" encoding="UTF-8"?> |
application.properties
1 | spring.application.name=eureka-service |
EurekaServerApplication
1 | package cn.joylau.cloud.eureka.service; |
ComputeController
1 | package cn.joylau.cloud.eureka.service; |
配置说明
@EnableEurekaServer: 开启服务发现- eureka是一个高可用的组件,它没有后端缓存,每一个实例注册之后需要向注册中心发送心跳(因此可以在内存中完成),在默认情况下eureka server也是一个eureka client ,必须要指定一个 server
- 当client向server注册时,它会提供一些元数据,例如主机和端口,URL,主页等。Eureka server 从每个client实例接收心跳消息。 如果心跳超时,则通常将该实例从注册server中删除
@EnableDiscoveryClient: 注册一个微服务spring.application.name:应用名
JoyLau-MyBatis 使用说明
关于joylau-mybatis的说明
- 该项目来源自 https://github.com/abel533/Mapper 详细信息和源代码可fork查看
- 我封装之后项目地址 https://github.com/JoyLau/joylau-mybatis
- 我自己整合通用Mapper,分页,以及排序功能,使用起来无缝结合,丝般顺滑
- 我对其封装了所有的通用mapper,并整合本项目添加了自己的方法,详细请查看下文或者在线查看api文档: http://api.joylau.cn/
- 文档你主要需要查看function的类注释
- 下面我来逐一介绍:
BaseController
继承FunctionController,目前有2个抽象方法,getSession()和getContextPath(),一看就知道是干嘛的,不多说。想要扩展很简单,继续写自己的方法即可
BaseMapper
- 集成了MySQL所使用的绝大部分通用Mapper,包括BaseMapper,ExampleMapper,RowBoundsMapper,MySqlMapper,IdsMapper…等等,详细可查看API文档,或者下载源码查看
- 所有的单表及简单的多表操作都在这里面啦,基本上你是不需要扩展啦,好不好用,敲起mapper再点一下你就知道了
BaseService
- 得益于Spring项目的强大支持,在Spring4.x后,支持泛型注入,这使得我们封装的更加简单了
- 现在,不必再调用到Mapper层,现在在Service层就可以完美使用,封装了3个插入方法,4个更新方法,5个删除方法,13个查询方法
- 内容涵盖了单条记录CRUD;根据ID或者属性或者条件CRUD;批量删除,插入;分页查询
- 说下分页查询怎么使用:调用selectPage可以进行单表分页查询,调用selectPageByExample可以进行条件分页查询
BaseServiceImpl
- 继承的FunctionServiceImpl已经实现了上述所有的通用CURD方法
- 在继承的FunctionServiceImpl类里我提供了获取mapper的方法,由此方法,可以进行很方便的扩展,你懂得~~
BaseModel
- 添加每个实体都会用到的id属性
- 添加了createTime和updateTime属性,虽然在业务上可能没有什么用处,但是对于开发和运维的作用相当大,谁用谁知道
我的接口解释
1 |
|
怎么使用?
很简单
- 你的Mapper继承BaseMapper
- 你的Service继承BaseService
- 你的ServiceImpl实现你的Service借口,再继承BaseServiceImpl
- 你的Model继承BaseModel
来试一下
- 在你的ServiceImpl里点一下方法试试? 是不是很棒???
- 在你的Mapper里再点一下方法试试?? 6666…
最后
- 能想到的我都写了,BaseMapper和BaseServiceImpl基本上不需要扩展了,有不明白的可以联系我
- 欢迎指正,共同学习
Redis有多快??? --- 基准性能测试

说明
- redis默认提供了性能测试的工具
- 在linux下文件是redis-benchmark
- 在windows下文件是redis-benchmark.exe
参数查看
redis-benchmark -h1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48Usage: redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests]> [-
k <boolean>]
-h <hostname> Server hostname (default 127.0.0.1)
-p <port> Server port (default 6379)
-s <socket> Server socket (overrides host and port)
-a <password> Password for Redis Auth
-c <clients> Number of parallel connections (default 50)
-n <requests> Total number of requests (default 100000)
-d <size> Data size of SET/GET value in bytes (default 2)
-dbnum <db> SELECT the specified db number (default 0)
-k <boolean> 1=keep alive 0=reconnect (default 1)
-r <keyspacelen> Use random keys for SET/GET/INCR, random values for SADD
Using this option the benchmark will expand the string __rand_int__
inside an argument with a 12 digits number in the specified range
from 0 to keyspacelen-1. The substitution changes every time a command
is executed. Default tests use this to hit random keys in the
specified range.
-P <numreq> Pipeline <numreq> requests. Default 1 (no pipeline).
-q Quiet. Just show query/sec values
--csv Output in CSV format
-l Loop. Run the tests forever
-t <tests> Only run the comma separated list of tests. The test
names are the same as the ones produced as output.
-I Idle mode. Just open N idle connections and wait.
Examples:
Run the benchmark with the default configuration against 127.0.0.1:6379:
$ redis-benchmark
Use 20 parallel clients, for a total of 100k requests, against 192.168.1.1:
$ redis-benchmark -h 192.168.1.1 -p 6379 -n 100000 -c 20
Fill 127.0.0.1:6379 with about 1 million keys only using the SET test:
$ redis-benchmark -t set -n 1000000 -r 100000000
Benchmark 127.0.0.1:6379 for a few commands producing CSV output:
$ redis-benchmark -t ping,set,get -n 100000 --csv
Benchmark a specific command line:
$ redis-benchmark -r 10000 -n 10000 eval 'return redis.call("ping")' 0
Fill a list with 10000 random elements:
$ redis-benchmark -r 10000 -n 10000 lpush mylist __rand_int__
On user specified command lines __rand_int__ is replaced with a random integer
with a range of values selected by the -r option.
开始测试
- 搞清了参数的含义,可以进行测试了
- 本次配置为Redis的默认配置,默认的配置项已经有足够好的性能表现了,不需要调优
redis-benchmark -h joylau.cn -p 6379 -a XXX -t get,set -n 1000 -c 400 -q
我是模仿了我自己现在公司的业务需求,测试了我直接服务器上的Redis,向redis服务器发送1000个请求,每个请求附带400个并发客户端,以静默显示

可以看到,set操作每秒处理17241次,get操作每秒处理17543次redis-benchmark -h joylau.cn -p 6379 -a XXX -t get,set -n 1000 -c 400
同上,以标准格式显示

可以看到,set操作每秒处理17857次,get操作每秒处理18518次- 我自己也开了本地的服务器做测试,每秒操作次数可达100000次
一些参数说明
- -t : 可以选择你需要运行的测试用例
- -r : 设置随机数来SET/GET/INCR
- -P : 一次性执行多条命令,记得在多条命令需要处理时候使用 pipelining。
陷阱和错误的认识
第一点是显而易见的:基准测试的黄金准则是使用相同的标准。 用相同的任务量测试不同版本的 Redis,或者用相同的参数测试测试不同版本 Redis。 如果把 Redis 和其他工具测试,那就需要小心功能细节差异。
- Redis 是一个服务器:所有的命令都包含网络或 IPC 消耗。这意味着和它和 SQLite, Berkeley DB, Tokyo/Kyoto Cabinet 等比较起来无意义, 因为大部分的消耗都在网络协议上面。
- Redis 的大部分常用命令都有确认返回。有些数据存储系统则没有(比如 MongoDB 的写操作没有返回确认)。把 Redis 和其他单向调用命令存储系统比较意义不大。
简单的循环操作 Redis 其实不是对 Redis 进行基准测试,而是测试你的网络(或者 IPC)延迟。想要真正测试 Redis,需要使用多个连接(比如 redis-benchmark), 或者使用 pipelining 来聚合多个命令,另外还可以采用多线程或多进程。 - Redis 是一个内存数据库,同时提供一些可选的持久化功能。 如果你想和一个持久化服务器(MySQL, PostgreSQL 等等) 对比的话, 那你需要考虑启用 AOF 和适当的 fsync 策略。
- Redis 是单线程服务。它并没有设计为多 CPU 进行优化。如果想要从多核获取好处, 那就考虑启用多个实例吧。将单实例 Redis 和多线程数据库对比是不公平的。
影响 Redis 性能的因素
有几个因素直接决定 Redis 的性能。它们能够改变基准测试的结果, 所以我们必须注意到它们。一般情况下,Redis 默认参数已经可以提供足够的性能, 不需要调优。
- 网络带宽和延迟通常是最大短板。建议在基准测试之前使用 ping 来检查服务端到客户端的延迟。根据带宽,可以计算出最大吞吐量。 比如将 4 KB 的字符串塞入 Redis,吞吐量是 100000 q/s,那么实际需要 3.2 Gbits/s 的带宽,所以需要 10 GBits/s 网络连接, 1 Gbits/s 是不够的。 在很多线上服务中,Redis 吞吐会先被网络带宽限制住,而不是 CPU。 为了达到高吞吐量突破 TCP/IP 限制,最后采用 10 Gbits/s 的网卡, 或者多个 1 Gbits/s 网卡。
- CPU 是另外一个重要的影响因素,由于是单线程模型,Redis 更喜欢大缓存快速 CPU, 而不是多核。这种场景下面,比较推荐 Intel CPU。AMD CPU 可能只有 Intel CPU 的一半性能(通过对 Nehalem EP/Westmere EP/Sandy 平台的对比)。 当其他条件相当时候,CPU 就成了 redis-benchmark 的限制因素。
- 在小对象存取时候,内存速度和带宽看上去不是很重要,但是对大对象(> 10 KB), 它就变得重要起来。不过通常情况下面,倒不至于为了优化 Redis 而购买更高性能的内存模块。
- Redis 在 VM 上会变慢。虚拟化对普通操作会有额外的消耗,Redis 对系统调用和网络终端不会有太多的 overhead。建议把 Redis 运行在物理机器上, 特别是当你很在意延迟时候。在最先进的虚拟化设备(VMWare)上面,redis-benchmark 的测试结果比物理机器上慢了一倍,很多 CPU 时间被消费在系统调用和中断上面。
- 如果服务器和客户端都运行在同一个机器上面,那么 TCP/IP loopback 和 unix domain sockets 都可以使用。对 Linux 来说,使用 unix socket 可以比 TCP/IP loopback 快 50%。 默认 redis-benchmark 是使用 TCP/IP loopback。 当大量使用 pipelining 时候,unix domain sockets 的优势就不那么明显了。
- 当大量使用 pipelining 时候,unix domain sockets 的优势就不那么明显了。
- 当使用网络连接时,并且以太网网数据包在 1500 bytes 以下时, 将多条命令包装成 pipelining 可以大大提高效率。事实上,处理 10 bytes,100 bytes, 1000 bytes 的请求时候,吞吐量是差不多的
我想说
- 我分别测试我之前在腾讯云上的Redis服务器 (Windows Server 2008R2) 和现在在阿里云上的服务器 (Linux CentOS 7.2) 及 局域网下同事的Redis服务器,和本机Redis的服务器
速度最快的本机服务器,其次是同事的服务器,再次是阿里云上的服务器,最后是腾讯云上的服务器 - 测试差异之大除了在硬件上的差别外,最客观的因素在网络带宽上,我自己2个位于云上的服务器都是1M的带宽,如此测试,正如上面所说,远远不达不到数据传输所需要的带宽值
最后
Docker常用命令备忘
Docker
- 安装:
yum install docker - 卸载:
yum remove docker - 启动:
systemctl start docker - 开机自启:
systemctl enable docker
Dockerfile
1 | FROM java:8 |
镜像
- 编译镜像:
docker build –t joylau/docker . - 查看镜像:
docker images - 删除镜像:
docker rmi name/id
容器
- 运行:
docker run –d --name joylau –p 8080:8080 joylau/docker - 停止容器:
docker stop id/name - 查看运行中的容器 :
docker ps - 查看所有容器:
docker ps -a - 删除容器:
docker rm id/name
2018-07-05 16:05:00 更新
拉取docker镜像
docker pull image_name
查看宿主机上的镜像,Docker镜像保存在/var/lib/docker目录下:
docker images
删除镜像
docker rmi docker.io/tomcat:7.0.77-jre7 或者 docker rmi b39c68b7af30
查看当前有哪些容器正在运行
docker ps
查看所有容器
docker ps -a
启动、停止、重启容器命令:
docker start container_name/container_id
docker stop container_name/container_id
docker restart container_name/container_id
后台启动一个容器后,如果想进入到这个容器,可以使用attach命令:
docker attach container_name/container_id
删除容器的命令:
docker rm container_name/container_id
删除所有停止的容器:
docker rm $(docker ps -a -q)
查看当前系统Docker信息
docker info
从Docker hub上下载某个镜像:
docker pull centos:latest
docker pull centos:latest
查找Docker Hub上的nginx镜像
docker search nginx
执行docker pull centos会将Centos这个仓库下面的所有镜像下载到本地repository。
2018-07-09 14:02:25 更新
docker search xxx : 在docker仓库查找镜像
docker images | grep xxx : 在本地仓库查找镜像
2018-07-12 09:44:40 更新
进入容器: docker exec -it 容器的ID或者NAME /bin/bash
2020-04-12 12:30:25 更新
查找自定义属性
1 | docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.Names}}\t{{.Status}}" |










