续上一篇随笔: https://www.cnblogs.com/kingstarer/p/8469016.html 《工做碰上的技术问题及处理经验》html
因为内容有不少空格,若是直接在正文粘贴,发表后空格会消失,致使版本看起来比较难看。linux
因此我把主要内容作为代码发表。算法
我以为天天把工做碰上的问题作一个简单的笔记挺不错的,一来能够锻炼本身的表达能力,二来也方便本身之后复查,由于之后工做极可能再碰上一样的问题。sql
因为我每次记录笔记时,可能只是记录了关键字,而要发出来作为共享随笔,只有这些关键字确定是不行的,你们看了一头雾水。数据库
因此发表前须要二次整理,目前只整理到了20180424,还有一年多的笔记,后面会继续整理,陆续发表出来。编程
但愿能对你们有所帮助。vim
20171226: socket被子进程close父进程还能用,可是被shutdown父进程则没法用。 shutdown后还须要close。close计数为0时会自动shutdown。 recv函数参数含义: msg_peek recv 只读数据 不取出 msg_waitall recv 等到全部数据读取完毕才返回 msg_confirm send 等到对方收到数据才返回 MSG_NOSIGNAL send 对方关闭socket时不发送sigpipe信号(仍是会返回出错) TCP_NODELAY,出现40ms延时最大的可能就是因为没有设置TCP_NODELAY 在长链接的交互中,有些时候一个发送的数据包很是的小, 加上一个数据包的头部就会致使浪费,并且因为传输的数据多了,就可能会形成网络拥塞的状况, 在系统底层默认采用了Nagle算法,能够把连续发送的多个小包组装为一个更大的数据包而后再进行发送. 可是对于咱们交互性的应用程序意义就不大了,在这种状况下咱们发送一个小数据包的请求,就会马上进行等待,不会还有后面的数据包一块儿发送 下一个数据包,这个时候服务端出现了延时返回的问题.对于这个问题能够经过设置server端TCP_QUICKACK选项来解决. TCP_QUICKACK可让服务端尽快的响应这个ack包. 采用writev方式发送多个小数据包 一台机器上的端口是有限,最多65535(一个unsigned char)个,在系统文件/proc/sys/net/ipv4/ip_local_port_range 中咱们通常能够看到32768 61000 的结果,这里表示这台机器可使用的端口范围是32768到61000, 小提示: 通常的服务模式都是服务端一个端口,客户端使用不一样的端口进行链接,可是其实咱们也是能够把这个过程倒过来,咱们客户端只用一个端可是服务端确是不一样的端口,客户端作下面的修改原有的方式 socket分配句柄-> connect 分配的句柄 改成 socket分配句柄 ->对socket设置SO_REUSEADDR选项->像服务端同样bind某个端口->connect 就能够实现 不过这种应用相对比较少,对于像网络爬虫这种状况可能相对会比较适用,只不过6w链接已经够多了,继续增长的意义不必定那么大就是了. 这个要根据状况来看, 通常状况connect一个不存在的ip地址,发起链接的服务须要等待ack的返回,因为ip地址不存在,不会有返回,这个时候会一直等到超时才返回。若是链接的是一个存在的ip,可是相应的端口没有服务,这个时候会立刻获得返回,收到一个ECONNREFUSED(Connection refused)的结果。 可是在咱们的网络会存在一些有限制的路由器,好比咱们一些机器不容许访问外网,这个时候若是访问的ip是一个外网ip(不管是否存在),这个时候也会立刻返回获得一个Network is unreachable的错误,不须要等待。 20180108: g_trash_stack_push会破坏存到栈里面的内容 20180110: 经验:多磁盘系统可能出现热点磁盘,能够考虑使用条带化使得文件系统均匀分布 20180112: Linux堆栈是向下扩展的,因此若是出现数组写越界,破坏数组变量以前定义的一个变量的内容。(可是同一个结构体里面则是按声明顺序从小到大分配空间) 20180115: 网络编程时,服务器接收数据须要防止客户端发送数据不完整。最好让客户端在发送数据前先发送包长度。 20180116: linux下,select函数超时后会修改入参struct timeval参数,须要重置成须要的超时时间 读取文件尾部: if (0 > (fd = open(strLogFile, O_APPEND | O_WRONLY | O_CREAT | O_TEXT, 0644))) 20180201: 若是出现退格键不能删除字符,终端显示不全等问题,通常能够观察是否stty参数设置异常:stty -a 20180228: 最近定位了系统传输给P9的数据出现入库失败的问题。 先说一下背景: 咱们数据库字符编码是GBK,P9数据库编码是UTF8。天天咱们系统有一些数据须要导出成文件,传给他们系统入库。 咱们作法是先导出GBK编码的文件再经过iconv转换成UTF8格式文件传给他们。 约定文件列分隔符是"|@|" 出现的问题: 因为某个库表有个字段长度不足,咱们入库时须要先substr再入库,致使有些数据出现半个中文问题。 这种数据导出到文件再用iconv转换成utf8格式时会把后面的竖线与半个中文合并成一个新的中文。 结果会致使转换后的数据缺失一列,对方系统入库失败。 解决方法: 字段导出时就转换成UTF8格式,若是碰上转换异常的字符忽略。 20180301: 今天一个网友系统短信验证码被刷了,虽然控制了ip和手机号码发送频率,可是仍是被人用n多肉鸡攻击。 当初项目上线为了用户体验,没有先验证图文验证码就直接发短信形成的祸端。 20180310: everything默认不搜索c盘,须要强制它搜索。工具->选项->索引->文件夹新增须要搜索的用户目录。 20180312: sqlplus的set term off能够不显示sql执行结果() 脚本 20180316: vim打开混合编码的文件,容易出现中文乱码的状况。能够强制vim把文件当成utf8格式打开:e ++enc=utf-8 20180318: 今天编译代码时报错,提示error C2065: “HANDLE_TIMEOUT”: 未声明的标识符。 但我明明在前面有定义HANDLE_TIMEOUT宏:#define HANDLE_TIMEOUT() 原觉得是编译器有bug,后来发现原来要用宏函数的写法才对:HANDLE_TIMEOUT(),我原来直接写了HANDLE_TIMEOUT 20180318: 今天用plsql同时执行多条insert语句时报错:ora-0091 无效字符 后来我把语句先后厍上BEGIN和END;就能够了 20180319: select返回可读,但recv返回0,这种状况通常是由于对方关闭socket 20180322: sourceinsight在括号前双击能够快速跳转到对应的另外一个括号位置。 20180408: release版本 gdb看不出来 加上-g从新编译 20180410: 今天发现一个命令ss,听说比netstat快不少。netstat -anp <=> ss -tanp ue高亮单词的方法: shift + 双击单词 20180411: 今天有同事说忽然登陆不了oracle,使用sqlplus user/pwd@dbname报错:“ora-12154: tns:could not resolve the connect identifier specified”,让我帮他看一下。 我过去他机器执行tnsping dbname,提示"tns-12533: tns:illegal address parameters",感受是tns没配置好。可是查看tns配置${ORACLE_HOME}/network/admin/tnsnames.ora,里面的配置没问题。 后来才发现昨天有人在.profile设置了TNS_ADMIN,把tns配置指向了另外一个目录,那里面tns配置错了。我以前没检查这个变量,查看了默认目录${ORACLE_HOME}/network/admin/,因此没找出缘由。 20180412: 今天用sftp上传文件时报错"fail to upload failure",觉得是文件有问题,查了半天没发现。后来发现原来是目标机器硬盘空间满了。 今天有gdb调试程序,学习了几个技巧: 1 调试机器源码目录与编译机器源码目录不一样,能够用set substitutes-path /xxa /xxb指示gdb到指定目录找源码文件。 .gdbinit set auto-load safe-path / print命令能够修改变量值,用法: print x=4 使用watch命令可让gdb在变量被修改时自动断点:watch *(char *)addr2line 20180413: 今天发现有同事在.h里面修改告终构体定义,但没有相应的编译全部.c。致使运行时出现内存越界。 把程序make clean后从新编译就行了。 这个问题确实比较难解决,由于写makefile时很差肯定每一个.c依赖于哪些.h 今天写了一个将/proc下面程序环境变量文件转成export语句的脚本 cat environ | tr '\0' '\n' | awk -F '=' '{ printf("export %s=%c%s%c\n", $1, 39, $2, 39); }' #39是单引号的asscii码 20180414: 后来发现原来delete * from tab;也会形成高水位。以前觉得只是有条件的delete会形成高水位。 oracle对于每一个数据段(能够简单理解为每一个表)都有一个高水位(hwm)标记使用空间上限。hwm默认状况只会增大,不会减小。 因此若是出现插入大量数据,而后又删除大量数据的表,会出现高水位远超过实际数据占用空间的状况。 而数据库作全表扫描时会扫描高水位下面全部数据,这就会致使有时表的数据不多,但查询起来仍然很慢的状况。 20180416: http常见标准错误400 因为语法格式有误,服务器没法理解此请求。404 Web 服务器找不到您所请求的文件或脚本。 20180417: 今天使用windows上的awk程序输出中文到屏幕时发现问题: 1 使用print输出字符串时,若是字符串有中文,会报错fatal: print to "standard output" failed (Invalid argument) 2 使用printf输出字符串时,若是字符串有中文,会报错fatal: printf to "standard output" failed (Bad file descriptor) 解决方法是不直接把awk运行结果输出到屏幕,使用重定向输出到txt文本,就不会报错了。 20180419: vs2015编译有utf8的源码时,须要在文件头添加BOM,不然会报错 20180424: C语言某些宏在宏里面写死了变量名,致使没法使用不一样名称的变量调用该宏 例以下面这个宏,强制要求使用变量名称txnJnl,若是想使用变量名txnJnl_realName则会调用失败 #define XML_TO_JNL(IDX) \ do { \ nRc = XmlIpc2St(&txnJnl, X2S(IDX));\ if (nRc) return nRc;\ } while(0) 对于这种状况c++可使用引用改变变量名,在c则可使用下面的编码技巧曲线救国 #define txnJnl txnJnl_realName REQ_XML_TO_JNL(X2S_REVERSALAUTHREQ2ONLJNL); #undef txnJnl 但最好仍是推荐在写宏时参数带上变量名 #define REQ_XML_TO_JNL(txnJnl,IDX) \ do { \ nRc = XmlIpc2St(&txnJnl, X2S(IDX));\ if (nRc) return nRc;\ } while(0) 这样才符合高内聚低耦合的设计原则。