<commit_before># **Skills(小技巧)** #
***
    主要记录了各种编程的小技巧或者小知识点


## **1. 函数调用约定(MSVC)** ##
        int add(int a,  int b)  
        {  
          return a + b;  
        }  

        函数调用约定是, 主调和被调函数之间的协议, 约定函数参数以什么顺序依次
    压栈, 以及函数结束后由谁来完成对入栈参数的清理(清栈)
> ### **1.1 __cdecl调用约定** ###
    1) 函数的参数从右到左依次压栈
    2) 函数的调用者在push参数, 调用add之后(add esp 8), 来平衡栈帧
    3) 由函数的调用者来平衡栈帧
    4) 函数中只有简单的(ret 0), 将清栈的操作交由函数的调用者来完成 

> ### **1.2 __stdcall调用约定** ###
    1) 函数的参数从右到左依次压栈
    2) 函数的调用者只是在push参数后直接盗用add
    3) 由函数自己类平衡栈帧
    4) 函数体自身有(ret 8)来平衡栈帧

> ### **1.3 具体的流程请查看例子** ###
    1) 以__cdecl调用约定编译后的函数为_add
    2) 以__stdcall调用约定编译后的函数为_add@8 (_函数名@参数的总字节数)
    3) 参见例子 ./call-convention/main.c 



## **2. 编译时候指定任意后缀的文件** ##
> ### **2.1 引子** ###
        查看STLport的源代码的时候发现有.c后缀的文件, 单文件中使用的是C++语法
    , 感到很奇怪。后来一想, 其实文件的后缀在*nix系统下是没有意义的, 所以猜想
    编译器定有什么编译选项可以指定任意格式的文件。

> ### **2.2 内幕** ###
    1) MSVC下有个编译选项/Tp, 指定文件按C++编译
    2) MSVC下有个编译选项/Tc, 指定文件按C编译
    3) GCC下有个编译选项 -x language, 可以在language指定具体文件 



## **3. git配置** ##
> ### **3.1 配置颜色** ###
    1) 常用的颜色:  
       git config --global color.branch auto  
       git config --global color.diff auto  
       git config --global color.interactive auto  
       git config --global color.status auto  
    2) 把颜色全部都打开: 
       git config --global color.ui true
> ### **3.2 编辑器配置** ###
    git config --global core.editor 'vim'
> ### **3.3 配置用户信息** ###
    git config --global user.name "your name"
    git config --global user.email <EMAIL>
> ### **3.4 一个git配置例子** ###
    [color]
      ui = true
    [core]
      editor = vim
    [user]
      name = ASMlover
      email = <EMAIL>
    [pretty]
      graph = %Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset
    [alias]
      lg = log --pretty=graph --graph --abbrev-commit --
   

## **4. 好玩儿** ##
> ### **4.1 一行代码将浏览器变为记事本** ###
    1) 在浏览器地址栏输入: 
       data:text/html, <html contenteditable>
    2) 由这一行代码引起的头脑风暴, [请查看](http://www.oschina.net/news/37360/one-line-code-online-editor)



## **5. Windows路径转换** ##
> ### **5.1 在命令行下从一个地方转到另一个地方** ###
        假定当前所在的位置是(C:\>), 现在需要直接转换到其他地方, 如果是在同一
    个驱动器下, 直接cd转换即可; 但是当在其他的驱动器(D:\demo\)的时候, 我们需
    要使用其他方法:
        1) C:\> cd /d D:\demo 
        2) pushd D:\demo 
        3) 方法1是直接跳转, 在返回的时候不容易; 方法二跳转后可以使用popd返回
> ### **5.2 命令行下打开窗口目录** ###
        在命令行下有时需要进入图形窗口目录查看, 我们可以使用explorer命令来完
    成该任务, 假设当前位置是(C:\>), 我们要进入(D:\demo):
        C:\> explorer D:\demo 



## **6. 新安装的动态库在系统中找不到(Linux)** ##
        下面的例子以libzmq为例, 系统中新安装了libzmq的动态库到/usr/local/lib
    下, 但是在程序运行的时候却不能加载;
        可以使用 sudo /sbin/ldconfig -v | grep libzmq来检查系统, 如果没有出
    现下面的内容:
        libzmq.so.1 -> libzmq.so.1.0.1
        则需要在/etc/ld.so.conf文件的最后一行加上 /usr/local/lib/ 

        另外新安装的共享库, 找不到的情况下还需要运行sudo ldconfig来配置动态
    库的环境




