前言 最近微信的跳一跳很火,大家看到排行榜上几百上千的分数,再看看自己百分左右的分数肯定很难过,我手残怪我吗?没关系,如果你跟着我来,也能让你分数霸榜。 原理 首先大家是有一个直观感受,根据两个箱子距离的不同,需要按压的时间也是不一样的,一般来说,一个大胆的猜测是按压时间和距离是成正比的。 这是我们的工作原理: 在跳一跳页面截图 计算出初始点和终点的距离 想办法测出距离与按压时间的系数 想办法让手机按压指定的时间 重复1-4 工具 adb调试工具,它可以辅助截图以及上传截图给电脑,以及控制手机按压位置及时间 python 处理数据 python Pillow库 一个图像库,可以获取图像信息 python matplotlib库 配合Pillow打开图像并记录鼠标点击地方的坐标 准备工作 环境 fedora 27 python3.6 安装 adb调试工具 fedora/centos sudo yum install adb ubuntu sudo apt install adb python需要的库 sudo pip3 i 继续阅读 >>


李余通 18/01/04 20:54:33
以前学习python都是马马虎虎,导致很多特性只是知道完全不会用,现在将他们重新学习 可迭代对象(Iterable) 简单来说,所有可以放入for循环中的对象都是可迭代对象,如列表,元组,字符串,字典… 如何判断对象是否是可迭代对象? 实际上,只要实现了__iter__方法的对象就是可迭代对象,这个方法用来返回迭代器本身(特别重要)。 eg: >>> s = "dasda" >>> s.__iter__() <str_iterator object at 0x7f23ebc44470> python提供了方法判断是否是可迭代对象。 >>> from collections import Iterable >>> isinstance(s,Iterable) True 迭代器(Iterator) 似乎和上面的概念很相似。实际上,所有实现了__next__()方法的对象都是迭代器。一般来说,也都可以放入for循环。 python中原生的迭代器不多,可 继续阅读 >>


李余通 18/01/02 19:16:42
题目 现有两个按钮,按下按钮0会执行2x+1,按下1执行2x+2。x初值为0,现要求出任意正整数n应使用何种按法使得x能变成n。 大眼一看这题就是遍历啊,找所有解法,但是不同于别的简单题,需要你有一个顺序去遍历。递归呗。使用深度优先搜索。 具体如下。 #include<stdio.h> #include<stdlib.h> int success; int max(int s){ int n = 0; int t = 0; while(t<s){ t = t*2+1; n++; } return n; } void print(int arr[],int now){ int i; for(i = 0;i<now;i++){ printf("%d ",arr[i]); } puts(""); } void do_sth(int arr[],int now,int t,int m,int ty 继续阅读 >>


