ARP单播问题
虚拟机桥接到宿主机的网卡,虚拟机访问宿主机时有如下arp包:
说明:
arp查询之后会在本地缓存一段时间,当缓存超过一段时间后,可能实际信息已发生变化,于是发送一个单播的arp查询请求校验一下;话说既然可能会失效了,那么删掉重新查一次不行吗?
正常的arp请求是不知道某IP在哪里,只好广播,谁是谁响应;由于广播的开销比较大,所以,当我知道很有可能某IP就在你那里的话,我不妨先发个单播包校验一下,如果确实发生变化了,就再发送广播包不迟
DevOps
虚拟机桥接到宿主机的网卡,虚拟机访问宿主机时有如下arp包:
说明:
arp查询之后会在本地缓存一段时间,当缓存超过一段时间后,可能实际信息已发生变化,于是发送一个单播的arp查询请求校验一下;话说既然可能会失效了,那么删掉重新查一次不行吗?
正常的arp请求是不知道某IP在哪里,只好广播,谁是谁响应;由于广播的开销比较大,所以,当我知道很有可能某IP就在你那里的话,我不妨先发个单播包校验一下,如果确实发生变化了,就再发送广播包不迟
当我们strace -c pid的时候,经常会发现futex占用大量时间,如下图:
那么, futex究竟是个什么东西呢?
futex – Fast Userspace Locking system call
一般来讲,futex是用于多线程程序中线程同步使用的; futex本身不是一个锁,但是可以利用这个机制实现锁。
传统的多线程同步是这样的(不保证说的对):
请求锁:
成功 –>干活 –> 干完 –> 发送信号给要加锁的线程
失败 –> 睡眠–> 收到信号–>继续请求锁
futex类似这样:
1 2 3 |
void waitUntilNotEqual(volatile int* addr, int value) { while (*addr == value) {} } |
在我们使用strace的时候,经常会遇到如下情景:
你们 restart_syscall 究竟是个什么系统调用呢?什么时候会用到该系统调用呢?
一般情况下,如果遇到这种情况,那么使用pstack看看进程的调用栈,会发现,很可能该进程处于sleep状态。
下面有一个实验:
1 |
strace php -r 'sleep(5);' |
回车之后,当看到nanosleep({5, 0}, 立即ctrl-z,会发现程序stop了, 然后,输入 fg(切换后台任务到前台,继续运行),这时,又一次看到了restart_syscall 了,如下:
或许可以这么解释: 当程序收到一个信号时,离开正在执行的系统调用去处理信号,处理完信号(上面是直到收到一个sigcont信号才算处理完上刚才的信号),继续执行运来的系统调用,似乎就是通过restart_syscall 这个系统调用进入未完的那个系统调用的,所以说,看到restart_syscall意味着刚才的系统调用没有完成的时候被迫去做别的了;
为什么strace一个sleep的进程总会看到这个呢?
strace本身是先给正在执行的进程发了个信号(什么信号?….然后….),再然后发送SIGCONT信号让程序继续执行,于是,程序进入restart_syscall ; 当然,不是所有系统调用可以中断的,也不是所有系统调用中断后都能restart的,参考: man strace
总结:
参考资料: https://www.quora.com/What-are-the-use-cases-of-restart_syscall-system-call-on-Linux-Systems
linux源码在线看: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/
gdb对python的调试支持还是比较成熟的,如果gdb版本(>7)够高的话,gdb默认编译了对python的支持,可以直接:
1 |
gdb -p pid_of_python |
当然,需要先安装对应版本的python-debuginfo
参考资料:
1. http://www.cnblogs.com/dkblog/p/3806277.html 这里的libpython.py 可能并不需要
2.
mysql导出导入大数据文件时,如果文件很大,导入时最好先把索引都去掉,如果导出时包含表结构,则在一个很大的文件上编辑表结构将非常麻烦,所以正确的做法:
1. 导出表结构(不包含数据)
1 |
mysqldump -d dbname tablename >tablename-schema.sql |
2. 编辑表结构(去掉索引)
3. 创建表
1 |
cat tablename-schema-no-index.sql|mysqldump dbname |
4. 导出表数据 (不包含表结构)
1 |
mysqldump -t dbname tablename >tablename-data.sql |
5. 导入数据
1 |
cat tablename-data.sql|mysqldump dbname |
6. 添加索引
附:
解压大文件直接到mysql:
1 |
tar -zxf bigfile.sql.tgz -O |mysql |
如何知道灌到什么程度了?
tar 在解压的时候,使用的也是外部的解压程序(如:gzip),通过管道交互,可以查看gzip读的那个文件读到哪里了,如:
1 |
cat /proc/pid_of_gzip/fdinfo/0 |
vagrant package 有两种方式,一种基于虚拟机名字的,一种基于vagratfile的。
对于自己安装的虚拟机,如果已经在使用privatekey的方式在登录了,那么package的时候,虽然该privatekey也能被打包,但是会认为该privatekey是打包的人提供的,不够安全,所以,会认为
正确的打包方式:
(尽管如此,使用同一个box的人使用的秘钥不还是一样的吗?不还是不安全的吗?暂且不管这么多了,至少每次启动新的虚拟机都能正常进入并完成初始设置)
使用该box启动新的虚拟机:
可见,该虚拟机有自己的private_key了
就算打包的时候没有重新生成privatekey,如果在创建虚拟机的vagrantfile中指定了ssh的用户名密码,在启动虚拟机的时候,也能自动删掉不安全的privatekey,并且自动写入一个新生成的privatekey,如下:
查看ssh-config:
可见,私钥写在了自己的目录下了(但是,这里还证明不了pubkey确实从guest中移除了,至少现在在guest中有两个pubkey)
如果在vagrant up的时候,由于某种原因没有能Insert一个安全的密码,在问题解决后,即使是在vagrant halt,如果发现存在不安全的key,也会即使更新能安全的key的:
关键点: 每次打包的时候,vagrantfile中指定用户名和密码
privatekey是否安全似乎是根据privatekey文件名判断的,后来打包的时候也没有重新生成privatekey
正解:
关键是,折腾了好几天,原来的镜像又好使了,啥问题没发现,xxx
注: virtualbox的动态磁盘一旦被撑大就回不去了,打包后的vbox,压缩也压缩不了
最初学习C语言的时候,只能在控制台上输出一些东西,和windows相比感觉非常的不实用,虽然也看见过一些程序能在控制台上输出炫酷的颜色的动画,但是基本语法还掌握不牢的时候,这样的程序也只能是欣赏一下,不敢想象自己去写这样的程序,后来也没再有机会研究这方面的东西。
今天,觉得控制台上输出只能顺序输出,最多也就是通过 \b 回退,不过这个回退也不过回退到行首,还有,虽然可以通过 \v 直接跳到下一行,但是:如何回退上上一行呢?如何在屏幕上指定坐标输出呢?
且看下面这个shell:
1 |
while sleep 1;do tput sc;tput cup 0 $(($(tput cols)-29));date;tput rc;done |
可以在控制台的右上角显示系统时间;
可见tput这个东西可以定位光标位置,那么tput是个什么东西呢?
其实,常用的clear命令就属于ncurses包
把ncureses-devel开发包安装一下就可以开发了; 文档: http://download.csdn.net/detail/Kevinxtq/1063483。该库方便开发terminal程序,当然没有该库也能做简单的光标定位,如:
1 |
echo -e "\e[31;46m\e[0;78HHello World\e[40;37m" |
在0行78列输出一个醒目的Hello World; 但是我不知道如何让光标回到原来的位置。
python 的snack模块就可以用于开发控制台窗口应用: http://www.wanware.com/tsgdocs/snack.html linux上认证方式配置程序: authconfig-tui 就是使用python借助snack来实现的
php 也有ncurses的封装: http://php.net/manual/en/book.ncurses.php
实例:
https://devzone.zend.com/173/using-ncurses-in-php/
https://github.com/PHPGangsta/PHP-NCurses-Example
安装: yum install php-pecl-ncurses
参考资料:
http://bbs.chinaunix.net/thread-4179287-1-1.html
http://www.cnblogs.com/Xiao_bird/archive/2009/07/21/1527947.html
1 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 |
#include<string> #include<iostream> using namespace std; class animal{ public: virtual void say()=0; virtual void run() { cout << "running" <<endl; } }; class dog:public animal{ public: void say() { cout<<"wang wang ..."<<endl; } virtual void run() { cout << "dog running" <<endl; } }; class jinmao:public dog{ public: void say() { cout << "I am jinmao, wang wang ..." <<endl; } void run() { cout << "jinmao running" <<endl; } }; void say(animal *a){ a->say(); } void run(animal *a){ a->run(); } void dog_run(dog *d){ d->run(); } int main(){ say(new dog()); say(new jinmao()); run(new dog()); run(new jinmao()); dog_run(new jinmao()); return 0; } |
多态玩的就是虚
什么是多态?
函数的形参中定义基类的情况,当然,这里的基类不一定是爷爷类,父亲类也可以,当实际调用时传递的如果是子类,那么,运行时会检查要调用的类的方法在基类(因为形参是基类,所以要参考基类)中是否virtual的,如果不是virtual的,则直接执行基类中的定义(即使当前确实是子类的实例,也不会执行子类的该方法,换言之,就是不允许覆盖,这就是virtual存在的意义,某些语言是直接覆盖的,没法选择不覆盖),如果是virtual的,则根据继承链向下检查,直到查到该方法的最后一个实现,哪怕继承链中的某些子类没有明确写virtual关键字也没关系(换言之,virtual属性是自动、强制继承的,或者说,dog类中的run方法的virtual关键字是多余的);具体实现上可能不是一个一个查,但至少逻辑上是这样的; 如果animal类的run方法不是virtual的,并不意味着子孙类的run方法再也不能添加virtual了,比如:animal的run没有virtual,dog的run使用了virtual,则run(animal *a)函数只能执行animal类中的run,而dog_run(dog *d) 却可以多态, 即: dog_run(new jinmao()) 时打印金毛的跑法
就是允许覆盖,多态的实现方式
就是没有函数的定义,只有声明,子类想不覆盖都不行,除非子类自己不创建对象,期待孙类的继承;
语法上来讲,函数不定义是不行的,但是纯虚函数就是不定义,所以必须明确说明不定义,即: =0 ,如下: (没有 =0 是不行的)
1 |
virtual void say()=0; |
c++中没有抽象类,也没有接口,更没有abstract、interface、implements等关键字,有的只有class和virtual
如果一个类中包含了纯虚函数,则该类自然为抽象类;
如果一个类中只包含纯虚函数,则该类相当于接口;
50款JavaScript图表库分享:
http://my.oschina.net/u/935975/blog/220987
纯文本流程图: http://my.oschina.net/iamancoder/blog/652233
13个JavaScript图表(JS图表)图形绘制插件:
http://blog.jobbole.com/13671/
js版的visio: http://demo.qunee.com
js通过数据生成流程图: http://my.oschina.net/blogshi/blog/221749
d3: https://github.com/cpettitt/dagre-d3 功能上来看,基本是dotgraph的js实现
js写的国际象棋: http://www.jointjs.com/demos/chess