## **7. 玩家二进制数据升级的问题** ##
    当涉及玩家的二进制数据升级的时候, 可以对玩家的数据打上版本的标记, 升级的
    时候直接写两套代码分别处理不同版本的数据信息;
    这样就可以处理不管是在数据结构的尾部增加还是在中间增加的玩家数据了;



## **8. 网络库Message Queue设计** ##
    可以设计两个队列, 各个工作线程将读取的数据推送到一个队列, 然后逻辑主线程
    再从另外一个线程读取消息数据信息;
    读取的数据信息可以直接设计成buffer即可, 这样每次读取数据信息的时候直接根
    据读取位置读取数据信息即可, 这样就可以避免频繁的申请释放内存了;
    两个数据队列直接采用无锁队列即可;
    
    读取的队列无锁, 网络处理线程读取的数据加锁写入写队列, 两个队列互相交换;
    1. 读优先 - 监测到读队列为空, 翻转两个队列
    2. 写优先 - 写队列满了之后再翻转两个数据队列
    3. 如果读队列中的数据没有取完, 而写队列满的情况, 后续来的数据丢掉



## **9. MySQL datetime转换为time_t** ##
> ### **在MySQL中转换**
    SELECT UNIT_TIMESTAMP(`time`) FROM `table_name`;
> ### **C++中转换**
    其实就是字符串类型的time转换为time_t类型, 可以先转换成tm结构再转换成
    time_t的数值类型;
    struct tm tm_out;
    strptime(src_time_str, "%Y-%m-%d %H:%M:%s", &tm_out);
    time_t t = mktime(&tm_out);
<commit_msg>add C++ information in linux platform<commit_after># **Skills(小技巧)** #
***
    主要记录了各种编程的小技巧或者小知识点


## **1. 函数调用约定(MSVC)** ##
        int add(int a,  int b)  
        {  
          return a + b;  
        }  

        函数调用约定是, 主调和被调函数之间的协议, 约定函数参数以什么顺序依次
    压栈, 以及函数结束后由谁来完成对入栈参数的清理(清栈)
> ### **1.1 __cdecl调用约定** ###
    1) 函数的参数从右到左依次压栈
    2) 函数的调用者在push参数, 调用add之后(add esp 8), 来平衡栈帧
    3) 由函数的调用者来平衡栈帧
    4) 函数中只有简单的(ret 0), 将清栈的操作交由函数的调用者来完成 

> ### **1.2 __stdcall调用约定** ###
    1) 函数的参数从右到左依次压栈
    2) 函数的调用者只是在push参数后直接盗用add
    3) 由函数自己类平衡栈帧
    4) 函数体自身有(ret 8)来平衡栈帧

> ### **1.3 具体的流程请查看例子** ###
    1) 以__cdecl调用约定编译后的函数为_add
    2) 以__stdcall调用约定编译后的函数为_add@8 (_函数名@参数的总字节数)
    3) 参见例子 ./call-convention/main.c 



## **2. 编译时候指定任意后缀的文件** ##
> ### **2.1 引子** ###
        查看STLport的源代码的时候发现有.c后缀的文件, 单文件中使用的是C++语法
    , 感到很奇怪。后来一想, 其实文件的后缀在*nix系统下是没有意义的, 所以猜想
    编译器定有什么编译选项可以指定任意格式的文件。

> ### **2.2 内幕** ###
    1) MSVC下有个编译选项/Tp, 指定文件按C++编译
    2) MSVC下有个编译选项/Tc, 指定文件按C编译
    3) GCC下有个编译选项 -x language, 可以在language指定具体文件 



## **3. git配置** ##
> ### **3.1 配置颜色** ###
    1) 常用的颜色:  
       git config --global color.branch auto  
       git config --global color.diff auto  
       git config --global color.interactive auto  
       git config --global color.status auto  
    2) 把颜色全部都打开: 
       git config --global color.ui true
> ### **3.2 编辑器配置** ###
    git config --global core.editor 'vim'
