微信中jssdk使用中分享的页面,有invalid signature的提示,需要关注以下两点

1. 确认url是页面完整的url(请在当前页面alert(location.href.split(‘#’)[0])确认),包括’http(s)://’部分,以及’?’后面的GET参数部分,但不包括’#'hash后面的部分。最主要的就是域名无后缀时,必须添加’/',如http://qq.com/

2. nonceStr最好是16位的字符,自己开始一直不是16位,一直就invalid signature了。

帮助文档中没有提nonceStr的规范制度,折腾了半天都不对,校验地址

http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign

和同事的联调时碰到一个诡异的问题,server端的业务逻辑层面没有任何异常,但返回结果给client端时,并没有发送完所有的数据,就直接发送了RST给client,导致client读取结果失败。注: client与server直接是短连接,server在write所有的数据后会直接close。

通过tcpdump截包对比之前旧版本正常的client端通信,发送server与旧版本的client通信时,三次握手 => client发送数据 => server发送响应数据 => 四次挥手。但与新版本client通信时,则直接是 三次握手 => client发送数据 => server发送响应数据(未完成) => server发送RST

借助强大的Google大神,以及万能Stackoverflow。原因如下:当close断开连接时,如果缓冲区中又未被读取的数据,则tcp不会发送正常的FIN包,而发送RST给对端。

简单测试一下,代码如下,client和server的主要代码如下:

/*
 * client
*/
void send_plain_buf(int fd, size_t buf_size)
{
char buf[buf_size];
memset(buf, 0, buf_size);
int ret = write(fd, buf, buf_size);
if(ret < 0) {
fprintf(stderr, "send failed, err[%m]\n");
return;
}
ret = read(fd, buf, 1);
if(ret == 0) {
fprintf(stderr, "client get FIN\n");
} else {
fprintf(stderr, "read ret[%d], err[%m]", ret);
}
return;
}

/*
 *server
*/

void recv_plain_buf(int fd, size_t buf_size)
{
char buf[buf_size];
memset(buf, 0, buf_size);
int ret = read(fd, buf, buf_size);
if(ret < 0) {
fprintf(stderr, "server recv failed, err[%m]\n");
return;
}
return;
}

测试一:client发送1个byte,server读取1个byte,tcpdump截包

21:35:43.829700 IP tc-im-nrd306.tc.baidu.com.22579 > tc-im-nrd301.tc.baidu.com.8654: S 3630522968:3630522968(0) win 5840 <mss 1460,sackOK,timestamp 1827311072 0,nop,wscale 7>
21:35:43.829706 IP tc-im-nrd301.tc.baidu.com.8654 > tc-im-nrd306.tc.baidu.com.22579: S 2472593503:2472593503(0) ack 3630522969 win 5792 <mss 1460,sackOK,timestamp 2429650378 1827311072,nop,wscale 7>
21:35:43.829846 IP tc-im-nrd306.tc.baidu.com.22579 > tc-im-nrd301.tc.baidu.com.8654: . ack 1 win 46 <nop,nop,timestamp 1827311073 2429650378>
21:35:43.829873 IP tc-im-nrd306.tc.baidu.com.22579 > tc-im-nrd301.tc.baidu.com.8654: P 1:2(1) ack 1 win 46 <nop,nop,timestamp 1827311073 2429650378>
21:35:43.829876 IP tc-im-nrd301.tc.baidu.com.8654 > tc-im-nrd306.tc.baidu.com.22579: . ack 2 win 46 <nop,nop,timestamp 2429650378 1827311073>
21:35:43.829888 IP tc-im-nrd301.tc.baidu.com.8654 > tc-im-nrd306.tc.baidu.com.22579: F 1:1(0) ack 2 win 46 <nop,nop,timestamp 2429650378 1827311073>
21:35:43.830035 IP tc-im-nrd306.tc.baidu.com.22579 > tc-im-nrd301.tc.baidu.com.8654: . ack 2 win 46 <nop,nop,timestamp 1827311073 2429650378>
21:35:43.830080 IP tc-im-nrd306.tc.baidu.com.22579 > tc-im-nrd301.tc.baidu.com.8654: F 2:2(0) ack 2 win 46 <nop,nop,timestamp 1827311073 2429650378>
21:35:43.830083 IP tc-im-nrd301.tc.baidu.com.8654 > tc-im-nrd306.tc.baidu.com.22579: . ack 3 win 46 <nop,nop,timestamp 2429650378 1827311073>

测试二:client发送2个byte,server读取1个byte,tcpdump截包

21:36:31.137496 IP tc-im-nrd306.tc.baidu.com.22580 > tc-im-nrd301.tc.baidu.com.8654: S 3686863514:3686863514(0) win 5840 <mss 1460,sackOK,timestamp 1827358388 0,nop,wscale 7>
21:36:31.137501 IP tc-im-nrd301.tc.baidu.com.8654 > tc-im-nrd306.tc.baidu.com.22580: S 2526723815:2526723815(0) ack 3686863515 win 5792 <mss 1460,sackOK,timestamp 2429697693 1827358388,nop,wscale 7>
21:36:31.137666 IP tc-im-nrd306.tc.baidu.com.22580 > tc-im-nrd301.tc.baidu.com.8654: . ack 1 win 46 <nop,nop,timestamp 1827358388 2429697693>
21:36:31.137671 IP tc-im-nrd306.tc.baidu.com.22580 > tc-im-nrd301.tc.baidu.com.8654: P 1:3(2) ack 1 win 46 <nop,nop,timestamp 1827358388 2429697693>
21:36:31.137676 IP tc-im-nrd301.tc.baidu.com.8654 > tc-im-nrd306.tc.baidu.com.22580: . ack 3 win 46 <nop,nop,timestamp 2429697693 1827358388>

21:36:31.137705 IP tc-im-nrd301.tc.baidu.com.8654 > tc-im-nrd306.tc.baidu.com.22580: R 1:1(0) ack 3 win 46 <nop,nop,timestamp 2429697693 1827358388>

在net/ipv4/tcp.c:1900行附近的代码如下:

/* As outlined in RFC 2525, section 2.17, we send a RST here because
* data was lost. To witness the awful effects of the old behavior of
* always doing a FIN, run an older 2.1.x kernel or 2.0.x, start a bulk
* GET in an FTP client, suspend the process, wait for the client to
* advertise a zero window, then kill -9 the FTP client, wheee...
* Note: timeout is always zero in such a case.
*/
if (data_was_unread) {
/* Unread data was tossed, zap the connection. */
NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE);
tcp_set_state(sk, TCP_CLOSE);
tcp_send_active_reset(sk, sk->sk_allocation);
..

相关参考:

  1. RFC2525中的描述: http://tools.ietf.org/html/rfc2525#page-50
  2. 一个关于此问题的描述: http://cs.baylor.edu/~donahoo/practical/CSockets/TCPRST.pdf

阅读原文链接地址在这,http://bit.ly/hlFaqL

Mark一段针对废数据合并的。

更新和删除操作会产生很多的无用数据,这些垃圾数据的回收是通过定时合并操作实现的,一般可选择每天服务的低峰期,比如凌晨两点启动每日合并任务。

定时合并(Merge):采用0/1目录的方式,假设当前的服务目录编号为0,合并过程如下:

1, 关闭目录0的数据文件和索引文件,后续的更新操作(包括合并过程中的更新操作)都写入目录1中新开的文件;

2, 顺序读取目录0的索引文件,对每一个索引项,对比是否与内存中的内容一致,如果一致,说明是最新的有效索引,将对应的数据追加到目录1中的数据文件,同时生成相应的索引信息追加到目录1的索引文件中并修改内存中的索引项;

3, 合并过程结束时可以回收目录0中的数据文件和索引文件;

由于合并过程中可能有更新操作,且都需要追加目录1中的索引文件,因此,需要将索引文件编号分成两段,比如合并过程中写入的索引文件从1开始编号,最大不超过1000;更新操作写入的索引文件从1001开始编号。

,

某外资投行IT部门面试,同去了5个,唯一没offer的,不想说啥,如果因为某些原因觉得求职者动机问题较多,也应该在面试时保持公平,以均衡的考察各位candidate能力……

一面,HK人,UK经历,英语纯正,搞的我不适应,一个问题,design a distribution system for market trades,考虑各种问题,我扯了各种cache, thread pool, repacketing。

二面,中国人,英语好懂多了,一个问题,多态实现,具有多态特性的对象的内存分布,画出来= =。

三面,中国人,一个字,酷!一个问题,auto pointer的内存实现,各种有关此问题的内存布局以及操纵之类的。谈了reference counter。

群殴,discussion,问题不大,说说就行,一堆人单词量扯淡,四个问题两个看不懂。

最后是补的paper test,就写码,题目难度很简单,不具备啥算法,就纯粹写逻辑。

跟网上的面经以及其他candidate的问题差距十万八千里,不具备参考价值,前两名的面试官比较nice,三面的哥们你太酷了,膜拜下。

anyway,第一个纯E文正装面试,mark下,的确自身在之前表现的不如其他candidate积极

,

支持正则表达式比较。。。

select * from `tweets` where `nick` REGEXP `^leon`

/*
e.g: input:   abcdefgegcsgcasse
     output:  abcdefg
     tips: 算法示例,只支持由小写字母构成的字符串,当然可以lastpos[256];
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
 char buf[128];
 scanf("%s",buf);
 int i,lastpos[26];
 for(i=0;i<26;i++)
 lastpos[i] = -1;
 int s=0,maxlen=0,maxs,maxe;
 int len=strlen(buf);
 for(i=0;i<len;i++)
 {
 if(s > lastpos[buf[i]-'a'])
 {
 lastpos[buf[i]-'a']=i;
 }
 else
 {
 int len = i-s;
 if(len > maxlen)
 {
 maxlen = len;
 maxs = s;
 maxe = i-1;
 }
 s = i;
 lastpos[buf[i]-'a']=i;
 }
 }
 for(i=maxs;i<=maxe;i++)
 printf("%c",buf[i]);
 printf("\n");
 return 0;
}