李余通 17/12/24 20:49:00
定义 adlist.h typedef struct listNode{ struct listNode *prev; struct listNode *next; void *value; } 可以看出,redis的链表是一个双向链表,拥有前驱和后继,数据域为void型指针,意味着数据域可以指向需要的类型。 管理链表 adlist.h typedef struct list{ listNode *head; listNode *tail; unsigned long len; //节点复制函数 void *(*dup)(void *ptr); //节点释放函数 void (*free)(void *ptr); //节点比较函数 int (*match)(void *ptr,void *key); } 容易看出,为了管理链表,redis定义了一个结构体,会去存储链表头、尾、和长度。这样的好处在于求链表长度时间复杂度为O(1),而且便于 继续阅读 >>


李余通 17/12/24 20:31:44
两个可能相交的单链表,找出他们的交点 模型 head a1 a2 \ / \ / \ / | | | | tail 注意是单链表,所以他们的形状会是Y型而非X型。 分析 首先,最简单的一种方法是遍历,只是时间复杂度特别高。 简单来说,这两条链表的相交前长度都是不同的,但相交后的长度一致,那么只要想办法让他们从后往前遍历,就很容易找到交点。 - 存数组 - 用栈 其实都是相近的办法,但是栈比较高大上。 那么,就好办了,同时出栈或者同时逆序遍历,遇到下一节点不同的就是交点。 作者:baidu_35085676 发表于2017/12/21 17:56:11 原文链接 阅读:1 评论:0 查看评论 继续阅读 >>


李余通 17/12/21 17:56:11
源码分析章节,我尽量使用原生的redis源码,不去看黄建宏的注释,提高自己阅读源码的能力,此外,redis版本还是3.0 源码下载,大家可以到这 http://download.redis.io/releases/ sdsnew typedef char *sds; sds sdsnewlen(const void *init, size_t initlen) { struct sdshdr *sh; //分配内存 if (init) { sh = zmalloc(sizeof(struct sdshdr)+initlen+1); } else { sh = zcalloc(sizeof(struct sdshdr)+initlen+1); } //分配失败返回NULL if (sh == NULL) return NULL; sh->len = initlen; sh->free = 0;//这里可以看到sds初始是 继续阅读 >>


李余通 17/12/19 22:48:51
本系列所有文章基于《Redis设计与实现》学习而做的随笔,以后不再赘述 c语言的字符串 首先,我们都知道,Redis是用c语言实现的,而c语言,有个很大的弊端,那就是没有原生的字符串,字符串,是使用字符数组实现的。 基于这个原因,我们可以分析一下c字符串的缺点。 1. 字符串的拼接需要提前判断空间是否足够,否则可能造成缓冲区溢出。此外还必须进行malloc分配内存占用大量系统资源。 2. 字符串缩短时需要释放空间,否则可能造成内存泄漏。 那么,Redis的第一个要解决的就是实现一个高效的字符串 Redis的SDS 简单动态字符串(simple dynamic string,SDS)的定义如下: struct sdshdr{ int len; //记录buf中字符串的长度(strlen) int free; //记录buf中未使用的空间大小; char buf[]; //保存字符串的数组 } 举个例子: buf 申请了10个sizeof(char)的空间,保存的内容是"Redis" 那么 继续阅读 >>


李余通 17/12/18 22:56:14
get、post 很简单,直接request.getParameter(“name”) 其他方式 例如delete,put。 如上的方法可能无法获取,找到的原因说可能是tomcat api的问题。 解决办法: BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream())); String s = null; String data = ""; while((s = br.readLine()) != null) { data = data.concat(s).concat("\n"); } data = data.substring(0,data.length()-1); System.out.println(data); 获取了类似a=b&c=d的字符串,然后进行分析获得。 在分享一个自己写的分析字符串,接上面的代码 HashMap<String,String> hm = new HashMap 继续阅读 >>


李余通 17/12/11 22:05:56
背景 最近在学习restful api的开发,遇到这样的问题,书上使用itsdangerous生成token,但是同一个用户可以短时间内生成多个token,而这些token在有效期内都是可以使用的。现在就是要实现的需求是仅最新的token有效。老的token失效。 说明 假设一共开发了三种客户端:WEB,ANDROID,IOS,同一种客户端的token只保存最新的一份。 思路 使用数据库保存token,每次生成token时仅需更新token,验证时候先验证token是否有效,再去数据库查找是否是最新的token。 设计 数据库使用redis,提高查询速率。 现在需要确定使用hash还是k-v更好一些。 存法: hash: token:uid{ WEB:tokenweb, ANDROID:tokenandroid, IPHONE:tokeniphone, } k-v: token:uid:WEB:tokenweb token:uid:ANDROID:tokenandroid token:uid:IPHONE:toke 继续阅读 >>


李余通 17/12/04 17:03:36
定义方法 宏格式: 宏指令名 MACRO 形参 · · · (宏定义体) ENDM 调用 宏名[形参] 作用:MASM.EXE会将调用到宏的地方用宏定义体完全替换。定义宏的地方不会生成机器码。 过程格式: 过程名 PROC [NEAR/FAR] · · · RET · · · 过程名 ENDP 调用:call 过程名 注:过程不能传递参数 作用:定义过程的地方会生成机器码。 来个实例 拿9号功能调用来做一个对比。 9号功能调用 作用> 输出一串字符 实例> a.asm ;9号功能调用演示 data segment str db "this is a string.$" data ends code segment assume cs:code,ds:data sta 继续阅读 >>


李余通 17/12/03 00:04:27