> ### **3.3 配置用户信息** ###
    git config --global user.name "your name"
    git config --global user.email <EMAIL>
> ### **3.4 一个git配置例子** ###
    [color]
      ui = true
    [core]
      editor = vim
    [user]
      name = ASMlover
      email = <EMAIL>
    [pretty]
      graph = %Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset
    [alias]
      lg = log --pretty=graph --graph --abbrev-commit --
   

## **4. 好玩儿** ##
> ### **4.1 一行代码将浏览器变为记事本** ###
    1) 在浏览器地址栏输入: 
       data:text/html, <html contenteditable>
    2) 由这一行代码引起的头脑风暴, [请查看](http://www.oschina.net/news/37360/one-line-code-online-editor)



## **5. Windows路径转换** ##
> ### **5.1 在命令行下从一个地方转到另一个地方** ###
        假定当前所在的位置是(C:\>), 现在需要直接转换到其他地方, 如果是在同一
    个驱动器下, 直接cd转换即可; 但是当在其他的驱动器(D:\demo\)的时候, 我们需
    要使用其他方法:
        1) C:\> cd /d D:\demo 
        2) pushd D:\demo 
        3) 方法1是直接跳转, 在返回的时候不容易; 方法二跳转后可以使用popd返回
> ### **5.2 命令行下打开窗口目录** ###
        在命令行下有时需要进入图形窗口目录查看, 我们可以使用explorer命令来完
    成该任务, 假设当前位置是(C:\>), 我们要进入(D:\demo):
        C:\> explorer D:\demo 



## **6. 新安装的动态库在系统中找不到(Linux)** ##
        下面的例子以libzmq为例, 系统中新安装了libzmq的动态库到/usr/local/lib
    下, 但是在程序运行的时候却不能加载;
        可以使用 sudo /sbin/ldconfig -v | grep libzmq来检查系统, 如果没有出
    现下面的内容:
        libzmq.so.1 -> libzmq.so.1.0.1
        则需要在/etc/ld.so.conf文件的最后一行加上 /usr/local/lib/ 

        另外新安装的共享库, 找不到的情况下还需要运行sudo ldconfig来配置动态
    库的环境




## **7. 玩家二进制数据升级的问题** ##
    当涉及玩家的二进制数据升级的时候, 可以对玩家的数据打上版本的标记, 升级的
    时候直接写两套代码分别处理不同版本的数据信息;
    这样就可以处理不管是在数据结构的尾部增加还是在中间增加的玩家数据了;



## **8. 网络库Message Queue设计** ##
    可以设计两个队列, 各个工作线程将读取的数据推送到一个队列, 然后逻辑主线程
    再从另外一个线程读取消息数据信息;
    读取的数据信息可以直接设计成buffer即可, 这样每次读取数据信息的时候直接根
    据读取位置读取数据信息即可, 这样就可以避免频繁的申请释放内存了;
    两个数据队列直接采用无锁队列即可;
    
    读取的队列无锁, 网络处理线程读取的数据加锁写入写队列, 两个队列互相交换;
    1. 读优先 - 监测到读队列为空, 翻转两个队列
    2. 写优先 - 写队列满了之后再翻转两个数据队列
    3. 如果读队列中的数据没有取完, 而写队列满的情况, 后续来的数据丢掉



## **9. MySQL datetime转换为time_t** ##
> ### **在MySQL中转换**
    SELECT UNIT_TIMESTAMP(`time`) FROM `table_name`;
> ### **C++中转换**
    其实就是字符串类型的time转换为time_t类型, 可以先转换成tm结构再转换成
    time_t的数值类型;
    struct tm tm_out;
    strptime(src_time_str, "%Y-%m-%d %H:%M:%s", &tm_out);
    time_t t = mktime(&tm_out);



## **10. g++编译C++11** ##
    需要加上编译选项-std=c++0x
> ### **常用的C++11特性**
    1. shared_ptr
        在<memory>头文件中, 在命名空间std下面;

{'fraction_non_alphanumeric': 0.15718745758110492, 'fraction_numerical': 0.02036106963485815, 'mean_word_length': 2.717457114026236, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2175550', 'n_tokens_mistral': 4560, 'n_tokens_neox': 5135, 'n_words': 575}