<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>kamuszhou&#39;s blog</title>
    <link>https://ykyi.net/</link>
    <description>Recent content on kamuszhou&#39;s blog</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Tue, 06 Jun 2023 10:21:03 +0000</lastBuildDate>
    <atom:link href="https://ykyi.net/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Sample Page</title>
      <link>https://ykyi.net/sample-page/</link>
      <pubDate>Tue, 06 Jun 2023 10:21:03 +0000</pubDate>
      <guid>https://ykyi.net/sample-page/</guid>
      <description>&lt;p class=&#34;wp-block-paragraph&#34;&gt;
  This is an example page. It&amp;#8217;s different from a blog post because it will stay in one place and will show up in your site navigation (in most themes). Most people start with an About page that introduces them to potential site visitors. It might say something like this:
&lt;/p&gt;
&lt;blockquote class=&#34;wp-block-quote is-layout-flow wp-block-quote-is-layout-flow&#34;&gt;
  &lt;p&gt;
    Hi there! I&amp;#8217;m a bike messenger by day, aspiring actor by night, and this is my website. I live in Los Angeles, have a great dog named Jack, and I like pi&amp;#241;a coladas. (And gettin&amp;#8217; caught in the rain.)
  &lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>调研号称最快的快速傅里叶变换库fftw</title>
      <link>https://ykyi.net/?p=1769/</link>
      <pubDate>Fri, 13 May 2022 04:04:24 +0000</pubDate>
      <guid>https://ykyi.net/?p=1769/</guid>
      <description>&lt;p&gt;调研主流开源fft c/c++库，最后选择了最为知名的fftw项目。 读完了官方最新版手册的大部分内容。和当前项目使用的简单实现做bechmarking，fftw的速度在我的测试环境中比简单实现快30~40倍。 测试环境: AMD 4G主频&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;44.1K采样10分钟&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;44.1K采样1分钟&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;44.1K采样10秒&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;简单实现&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;2.01017秒&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;0.203767秒&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;0.037936秒&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;fftw&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;0.047039秒&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;0.00466秒&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;0.001126秒&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;summary&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;42.3倍&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;43.7倍&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;33.7倍&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;帧长都是1024, 帧跳512。&lt;/p&gt;
&lt;p&gt;虽然fftw的性能领先得非常地明显，但如果每一分钟左右，甚至更短的时间就计算一次，简单fft也能在一秒钟内完成。看来fft并非主要耗时部分。这次调研fft算法更新了我对fft的看法。我印象中FFT仅管是快速算法，仍然非常耗时，所以才需要DSP芯片。看来现在的通用CPU亦能应付大部分场景。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux下接链Matlab的库，它们在哪里～</title>
      <link>https://ykyi.net/?p=1763/</link>
      <pubDate>Thu, 03 Mar 2022 08:21:26 +0000</pubDate>
      <guid>https://ykyi.net/?p=1763/</guid>
      <description>&lt;p&gt;这篇短博客就记一下matlab把库文件放哪～&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: center&#34;&gt;64-bit Apple Mac&lt;/th&gt;
					&lt;th&gt;64-bit Linux&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: center&#34;&gt;matlabroot/bin/maci64:matlabroot/sys/os/maci64&lt;/td&gt;
					&lt;td&gt;matlabroot/bin/glnxa64:matlabroot/sys/os/glnxa64&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;mac用的是名字是maci64， linux用的名字是glnxa64。&lt;br&gt;
好奇怪的名字, glnxa ? 是不是 Gnu LiNuX Archives 的缩写呢？google了一会儿没找到答案。&lt;/p&gt;</description>
    </item>
    <item>
      <title>用FFmpeg5.0 &#43; SDL3 播放视频</title>
      <link>https://ykyi.net/?p=1755/</link>
      <pubDate>Tue, 15 Feb 2022 02:23:38 +0000</pubDate>
      <guid>https://ykyi.net/?p=1755/</guid>
      <description>&lt;p&gt;上个月看完了讲H.264视频编解码的经典书：“The H.264 Advanced Video Compression Standard”，看完后感觉也不是那么难。记得大约十年前第一次看到预测(prediction), 运动补偿(motion compensation)之类的术语和示意图，感觉是非常晦涩难懂的知识。而现在补了基础信号理论的知识，也扫除了很多畏难心理。&lt;/p&gt;
&lt;p&gt;后来了解到比较常用的开源H.264编码器是X264，而FFmpeg则自带一个广泛使用的开源H.264解码器。于是，我就想对照着开源代码，再过一遍理论知识。那就选FFmpeg吧～毕竟名气太大。&lt;/p&gt;
&lt;p&gt;首先，得用FFmpeg整一个简单的播放器跑起来才能调试。但是，网络上虽然有大量FFmpeg编写简单播放器的代码，绝大部分代码却是无法用最新的FFmpeg通过编译的。毕竟FFmpeg在持续开发中，连上层API也会有变化。我下载了目前(2022/Feb/13)最新的代码，版本号是5.0。旧FFmpeg播放器代码跑不起来。&lt;/p&gt;
&lt;p&gt;好在我在youtube.com上找到一位FFmpeg核心维护者Matt Szatmary做的presentation，&lt;a href=&#34;https://www.youtube.com/watch?v=1aEinrlyp8w&amp;amp;list=PLxbPHSSMPBeicXAHVfyFvGfCywRCq39Mp&#34;&gt;An Introduction to Building tools with FFmpeg libraries and APIs – Matt Szatmary | August 2019&lt;/a&gt;{.wp-editor-md-post-content-link}，结合它的介绍，把简单的播放功能跑起来了。这里有个小遗憾没能找到Matt Szatmary的源代码，虽然他在视频中说是开源的。本来还想学习一下大佬的写法。&lt;/p&gt;
&lt;p&gt;代码贴在这里。用这个小DEMO可以用调试器跟到FFmpeg的代码里看H264解码器的具体实现了。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-C &#34;&gt;#include &amp;lt;stdio.h&amp;gt;
#define __STDC_CONSTANT_MACROS
// Linux...
#ifdef __cplusplus
extern &#34;C&#34;
{
#endif
#include &amp;lt;libavcodec/avcodec.h&amp;gt;
#include &amp;lt;libavformat/avformat.h&amp;gt;
#include &amp;lt;libswscale/swscale.h&amp;gt;
#include &amp;lt;libavutil/imgutils.h&amp;gt;
#include &amp;lt;SDL2/SDL.h&amp;gt;
#ifdef __cplusplus
};
#endif

int sfp_refresh_thread(void *opaque);

// Refresh Event
#define SFM_REFRESH_EVENT (SDL_USEREVENT + 1)
#define SFM_BREAK_EVENT (SDL_USEREVENT + 2)
int thread_exit = 0;
int thread_pause = 0;

int sfp_refresh_thread(void *opaque)
{
    SDL_Event event;

    thread_exit = 0;
    thread_pause = 0;
    while (!thread_exit)
    {
        if (!thread_pause)
        {
            SDL_Event event;
            event.type = SFM_REFRESH_EVENT;
            SDL_PushEvent(&amp;event);
        }
        SDL_Delay(40);
    }
    thread_exit = 0;
    thread_pause = 0;
    // Break
    event.type = SFM_BREAK_EVENT;
    SDL_PushEvent(&amp;event);
    return 0;
}

int main(int argc, char *argv[])
{
    AVFormatContext *pFormatCtx;
    int i, videoindex;
    AVCodecParameters *pCodecPar;
    AVCodecContext *pCodecCtx;
    const AVCodec *pCodec;
    AVFrame *pFrame, *pFrameYUV;
    unsigned char *out_buffer;
    AVPacket *packet;
    int ret, got_picture;
    //------------SDL----------------
    int screen_w, screen_h;
    SDL_Window *screen;
    SDL_Renderer *sdlRenderer;
    SDL_Texture *sdlTexture;
    SDL_Rect sdlRect;
    SDL_Thread *video_tid;
    SDL_Event event;
    struct SwsContext *img_convert_ctx;
    char filepath[] = &#34;video&#34;;

    // avformat_network_init();
    // pFormatCtx = avformat_alloc_context();
    pFormatCtx = NULL;    // MYNOTE: if pFormatCtx is not allocated explicitly using avformat_alloc_context()
    // pFormatCtx will be allocated implicitly in avformat_open_input.
    if (avformat_open_input(&amp;pFormatCtx, filepath, NULL, NULL) != 0)
    {
        printf(&#34;Couldn&#39;t open input stream.\n&#34;);
        return -1;
    }
    if (avformat_find_stream_info(pFormatCtx, NULL) &amp;lt; 0)
    {
        printf(&#34;Couldn&#39;t find stream information.\n&#34;);
        return -1;
    }
    videoindex = -1;
    for (i = 0; i &amp;lt; pFormatCtx-&amp;gt;nb_streams; i++)
        if (pFormatCtx-&amp;gt;streams[i]-&amp;gt;codecpar-&amp;gt;codec_type == AVMEDIA_TYPE_VIDEO)
        {
            videoindex = i;
            pCodecPar = pFormatCtx-&amp;gt;streams[i]-&amp;gt;codecpar;
            break;
        }
    if (videoindex == -1)
    {
        printf(&#34;Didn&#39;t find a video stream.\n&#34;);
        return -1;
    }

    pCodec = avcodec_find_decoder(pCodecPar-&amp;gt;codec_id);
    if (pCodec == NULL)
    {
        printf(&#34;Codec not found.\n&#34;);
        return -1;
    }
    pCodecCtx = avcodec_alloc_context3(pCodec);
    if (!pCodecCtx)
    {
        fprintf(stderr, &#34;Could not allocate video codec context\n&#34;);
        exit(1);
    }
    // 这一步不能少，否则会崩溃。把CodecPar的参数再复制到codecCtx中
    ret = avcodec_parameters_to_context(pCodecCtx, pCodecPar);
    if (ret &amp;lt; 0)
    {
        printf(&#34;avcodec_parameters_to_context failed...&#34;);
        return -1;
    }
    // pCodecCtx = pFormatCtx-&amp;gt;streams[videoindex]-&amp;gt;codecpar;
    if (avcodec_open2(pCodecCtx, pCodec, NULL) &amp;lt; 0)
    {
        printf(&#34;Could not open codec.\n&#34;);
        return -1;
    }
    pFrame = av_frame_alloc();
    pFrameYUV = av_frame_alloc();
    size_t sz = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx-&amp;gt;width, pCodecCtx-&amp;gt;height, 1);
    out_buffer = (unsigned char *)av_malloc(sz);
    av_image_fill_arrays(pFrameYUV-&amp;gt;data, pFrameYUV-&amp;gt;linesize, out_buffer,
                         AV_PIX_FMT_YUV420P, pCodecCtx-&amp;gt;width, pCodecCtx-&amp;gt;height, 1);
    // Output Info-----------------------------
    printf(&#34;---------------- File Information ---------------\n&#34;);
    av_dump_format(pFormatCtx, 0, filepath, 0);
    printf(&#34;-------------------------------------------------\n&#34;);
    img_convert_ctx = sws_getContext(pCodecCtx-&amp;gt;width, pCodecCtx-&amp;gt;height, pCodecCtx-&amp;gt;pix_fmt,
                                     pCodecCtx-&amp;gt;width, pCodecCtx-&amp;gt;height, AV_PIX_FMT_YUV420P,
                                     SWS_BICUBIC, NULL, NULL, NULL);
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO |
                 SDL_INIT_TIMER))
    {
        printf(&#34;Could not initialize SDL - %s\n&#34;, SDL_GetError());
        return -1;
    }
    // SDL 2.0 Support for multiple windows
    screen_w = pCodecCtx-&amp;gt;width;
    screen_h = pCodecCtx-&amp;gt;height;
    screen = SDL_CreateWindow(&#34;Simplest ffmpeg player&#39;s Window&#34;,
                              SDL_WINDOWPOS_UNDEFINED,
                              SDL_WINDOWPOS_UNDEFINED,
                              screen_w, screen_h, SDL_WINDOW_OPENGL);
    if (!screen)
    {
        printf(&#34;SDL: could not create window - exiting:%s\n&#34;, SDL_GetError());
        return -1;
    }
    sdlRenderer = SDL_CreateRenderer(screen, -1, 0);
    // IYUV: Y + U + V (3 planes)
    // YV12: Y + V + U (3 planes)
    sdlTexture = SDL_CreateTexture(sdlRenderer,
                                   SDL_PIXELFORMAT_IYUV,
                                   SDL_TEXTUREACCESS_STREAMING, pCodecCtx-&amp;gt;width, pCodecCtx-&amp;gt;height);
    sdlRect.x = 0;
    sdlRect.y = 0;
    sdlRect.w = screen_w;
    sdlRect.h = screen_h;
    packet = (AVPacket *)av_malloc(sizeof(AVPacket));
    video_tid = SDL_CreateThread(sfp_refresh_thread, NULL, NULL);
    //------------SDL End------------
    // Event Loop
    for (;;)
    {
        char buf[1024];
        int ret;
        // Wait
        SDL_WaitEvent(&amp;event);
        if (event.type == SFM_REFRESH_EVENT)
        {
            while (1)
            {
                if (av_read_frame(pFormatCtx, packet) &amp;lt; 0)
                    thread_exit = 1;
                if (packet-&amp;gt;stream_index == videoindex)
                    break;
            }

            // ret = avcodec_decode_video2(pCodecCtx, pFrame, &amp;got_picture, packet);
            // ret = my_decode();
            ret = avcodec_send_packet(pCodecCtx, packet);
            if (ret &amp;lt; 0)
            {
                fprintf(stderr, &#34;Error sending a packet for decoding\n&#34;);
                exit(1);
            }

            while (ret &amp;gt;= 0)
            {
                ret = avcodec_receive_frame(pCodecCtx, pFrame);
                if (ret == AVERROR(EAGAIN))
                {
                    fprintf(stderr, &#34;EAGAIN occurred...\n&#34;);
                    break;
                }
                if (ret == AVERROR_EOF)
                {
                    printf(&#34;byebye...\n&#34;);
                    exit(0);
                }
                if (ret &amp;lt; 0)
                {
                    fprintf(stderr, &#34;Error during decoding\n&#34;);
                    exit(1);
                }

                printf(&#34;Got frame %3d\n&#34;, pCodecCtx-&amp;gt;frame_number);
                fflush(stdout);

                /* the picture is allocated by the decoder. no need to
                   free it */
                // snprintf(buf, sizeof(buf), &#34;%s-%d&#34;, &#34;player.c&#34;, dec_ctx-&amp;gt;frame_number);
                // pgm_save(frame-&amp;gt;data[0], frame-&amp;gt;linesize[0], frame-&amp;gt;width, frame-&amp;gt;height, buf);

                sws_scale(img_convert_ctx, (const unsigned char *const *)pFrame-&amp;gt;data,
                          pFrame-&amp;gt;linesize, 0, pCodecCtx-&amp;gt;height, pFrameYUV-&amp;gt;data, pFrameYUV-&amp;gt;linesize);
                // SDL---------------------------
                SDL_UpdateTexture(sdlTexture, NULL, pFrameYUV-&amp;gt;data[0],
                                  pFrameYUV-&amp;gt;linesize[0]);
                SDL_RenderClear(sdlRenderer);
                SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);
                SDL_RenderPresent(sdlRenderer);
                // SDL End-----------------------
            }

            // av_free_packet(packet);
            av_packet_unref(packet);
        }
        else if (event.type == SDL_KEYDOWN)
        {
            // Pause
            if (event.key.keysym.sym == SDLK_SPACE)
                thread_pause = !thread_pause;
        }
        else if (event.type == SDL_QUIT)
        {
            thread_exit = 1;
        }
        else if (event.type == SFM_BREAK_EVENT)
        {
            break;
        }
    }
    sws_freeContext(img_convert_ctx);
    SDL_Quit();
    av_frame_free(&amp;pFrameYUV);
    av_frame_free(&amp;pFrame);
    avcodec_free_context(&amp;pCodecCtx);
    avcodec_close(pCodecCtx);
    avformat_close_input(&amp;pFormatCtx);

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>adonisjs5的Ioc机制初探</title>
      <link>https://ykyi.net/?p=1733/</link>
      <pubDate>Mon, 20 Dec 2021 05:18:33 +0000</pubDate>
      <guid>https://ykyi.net/?p=1733/</guid>
      <description>&lt;h2 id=&#34;什么是ioc&#34;&gt;什么是Ioc&lt;/h2&gt;
&lt;p&gt;Ioc(Inversion of Control)是一种设计模式.它指的是使用某对象/资源的代码,不负责该对象的依赖对象的创建和维护,而交给一个专门的容器来负责.这样,怎么创建对象的控制权就转移到了这个专门的容器,即实现了所谓的控制反转.Ioc用来降低对象之间由依赖关系产生的耦合.（按照软件工程理论,依赖算是最弱的一种耦合了.依赖 &amp;lt; 关联 &amp;lt; 聚合 &amp;lt; 组合&amp;lt; 继承）我感觉,Ioc算是一个升级版的工厂模式,它管理了大量的工厂函数和对应的资源名称.可以把创建资源/对象的依赖写在Ioc里面.&lt;/p&gt;
&lt;h2 id=&#34;adonisjs5中的ioc&#34;&gt;adonisjs5中的Ioc&lt;/h2&gt;
&lt;p&gt;我感觉有点奇怪,adonisjs5的官方文档中没有专门提及Ioc. &lt;a href=&#34;https://docs.adonisjs.com/guides/introduction&#34;&gt;https://docs.adonisjs.com/guides/introduction&lt;/a&gt;{.wp-editor-md-post-content-link} 但在adonisjs4.x &lt;a href=&#34;https://legacy.adonisjs.com/docs/4.1/ioc-container&#34;&gt;https://legacy.adonisjs.com/docs/4.1/ioc-container&lt;/a&gt;{.wp-editor-md-post-content-link} 的官方文档中却有单独的一节来讲Ioc.以至于,我第一次读完adonis5的文档后,对Ioc竟然没什么印象.而Ioc却是adonis最为重要的概念.anyway~,看看adonis的源代码怎么处理Ioc吧.&lt;/p&gt;
&lt;h3 id=&#34;注册ioc&#34;&gt;注册Ioc&lt;/h3&gt;
&lt;p&gt;在adonisjs的代码中搜索一下,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;find node_modules/@adonisjs -iname &#34;*ioc*&#34;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;很容易发现adonisjs实现Ioc的代码在node_modules/@adonisjs/fold/build/src/Ioc/这个目录中.目录名就是Ioc,毫不掩饰自己的目的.&lt;br&gt;
逛一逛Ioc这个目录下的js文件,发现最重要的是index.js 和 binBindings.js这两个文件.其中index.js中有一个类就叫Ioc, 而注册到Ioc中的资源被放在Bindings.js文件中Bindings类中.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-javascript &#34;&gt;    /**
     * Define a binding
     */
    register(binding, callback, singleton) {
        this.list.set(binding, { callback, singleton });
        return this;
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Binding类中的register函数非常显眼.显然注册一个资源到Ioc的代码会走到这里.在这里下断点,调起调试器.发现register函数的三个参数的含义是： binding即资源的的namespace,通过调试器发现注册的第一个资源的namespace是“Adonis/Core/Application”；callback相当于创建这种资源的工厂函数,调用它即生产出一个对应的对象；而singleton则是一个boolean值,指示该种资源是不是一个单件.看看栈的上一个frame,是Ioc类的singleton()函数.看来,“Adonis/Core/Application”这个资源是通过Ioc.singleton()创建的.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-javascript &#34;&gt;    /**
     * Same as the [[bind]] method, but registers a singleton only. Singleton&#39;s callback
     * is invoked only for the first time and then the cached value is used
     */
    singleton(binding, callback) {
        helpers_2.ensureIsFunction(callback, &#39;&#34;ioc.singleton&#34; expect 2nd argument to be a function&#39;);
        this.bindings.register(binding, callback, true);
        return this;
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ioc.singleton()函数注释告诉我们.single()函数跟bind()函数一样,只不过是注册一个单件,单件的callback工厂函数仅调用一次.第一次创建会把资源cache起来,而后直接返回cache.这个cache即Bindings类中的list成员.虽然名字是list,但却是一个Map.映射namespace到对象/资源.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fiduccia Mattheyses算法(即FM算法)的论文解读</title>
      <link>https://ykyi.net/?p=1727/</link>
      <pubDate>Sat, 11 Dec 2021 15:35:42 +0000</pubDate>
      <guid>https://ykyi.net/?p=1727/</guid>
      <description>&lt;p&gt;kamuszhou的博客，转载请注明URL。&lt;/p&gt;
&lt;p&gt;现代大规模集成电路图（VLSI）非常庞大，当我们希望用多个FPGA仿真一个VLSI时，需要把VLSI在满足一些约束条件的情况下切割成多个小部分，每个部分都可以装进一个FPGA。&lt;/p&gt;
&lt;p&gt;这个问题抽象成数学模型，实际上就是一个超图分割的问题。在超图分割领域有一篇发表于1982年的论文，名字是”A Linear-Time Heuristic for Improving Network Partitions”。这篇论文提出了一种改进的“超图二分问题”算法，简称为FM算法。虽然在1982年这篇论文发表时，“超图分割”算法领域已经发展了近十年。但这篇论文似乎有着近乎祖师爷级论文的地位，相当多的后期该领域的论文都会引用这篇文章。论文发表之后该领域继续发展出的“层次化超图多分割”算法可以看成是FM算法发展而来。该算法中涉及到的概念和思路是后续算法的基础，是很好的该领域入门学习的资料。&lt;br&gt;
（更多超图及超图分割的基础概念请自行搜索，本博客主要解读论文）&lt;/p&gt;
&lt;p&gt;论文的下载地址：&lt;br&gt;
&lt;a href=&#34;https://ieeexplore.ieee.org/document/1585498&#34; title=&#34;https://ieeexplore.ieee.org/document/1585498&#34;&gt;https://ieeexplore.ieee.org/document/1585498&lt;/a&gt;{.wp-editor-md-post-content-link}&lt;/p&gt;
&lt;p&gt;在论文的摘要部分论述到：本文提出了一种启发式的，利用最小割(mincut)的迭代算法解决超图二分问题。该算法在最坏情况下的时间复杂度也是线性的。在实际应用中，绝大多数情况下，该算法都只需要很少次数的迭代。算法有三个特点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;超图被分成两个Block。每次移动一个结点把它从原来的Block移往另一个Block。同时维持两个Block的平衡。重要的是，这个平衡不是基于每个Block中的结点数量，而是更一般的size of block的概念，它考虑到了每个结点的权重是不一样的。&lt;/li&gt;
&lt;li&gt;利用一个相当高效的数据结构，可以在O(1)常数时间复杂度内找到需要移动的最佳结点。&lt;/li&gt;
&lt;li&gt;在移动了某个结点后，再高效地更新受上次移动影响的结点的信息(即论文后面会提到的结点的gain值)。这第三个特点亦在论文的Introduction中被再次提到，作者认为这是该论文的主要贡献(main contribution).&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;术语及基本概念&#34;&gt;术语及基本概念&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;n(i): 当i是超边的编号时，n(i)定义为每个超边上的结点数目。&lt;/li&gt;
&lt;li&gt;s(i)或p(i): 当i表示结点时，s(i)或p(i)表示结点上的PIN数目，即结点一共跟多个条超边有连接，更多时候亦称为结点的size。&lt;/li&gt;
&lt;li&gt;邻居结点： 如果两个结点至少能通过一条超边连接，即为邻居结点。&lt;/li&gt;
&lt;li&gt;A，B： 代表超图二分割后的两个BLOCK。&lt;/li&gt;
&lt;li&gt;｜A｜： $|A| = \sum_{i=i}^{n}{s(i)}$ 即Block A的size定义为Block A中所有的结点的size的连加。&lt;/li&gt;
&lt;li&gt;A(n)或B(n)： n表示编号为n的边，A(n)则表示该条n在Block A中的结点数。&lt;/li&gt;
&lt;li&gt;cut: 在A和B中都有结点的超边。&lt;/li&gt;
&lt;li&gt;cutstate: 一条超边是不是cut（后来发展成多分割问题中的cutsize）。&lt;/li&gt;
&lt;li&gt;cell gains: 当移动一个结点到另一个BLOCK时，cut减少的数目。&lt;br&gt;
&lt;img decoding=&#34;async&#34; src=&#34;http://supershell.cn/wp-content/uploads/2021/12/cell_gains.png&#34; alt=&#34;cell gains&#34; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;维持平衡&#34;&gt;维持平衡&lt;/h2&gt;
&lt;p&gt;最容易想到的是就是使超图二分割后的两个BLOCK中的结点数量大致相同。不过，可以稍微变复杂一点，即考虑每个结点的权重。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;W ＝ |A| + |B| 所有结点的size连加和&lt;/li&gt;
&lt;li&gt;r = |A| / (|A| + |B|) 一个大小0到1之间的比率&lt;/li&gt;
&lt;li&gt;smax = $\max_{1&amp;lt;i&amp;lt;n}{s(i)}$ 最大的结点size&lt;br&gt;
* rW – k ＊ smax &amp;lt;= |A| &amp;lt;= rW + k * smax；k &amp;gt; 1 平衡公式&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;公式不难，描述地很清楚。简单地讲，block的size考虑到了每个结点的权重不同。另外，允许每个block的size在满足比率r的附近上下浮动k个最大结点size。它的含义是，在刚好满足分割比率r的时候，还能够至少移动k个结点。&lt;/p&gt;</description>
    </item>
    <item>
      <title>如何知道gcc/g&#43;&#43; 的默认C&#43;&#43;版本</title>
      <link>https://ykyi.net/?p=1712/</link>
      <pubDate>Sun, 21 Nov 2021 12:48:51 +0000</pubDate>
      <guid>https://ykyi.net/?p=1712/</guid>
      <description>&lt;p&gt;C++在C++ 11之后在保持向后兼容的情况下，语法增强了非常多，变化很大。得益于Move语义，和一些标准库的改进（如std::list的size()函数在C++11之前是O(n)的复杂度，从C++11开始变成常数复杂度）。一些旧C++代码即使什么改动也不做，只需要在新的C++标准下编译，也能获得性能提升。一般要给g++开启C++11需要用 -std=c++11，开启C++17则是 -std=c++17。那么，如果不添加这些选项，gcc/g++默认使用的C++版本号是什么呢？&lt;/p&gt;
&lt;p&gt;如果你的gcc/g++版本号大于4.7的话，可以用如下命令获得默认c++版本。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;kamus@shyyp.net:~$ g++ --version | head -1
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
kamus@shyyp.net:~$ g++ -dM -E -x c++  /dev/null | grep -F __cplusplus
#define __cplusplus 201402L
kamus@shyyp.net:~$ gcc -dM -E -x c++  /dev/null | grep -F __cplusplus    ＃其实用gcc也可以
#define __cplusplus 201402L
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如上所示，我的g++版本是9.3.0。它的默认C＋＋版本是C＋＋14。&lt;br&gt;
这是我家用的电脑。我在公司的机器上运行结果如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;kamuszhou@centos ~ $ g++ --version | head -1
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
kamuszhou@centos~ $ g++ -dM -E -x c++  /dev/null | grep -F __cplusplus
#define __cplusplus 199711L
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如上所示，老版的g++ 4.8.4用的默认C++版本还是c++98&lt;/p&gt;</description>
    </item>
    <item>
      <title>安卓平台下面开发DSP应用</title>
      <link>https://ykyi.net/?p=1698/</link>
      <pubDate>Fri, 18 Jun 2021 01:24:40 +0000</pubDate>
      <guid>https://ykyi.net/?p=1698/</guid>
      <description>&lt;p&gt;这两天考察在手机上面写DSP应用的可能性，找了一些资料读了，有这些困难：&lt;/p&gt;
&lt;p&gt;安卓平台：&lt;br&gt;
谷歌有一个叫Oboe的C++库帮助开发音频APP，但是官方文档只提供了一些简单的例子，没有给出类似效果器之类有复杂数学运算的例子。我担心很多DSP运算的实时性得不到保证。&lt;/p&gt;
&lt;p&gt;得有DSP芯片的配合才能写出高效的DSP算法，虽然 arm CPU集成有DSP芯片，但是要充分利用DSP的指令，得用arm的付费编译器，据说挺贵的。而且，如果用DSP的指令优化算法，&lt;/p&gt;
&lt;p&gt;安卓碎片化的问题有更多的坑。如果用了非常底层的代码（直接写死了DSP的指令），代码在不同的机器上可能表现很不一样，很可能有些机器跑不起来。&lt;/p&gt;
&lt;p&gt;一篇2014年的技术文章 &lt;a href=&#34;https://www.androidauthority.com/state-audio-android-414978/&#34;&gt;https://www.androidauthority.com/state-audio-android-414978/&lt;/a&gt;{.wp-editor-md-post-content-link} 讲在android平台下面开发DSP的应用很困难。虽然是7年前的文章，但也很有参考价值。&lt;/p&gt;
&lt;p&gt;苹果iOS：&lt;br&gt;
苹果对DSP有很好的支持，但是我没有Mac电脑也没有iphone手机，没办法做开发。&lt;/p&gt;
&lt;p&gt;不过，有一个superepowered的开源库，声称完美提供了开发DSP的能力。但是这个库不是完全免费的。官网上也没有明确价格，需要Contact sales。 &lt;a href=&#34;https://superpowered.com/pricing&#34;&gt;https://superpowered.com/pricing&lt;/a&gt;{.wp-editor-md-post-content-link}&lt;br&gt;
那算了，没太大兴趣了解。&lt;/p&gt;</description>
    </item>
    <item>
      <title>用琴生(Jensen)不等式证明期望最大值(EM)算法收敛</title>
      <link>https://ykyi.net/?p=1683/</link>
      <pubDate>Sun, 13 Jun 2021 04:04:43 +0000</pubDate>
      <guid>https://ykyi.net/?p=1683/</guid>
      <description>&lt;p&gt;今年二月份刷了一遍“机器学习白板推导”系列视频。https://www.bilibili.com/video/BV1aE411o7qd 。这个机器学习的公式推导系列讲地真是太好了，当时像追剧一般花了两个星期听完。非常感谢录这个视频系列的老师shuhuai008。不过，因为以前机器学习的基础几乎为0，又没有动手做相关练习。三个半月以后，又忘了很多了。昨天，我想起要复习一下EM算法，于是又把视频捡起来找到EM算法的部分，复习一下。&lt;/p&gt;
&lt;p&gt;第二次看，果然快了很多。不过，在用琴生不等式证明EM算法收敛的部分，卡住了。我不断回忆第一次看的时候是如何理解的，奈何回忆不起来了。于是，找到Jensen不等式的词条看了看，琢磨了好久。终于懂了，在这里把这个思考过程记下来。&lt;/p&gt;
&lt;p&gt;我卡在这个步骤：需要用Jensen Inequality证明如下不等式：&lt;br&gt;
[latex]&lt;br&gt;
\int\limits_z P(z|x, \theta^{(t)}) \log_{}{\frac{P(z|x, \theta^{(t+1)})}{P(z|x, \theta^{(t)})} } dz \le 0&lt;br&gt;
[/latex]&lt;br&gt;
上面公式中的z表示模型中的隐变量，x表示观测值，$ \theta $是参数，$ \theta^{(t)} $表示theta在第t时刻的值（EM算法是一个迭代算法）。&lt;/p&gt;
&lt;p&gt;证明这个不等式需要用到琴生不等式在凹函数上的性质。如下：&lt;br&gt;
设f(x)中一个凹函数（凹函数图形和中文字凹的形状相反，可以理解为上凸，log函数即一个凹函数）,下面的不等式成立。&lt;br&gt;
$$&lt;br&gt;
a_1f(x_1) + a_2f(x_2) + \dots + a_nf(x_n) \le f(a_1x_1 + a_2x_2 + \dots + a_nx_n)&lt;br&gt;
且 a_1 + a_2 + \dots + a_n = 1&lt;br&gt;
$$&lt;br&gt;
用自然语言描述是：凹函数定义域内的n个自变量对应的因变量的线性组合小于或等于n个自变量先做线性组合再求对应的因变量，作线性组合的系数之和为1。简单地说：先求函数值再做线性组合 小于或等于 先做线性组合再求函数值。&lt;/p&gt;
&lt;p&gt;再回到我们要证明的不等式。积分号即可看成是无穷多个值的线性组合，对数符号log后面对应的那一坨&lt;br&gt;
$$ {\frac{P(z|x, \theta^{(t+1)})} {P(z|x, \theta^{(t)})} } $$&lt;br&gt;
看成是log函数的因变量，log前面的&lt;br&gt;
$$&lt;br&gt;
P(z|x, \theta^{(t)})&lt;br&gt;
$$&lt;br&gt;
看成是线性组合的系数，很明显这个系数是满足积分和为1的概率密度。于是，就可以套用上面提到的凹函数上的琴生不等式。不等式的右边为0，左边是“先求函数值再做线性组合”，化简为左边小于“先做线性组合再求函数值”：&lt;br&gt;
$$&lt;br&gt;
\begin{aligned}&lt;br&gt;
左边 &amp;amp;\le log_{}{\int\limits_z {\frac{P(z|x, \theta^{(t+1)})} {P(z|x, \theta^{(t)})} } P(z|x, \theta^{(t)})}dz \&amp;amp;=log_{}{}\int \limits_zP(z|x,\theta^{(t+1)})dz=log_{}{1}=0&lt;br&gt;
\end{aligned}&lt;br&gt;
$$&lt;br&gt;
得证！&lt;/p&gt;</description>
    </item>
    <item>
      <title>使用tailwindcss创建一个全屏模式对话框</title>
      <link>https://ykyi.net/?p=1672/</link>
      <pubDate>Sun, 09 Aug 2020 10:42:00 +0000</pubDate>
      <guid>https://ykyi.net/?p=1672/</guid>
      <description>&lt;p&gt;最开始用的css UI库是最常用，历史最悠久的bootstrap。 后来又接触了bulma，bulma也做得很漂亮，不过我没有把bulma用在实战中。前段时间打算改版我的粤语网站&lt;a href=&#34;https://ykyi.net&#34; title=&#34;https://ykyi.net&#34;&gt;https://ykyi.net&lt;/a&gt;{.wp-editor-md-post-content-link}, 调研了多种技术方案，最终选中了&lt;a href=&#34;http://nextjs.org&#34; title=&#34;nextjs&#34;&gt;nextjs&lt;/a&gt;{.wp-editor-md-post-content-link}。读nextjs官方文档时发现tailwind是nextjs默认配好的css库。这是第一次接触到&lt;a href=&#34;https://tailwindcss.com&#34; title=&#34;tailwindcss&#34;&gt;tailwindcss&lt;/a&gt;{.wp-editor-md-post-content-link}。较之Bulma和bootstrap这些UI库给了开箱即用的很多控件，tailwind只是提供了很多css工具(css类)，用户需要用这些工具自己创建最终使用的控件。一开始会让人有点畏惧，实际使用之后，其实完全自己创建美观的UI控件也并非有那么困难。&lt;/p&gt;
&lt;p&gt;今天用tailwind做了一个全屏的模式对话框Modal Dialog。代码实际上是从网上抄下来的。天下代码我抄你，你抄我嘛～～&lt;br&gt;
HTML代码如下。&lt;pre data-language=HTML&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class=&#34;language-markup &#34;&gt;&amp;lt;div className=&amp;ldquo;bg-gray-200 flex items-center justify-center h-screen&amp;rdquo;&amp;gt;
&amp;lt;button className=&amp;ldquo;modal-open btn btn-green&amp;rdquo;&amp;gt;Open Modal&amp;lt;/button&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;div className=&amp;ldquo;modal opacity-0 pointer-events-none fixed w-full h-full top-0 left-0 flex items-center justify-center&amp;rdquo;&amp;gt;
&amp;lt;div className=&amp;ldquo;modal-overlay absolute w-full h-full bg-gray-900 opacity-50&amp;rdquo;&amp;gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;amp;lt;div className=&amp;quot;modal-container bg-white w-11/12 md:max-w-md mx-auto rounded shadow-lg z-50 overflow-y-auto&amp;quot;&amp;amp;gt;
  &amp;amp;lt;div className=&amp;quot;modal-content py-4 text-left px-6&amp;quot;&amp;amp;gt;
    &amp;amp;lt;div className=&amp;quot;flex justify-between items-center pb-3&amp;quot;&amp;amp;gt;
      &amp;amp;lt;p className=&amp;quot;text-2xl font-bold&amp;quot;&amp;amp;gt;Simple Modal!&amp;amp;lt;/p&amp;amp;gt;
      &amp;amp;lt;div className=&amp;quot;modal-close cursor-pointer z-50&amp;quot;&amp;amp;gt;
        &amp;amp;lt;svg className=&amp;quot;fill-current text-black&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; width=&amp;quot;18&amp;quot; height=&amp;quot;18&amp;quot; viewBox=&amp;quot;0 0 18 18&amp;quot;&amp;amp;gt;
          &amp;amp;lt;path d=&amp;quot;M14.53 4.53l-1.06-1.06L9 7.94 4.53 3.47 3.47 4.53 7.94 9l-4.47 4.47 1.06 1.06L9 10.06l4.47 4.47 1.06-1.06L10.06 9z&amp;quot;&amp;amp;gt;&amp;amp;lt;/path&amp;amp;gt;
        &amp;amp;lt;/svg&amp;amp;gt;
      &amp;amp;lt;/div&amp;amp;gt;
    &amp;amp;lt;/div&amp;amp;gt;

    &amp;amp;lt;p&amp;amp;gt;Modal content can go here&amp;amp;lt;/p&amp;amp;gt;
    &amp;amp;lt;p&amp;amp;gt;...&amp;amp;lt;/p&amp;amp;gt;
    &amp;amp;lt;p&amp;amp;gt;...&amp;amp;lt;/p&amp;amp;gt;
    &amp;amp;lt;p&amp;amp;gt;...&amp;amp;lt;/p&amp;amp;gt;
    &amp;amp;lt;p&amp;amp;gt;...&amp;amp;lt;/p&amp;amp;gt;

    &amp;amp;lt;div className=&amp;quot;flex justify-end pt-2&amp;quot;&amp;amp;gt;
      &amp;amp;lt;button className=&amp;quot;btn btn-green m-2&amp;quot;&amp;amp;gt;Action&amp;amp;lt;/button&amp;amp;gt;
      &amp;amp;lt;button className=&amp;quot;modal-close btn btn-green m-2&amp;quot;&amp;amp;gt;Close&amp;amp;lt;/button&amp;amp;gt;
    &amp;amp;lt;/div&amp;amp;gt;

  &amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;/div&amp;amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>讲讲为什么要用javascript的requestAnimationFrame函数在web上实现复杂动画效果</title>
      <link>https://ykyi.net/?p=1663/</link>
      <pubDate>Thu, 05 Mar 2020 04:17:12 +0000</pubDate>
      <guid>https://ykyi.net/?p=1663/</guid>
      <description>&lt;p&gt;简单地讲，requestAnimationFrame函数更适合在浏览器上面做复杂的动画。比用定时器效率高。&lt;/p&gt;
&lt;p&gt;废话如下：&lt;/p&gt;
&lt;p&gt;现代的WEB世界(2020年)，网页上各种各样的内容丰富多彩。虽然css也能完成很多简单的动画，但是仍然有一些复杂的动画animation需求需要javascript处理。之前，我简单地理解，浏览器已经有定时器函数setTimeout()和setInterval(),就足够做出复杂的动画形式。原来，不是这样的。&lt;/p&gt;
&lt;p&gt;这段时间在做一个运行在浏览器上的红白机模拟器，参考开源代码，发现用的是requestAnimationFrame()函数。于是，查了一些资料，涨了知识。&lt;/p&gt;
&lt;h4 id=&#34;首先使用定时器settimeout和setinterval做动画有两个大缺点&#34;&gt;首先，使用定时器SetTimeout和setInterval做动画有两个大缺点。&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;受有限的资源，或者糟糕的cpu密集的业务代码的影响。浏览器并不严格按照定时器函数中的时间间隔参数来调度定时回调函数。比如50ms，有时会快，有时会慢。这样，动画效果的帧与帧之间的画面就不会那么流畅了。&lt;/li&gt;
&lt;li&gt;频繁的调用计时器函数setTimeout或setInterval，可能导致浏览器假死。浏览器竭尽全力的处理一些跟动画无关的代码，比如文档流的不断重排。这样，用户的界面根本没有获得重新渲染的机会。特别在手机浏览器，由于手机的环境比较特殊。手机的电池可以不够，网络不好，都可能影响web页面的文档重排（page reflow）的效率。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;为什么用requestanimationframe&#34;&gt;为什么用requestAnimationFrame&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;针对定时器的缺点1，浏览器的实现保证requestAnimationFrame设定的回调函数会严格定时执行。当然是在web页是活跃状态，即不是在后台运行。等下会讲到后台执行时的情况。一般浏览器调用requestAnimationFrame设定的回调函数的频率是每秒60次。不同浏览器的实现有不变。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;当web页面被放入后台运行时，浏览器会大辐降低requestAnimationFrame设置的回调函数调用频率。低至每秒两次，甚至暂停。这样，又能节省相当多的资源。比如手机上珍贵的电池资源。非常容易理解，web页面不可见的时候，还继续渲染画面是完全没有意义的。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;需要注意的地方&#34;&gt;需要注意的地方&lt;/h3&gt;
&lt;p&gt;既然requestAnimationFrame的调用频率因浏览器而异，另外页面在后台时又可能会暂停。所以，生成动画的代码不能预设回调函数以某一个固定的频率执行。解决这个问题，requestAnimationFrame的回调函数会传入一个时间戳参数，&lt;/p&gt;
&lt;p&gt;下面是官方文档对传入回调函数的时间参数的解释，给了一个高精度的时间戳，单位是毫秒。嗯，对于浏览器来说，如果能精确到毫秒的话，算得上高精度的时间戳了。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The callback function is passed one single argument, a DOMHighResTimeStamp similar to the one returned by performance.now(), indicating the point in time when requestAnimationFrame() starts to execute callback functions&lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>Tokio简介</title>
      <link>https://ykyi.net/?p=1648/</link>
      <pubDate>Sun, 16 Feb 2020 13:28:36 +0000</pubDate>
      <guid>https://ykyi.net/?p=1648/</guid>
      <description>&lt;h1 id=&#34;什么是tokio&#34;&gt;什么是Tokio&lt;/h1&gt;
&lt;p&gt;Tokio是一个事件驱动的运行时(官网用词runtime)，用来编写rust异步代码。所谓异步代码，即和同步代码对应而言。比如同步读磁盘上的文件：应用代码调用读文件的函数，函数封装了操作系统的系统调用，通知操作系统读入文件内容，操作系统把文件内容全部读出后才回到应用代码，继续执行之后的逻辑。在操作系统读文件内容的过程中，应用程序无所事事，默默地等待。而异步读入文件内容，异步调用通知操作系统读文件后立即返回，应用程序有机会在操作系统读文件时干其他事情，当操作系统读完文件内容后会以某种形式通知应用程序读文件已经完成&lt;/p&gt;
&lt;p&gt;Tokio为异步编程提供了这些东西：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一些基本工具。比如同步原语(synchronization primitives)，管道(channels)，计时器，延时，intervals(不知道这是什么东西，描述一个时间间隔么？)。&lt;/li&gt;
&lt;li&gt;API。网络相关的tcp,udp异步函数，异步文件操作函数，异步的进程和信号管理。&lt;/li&gt;
&lt;li&gt;调度器，用来调度tasks(类似其他语言的异步框架的绿色线程或协程的概念)。&lt;/li&gt;
&lt;li&gt;I/O驱动(官网用语IO driver)，使用原生操作系统的事件队列接口。比如:linux下的epoll,freeBSD下的kqueue，windows下的IOCP。&lt;/li&gt;
&lt;li&gt;高性能的计时器。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;快速-fast&#34;&gt;快速 Fast&lt;/h2&gt;
&lt;p&gt;Tokio使用的是Rust编程语言，当然有资格有能力做到快速。Tokio要设计时也把速度放在非常重要的位置。&lt;/p&gt;
&lt;h2 id=&#34;零开销抽象-zero-cost-abstractions&#34;&gt;零开销抽象 Zero-cost abstractions&lt;/h2&gt;
&lt;p&gt;Tokio广泛使用Future这个异步概念(类似node.js中的promise，据我理解，不同语言的异步框架中使用的future和promise是非常近似的概念)。官方文档声称tokio的future和其他语言的future实现不一样。它是独一无二的(unique)。Tokio中的future会被编译器编译成一个状态机。做异步事件的同步处理时，分配内存，及其他future的实现中有开销的地方，tokio都是零开销。(我觉得协程类的异步框架都要维护状态机用来记录栈的信息么,状态机并不unique。unique的是零开销抽象)。&lt;/p&gt;
&lt;p&gt;零开销抽象并不意味着tikio自身没有开销，而指是不可能再用其他什么方法减少开销，开销已经减到最少。&lt;/p&gt;
&lt;h1 id=&#34;并发-concurrency&#34;&gt;并发 Concurrency&lt;/h1&gt;
&lt;p&gt;Tokio提供了一个多线程，work-stealing(不知用哪个中文合适)的调度器。Tokio是开箱即用的，意味着，当你使用tokio运行时的时候，你就可能充分利用电脑上所有的cpu核心。&lt;/p&gt;
&lt;p&gt;现代计算机通过增加中央处理器的核心来增加性能。所以，能够利用好多核心对于高性能的应用来说是至关重要的。&lt;/p&gt;
&lt;h1 id=&#34;非阻塞io-non-blocking-io&#34;&gt;非阻塞I/O Non-blocking I/O&lt;/h1&gt;
&lt;p&gt;tokio使用操作系统原生的多路复用技术(linux的epoll,freeBSD的kqueue,windows的IOCP)，一个线程可以同时管理多个socket。这样能减少系统调用(system call)，提高应用的性能。&lt;/p&gt;
&lt;h1 id=&#34;可靠-reliable&#34;&gt;可靠 Reliable&lt;/h1&gt;
&lt;p&gt;Tokio在设计时就竭尽所能避免应用程序因使用tokio不当产生BUG，但tokio当然不可能完全做到这点。Tokio的API设计得不易于用错。这样，在项目的最后一天，你就可以信心满满地交付了。&lt;/p&gt;
&lt;h1 id=&#34;所有权和类型系统-ownership-and-type-system&#34;&gt;所有权和类型系统 Ownership and type system&lt;/h1&gt;
&lt;p&gt;Tokio籍由Rust语言特有的所有权系统和严格的类型安全，能避免很多内存安全方面的错误。它能避免绝大多数常见的内存出错：访问未初始化内存，访问释放后内存，内存重复释放（Double Free)。并且，做到这些并不需要付出运行时的额外开销。(回忆自己用C/C++写的复杂应用时追踪偶发的内存出错BUG真是无比痛苦。)&lt;/p&gt;
&lt;p&gt;另外，严格的类型安全系统也使得难以错误使用API。比如，Tokio中的互斥锁并不需要开发者显式释放。(这一点并不稀奇，C++的RAII，Go的defer,python的with也能做到，稍微现代的语言都有类似机制。)&lt;/p&gt;
&lt;h1 id=&#34;反向压力传递-backpressure&#34;&gt;反向压力传递 Backpressure&lt;/h1&gt;
&lt;p&gt;Tokio自带了压力反向传递的功能，这真是真是一个让人称赞的功能，真香。所谓反向压力传递，可以这么理解：当消费者消费的速度小于生产者生产的速度时，数据会在内存中越堆越多，最终把内存撑暴。反向压消费力传递指的是，消费者的压力会反向传递给生产者，让生产者减慢生产的速度以匹配消费者的消费速度。很多其他的库并没有提供这个功能，于是应用需要自己实现一个。但要实现一个高性能的类似功能并不是一件容易的事情。（回忆起自己有段时间用C++的asio异步网络库写的服务器。我的实现是当存放任务的队列到达一个阈值时就让生产者线程sleep很短一段时间，再从网络中读取数据，生产任务，结果性能大降。我相信tokio一定优雅高效地提供了这个功能。）&lt;/p&gt;
&lt;p&gt;tokio官方文档中表示，Tokio中的生产者天生是lazy的，它们会轮循消费者，只有当消费者充许增加数据时，生产者才生产数据。&lt;/p&gt;
&lt;h1 id=&#34;取消-cancellation&#34;&gt;取消 Cancellation&lt;/h1&gt;
&lt;p&gt;应用的业务代码持有一个future，它描述了异步计算的结果。如果当业务代码认为并不需要这个结果时，则可以不再持有这个future（让它的生命期结束）。这样，异步计算就会及时结束，不再执行不必要的计算。官方文档表示这主要受益于Tokio的轮循设计。&lt;/p&gt;
&lt;p&gt;多谢了Rust的权限模型，异步执行部分能通过实现drop这个特征(trait，类似c++,c#,java的接口)，及时感知到future已经被丢弃了。&lt;/p&gt;
&lt;h1 id=&#34;轻量级-lightweight&#34;&gt;轻量级 Lightweight&lt;/h1&gt;
&lt;p&gt;Tokio的伸缩性很好，且伸缩时不给应用增加额外负担。这样，tokio能在资源受限的环境下发展得不错。&lt;/p&gt;
&lt;h1 id=&#34;没有垃圾回收-no-garbage-collector&#34;&gt;没有垃圾回收 No garbage collector&lt;/h1&gt;
&lt;p&gt;tokio使用的是rust语言，所有没有垃圾回收机制，也就避免了在有垃圾回收的语言中普遍存在的“世界暂停”问题。应用会周期性的启动垃圾回收，在极限性能要求的情况下，这个问题就会暴露出来。Tokio的这个特性使得它适合中实时环境中使用。&lt;/p&gt;
&lt;h1 id=&#34;模块化-modular&#34;&gt;模块化 Modular&lt;/h1&gt;
&lt;p&gt;尽管Tokio提供了非常多开箱即用的功能，并且是用模块式的方式组织的。每一个component都使用一个独立的库library。用户可以精确的设定需要使用哪些特性而只导入相应的库，其他不需要使用的库则不会被编译进最终的应用程序中。很多其他著名的rust库也使用了tokio，比如hyper和actix。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Rust语言的宏编程极简教程Macro</title>
      <link>https://ykyi.net/?p=1631/</link>
      <pubDate>Thu, 06 Feb 2020 09:51:08 +0000</pubDate>
      <guid>https://ykyi.net/?p=1631/</guid>
      <description>&lt;h2 id=&#34;rust的宏和cc的异同&#34;&gt;Rust的宏和c/c++的异同&lt;/h2&gt;
&lt;p&gt;Rust语言的宏设计得比较复杂，当然也可以说功能非常强大，跟c/c++语言的宏非常不一样。&lt;br&gt;
&lt;strong&gt;相同点&lt;/strong&gt; 当然是宏能够让代码更精简，码农可以少敲很多样板代码(boilerplate code)。当然你说函数和类不也可以抽象代码，使代码精简吗？但宏能够获取很多在编译期的信息，函数和类却不能。比如，代码所在的文件和行数，这个信息只有宏才能获得。&lt;br&gt;
&lt;strong&gt;不同点&lt;/strong&gt; 是，C/C++的宏只是在预编译期简单地做模式替换，预编译后再交由编译器。c/c++的include头文件展开也是在预编译阶段。但Rust宏的展开不是发生在预编译期，而是编译期。于是Rust能够获得更复杂的更详细的编译器的信息。这里有两个概念Token Tree和AST。如果有大学阶段学习过的编译原理课程的背景就很容易理解。&lt;/p&gt;
&lt;h3 id=&#34;token-tree&#34;&gt;Token Tree&lt;/h3&gt;
&lt;p&gt;Token Tree简写成TT。编译器拿到源代码后先做词法分析，即把源代码字节流分成一个一个的token。token和token之间的逻辑关系也记录下来。比如下面的一个简单语句：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-rust &#34;&gt;a + b + (c + d[0]) + e
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;的Token Tree就长这个样子：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;&#34;&gt;«a» «+» «b» «+» «(   )» «+» «e»
         ╭────────┴──────────╮
          «c» «+» «d» «[   ]»
                       ╭─┴─╮
                        «0»
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;ast&#34;&gt;AST&lt;/h3&gt;
&lt;p&gt;AST的全称是Abstract Syntax Tree，抽象语法树。编译器把Token Tree翻译成AST，这是一个更有利于编译器理解源代码的结构。上面的TT翻译成对应的AST后长这个样子：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;&#34;&gt;              ┌─────────┐
              │ BinOp   │
              │ op: Add │
            ┌╴│ lhs: ◌  │
┌─────────┐ │ │ rhs: ◌  │╶┐ ┌─────────┐
│ Var     │╶┘ └─────────┘ └╴│ BinOp   │
│ name: a │                 │ op: Add │
└─────────┘               ┌╴│ lhs: ◌  │
              ┌─────────┐ │ │ rhs: ◌  │╶┐ ┌─────────┐
              │ Var     │╶┘ └─────────┘ └╴│ BinOp   │
              │ name: b │                 │ op: Add │
              └─────────┘               ┌╴│ lhs: ◌  │
                            ┌─────────┐ │ │ rhs: ◌  │╶┐ ┌─────────┐
                            │ BinOp   │╶┘ └─────────┘ └╴│ Var     │
                            │ op: Add │                 │ name: e │
                          ┌╴│ lhs: ◌  │                 └─────────┘
              ┌─────────┐ │ │ rhs: ◌  │╶┐ ┌─────────┐
              │ Var     │╶┘ └─────────┘ └╴│ Index   │
              │ name: c │               ┌╴│ arr: ◌  │
              └─────────┘   ┌─────────┐ │ │ ind: ◌  │╶┐ ┌─────────┐
                            │ Var     │╶┘ └─────────┘ └╴│ LitInt  │
                            │ name: d │                 │ val: 0  │
                            └─────────┘                 └─────────┘

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;AST图有排版有点乱，我懒得改了。这两人个图，TT和AST都是从 &lt;a href=&#34;https://danielkeep.github.io/tlborm/book/mbe-syn-source-analysis.html&#34;&gt;https://danielkeep.github.io/tlborm/book/mbe-syn-source-analysis.html&lt;/a&gt; 抄来的。您可以移步到那个页面。&lt;br&gt;
重点来了，Rust语言的宏展开就发生在编译器生成了源代码的AST的时候。Rust语言的宏可以从AST获得非常丰富的信息，并操作AST。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Rust语言中的单位类型unit type是什么</title>
      <link>https://ykyi.net/?p=1619/</link>
      <pubDate>Sun, 24 Nov 2019 10:39:09 +0000</pubDate>
      <guid>https://ykyi.net/?p=1619/</guid>
      <description>&lt;p&gt;每个学习Rust语言的读者碰到单位类型unit type ()的时候都非常疑惑这究竟是个什么鬼？&lt;br&gt;
本文总结了stackoverflow上面的贴子 &lt;a href=&#34;https://stackoverflow.com/questions/24842271/what-is-the-purpose-of-the-unit-type-in-rust&#34;&gt;What is the purpose of the unit type in Rust?&lt;/a&gt;{.wp-editor-md-post-content-link}加上我自己的理解。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;unit type是一个类型，有且仅有一个值，都写成小括号()&lt;/li&gt;
&lt;li&gt;单元类型()类似c/c++/java语言中的void。当一个函数并不需要返回值的时候，c/c++/java中函数返回void，rust则返回()。但语法层面上，void仅仅只是一个类型，该类型没有任何值;而单位类型()既是一个类型，同时又是该类型的值。&lt;/li&gt;
&lt;li&gt;单元类型()也类似c/c++/java中的null，但却有很大不同。 null是一个特殊值，可以赋给不可类型的值，例如java中的对象，c中指向struct实例的指针，c++中的对象指针。但在rust中，()不可以赋值给除单元类型外的其它的类型的变量，()只能赋值给()。&lt;/li&gt;
&lt;li&gt;Rust标准库中使用单元类型()的一个例子是HashSet。一个HashSet&lt;t&gt;只不过是HashMap的一个非常简单地包裹，写作：HashMap&amp;lt;T, ()&amp;gt;。HashMap的第二个泛型类型参数即用了单元类型()&lt;/li&gt;
&lt;li&gt;可以用Result&amp;lt;(), MyErrorType&amp;gt;代替Option&lt;myErrorType&gt;，某些开发者认为Result&amp;lt;(), MyErrorType&amp;gt;语义上能更简明地表示一个“结果”。&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;You could argue that Option&lt;myError&gt; is ‘better’, but I disagree; the Result’s naming conventions mean it’s explicitly clear what’s going on.&lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>使用Prettier,Husky和lint-staged，在提交javascript代码前自动格式化代码</title>
      <link>https://ykyi.net/?p=1615/</link>
      <pubDate>Sun, 24 Nov 2019 08:58:10 +0000</pubDate>
      <guid>https://ykyi.net/?p=1615/</guid>
      <description>&lt;h3 id=&#34;目标&#34;&gt;目标&lt;/h3&gt;
&lt;p&gt;为防止提交不合格的代码排版到仓库中，我们希望在提交前格式化代码，使之符合项目的代码格式规范，而且尽可能保证逻辑正确。即目标有两点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;对git staged的代码强行格式化，使符合规范。对于没有被staged的代码或文件，将完全忽略。&lt;/li&gt;
&lt;li&gt;跑单元测试。只有通过了单元测试才能提交代码。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;安装依赖&#34;&gt;安装依赖&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&#34;&#34;&gt;$ npm install --save-dev husky lint-staged
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;先安装husky和lint-staged。注间在安装husky之前需要确保工程目录已经是一个合法的git仓库。因为，安装husky时需要给git仓库安装预提交钩子(precommit hook)。&lt;br&gt;
Lint-staged提供了一个关键的功能，它能找到所有被git staged的文件，而不是工程下面所有的文件，然后通过管道交给Prettier做格式化。&lt;/p&gt;
&lt;h3 id=&#34;修改npm脚本&#34;&gt;修改npm脚本&lt;/h3&gt;
&lt;p&gt;对npm script做如下改动：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-json &#34;&gt;  &#34;scripts&#34;: {
    &#34;precommit&#34;: &#34;lint-staged&#34;
  },
  &#34;lint-staged&#34;: {
    &#34;*.{js,jsx,json}&#34;: [&#34;prettier --write&#34;, &#34;git add&#34;]
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;scripts.precommit由Husky处理，它会依照配置在把代码正式提交到仓库前运行lint-staged(当然我们也可以配置其他命令）。&lt;br&gt;
Lint-staged再找到属于它自己的配置部分，即lint-staged键下面的配置。&lt;br&gt;
在此例中，所有staged状态的，且扩展名是.js, .jsx, 和.json文件都会自动交由Prettier做格式化，然后再提交。&lt;/p&gt;
&lt;h1 id=&#34;为何一定要用lint-staged&#34;&gt;为何一定要用lint-staged&lt;/h1&gt;
&lt;p&gt;You might wonder why we don’t just use Husky to run a few npm scripts.&lt;br&gt;
你可以会疑惑，为什么一定要罗里罗嗦地用lint-staged，用Husky直接调用npm脚本不更简单么。&lt;br&gt;
这是因为我们用lint-staged拿到staged状态的文件，而不是所有的文件。&lt;br&gt;
你的node工程文件中可能已经有如下做代码格式化的脚本&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-json &#34;&gt;&#34;format&#34;: &#34;prettier --write &#39;**/*.{js,jsx}&#39;&#34;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你可能会因此如下配置&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-json &#34;&gt;&#34;lint-staged&#34;: {
  &#34;*.{js,jsx,json}&#34;: [&#34;npm run format&#34;, &#34;git add&#34;]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果是这样配置的话，就没有必要用lint-staged了。因为，这样的配置会把prettier应用到所有匹配.js,.jsx.json的文件上，而不是仅staged状态的文件。&lt;/p&gt;</description>
    </item>
    <item>
      <title>python用multiprocessing起子进程，父进程被杀掉时，如何让子进程也自动退出</title>
      <link>https://ykyi.net/?p=1612/</link>
      <pubDate>Fri, 11 Oct 2019 11:55:07 +0000</pubDate>
      <guid>https://ykyi.net/?p=1612/</guid>
      <description>&lt;p&gt;最近用python3写了一段代码，代码会起一个子进程做一些辅助的事情。但发现父进程被杀死后，这个子进程变成了孤儿进程，仍然在运行。&lt;br&gt;
起进程的代码大概如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-python &#34;&gt;from multiprocessing import Process, Queue
__q = Queue()
__p = Process(target=__run, args=(__q,))
__p.start()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;很不方便，那怎样让父进程退出后，子进程也跟着退出呢。&lt;br&gt;
一番google之后，原来可以用一行代码解决：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-python &#34;&gt;from multiprocessing import Process, Queue
__q = Queue()
__p = Process(target=__run, args=(__q,))
__p.daemon = True    # 加上这一行代码
__p.start()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;设置子进程的daemon属性为True。这样，当在控制台上用ctrl-c，退发送SIGTERM杀掉父进程后，子进程也会跟着退出，不会成为孤儿进程。&lt;br&gt;
参考python官方的解释：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;daemon&lt;br&gt;
The process’s daemon flag, a Boolean value. This must be set before start() is called.&lt;br&gt;
The initial value is inherited from the creating process.&lt;br&gt;
When a process exits, it attempts to terminate all of its daemonic child processes.&lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>Rust中的&amp;str和String有什么区别</title>
      <link>https://ykyi.net/?p=1602/</link>
      <pubDate>Mon, 07 Oct 2019 11:59:41 +0000</pubDate>
      <guid>https://ykyi.net/?p=1602/</guid>
      <description>&lt;p&gt;&amp;amp;str和String让Rust初学者困惑不已。这里简单的介绍一个&amp;amp;str和String的区别。&lt;/p&gt;
&lt;p&gt;String就像是Vec一样是动态分配在堆heap上的字符串类型，它指向一串UTF8编码的字节序。当需要拥有该字符串，要更改字符串的内容，要把字符串在线程之间传递，要在运行时动态创建字符串时使用此类型。&lt;/p&gt;
&lt;p&gt;str也指向一串UTF8编码的字节序，但并不拥有指向的字符串，而仅仅只是一个“string slice”。&lt;a href=&#34;https://doc.rust-lang.org/book/ch04-03-slices.html&#34;&gt;slice的详细解释点链接&lt;/a&gt;。str绝大多数情况下以引用**&amp;amp;str**的形式出现。又被称为字符串字面值(string literal)。&lt;br&gt;
和String指向的字符串肯定分配在堆上面不一样，str指向的字符串可能出现在各种地方：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;在程序的全局静态空间&lt;/strong&gt;(.text段？？)。一个string literal的类型和生命期是：&amp;amp;’static str。字符串的数据硬编码进生成的程序或库文件，但程序加运行时，字符串加载进内存。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分配在堆上面&lt;/strong&gt; String有一个方法是&lt;a href=&#34;https://doc.rust-lang.org/std/string/struct.String.html#method.as_str&#34;&gt;as_str&lt;/a&gt;,它返回一个&amp;amp;str,指向String管理的堆上面的字符串。另外，String有实现Deref&amp;lt;Target=str&amp;gt;这样一个Trait，让所有接受&amp;amp;str作为参数的函数，都可以传String的引用。编译器会自动把&amp;amp;String转成&amp;amp;str。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分配在栈上面&lt;/strong&gt; 如下面的代码，变量stack_str的类型是&amp;amp;str,它指向栈上面的字符串。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&#34;language-rust-lang &#34;&gt;use std::str;

let x: &amp;[u8] = &amp;[b&#39;a&#39;, b&#39;b&#39;, b&#39;c&#39;];
let stack_str: &amp;str = str::from_utf8(x).unwrap();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果以C++程序员的视角看String和&amp;amp;str。一个Rust的String类似std::string,完全拥有并管理（创建，销毁）需要的内存。而Rust的&amp;amp;str则类似char*（当然实际上要复杂很多），仅仅指向字符串，不负责管理对应的内存。&lt;/p&gt;
&lt;p&gt;再看看String和&amp;amp;str的互转化：&lt;br&gt;
&amp;amp;str转String可以用三种方法&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-rust-lang &#34;&gt;    let a: String = &#34;hello rust&#34;.into();
    let c: String = &#34;hello rust&#34;.to_string();
    let b: String = String::from(&#34;hello rust&#34;);
    println!(&#34;{}&#34;, a);   // 都输出 hello rust
    println!(&#34;{}&#34;, b);
    println!(&#34;{}&#34;, c);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;String转&amp;amp;str可以直接引用String类型的值或者调用String的as_str方法。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-rust-lang &#34;&gt;let a: String = String::from(&#34;hello rust&#34;);
let aaa: &amp;str = &amp;a;
let bbb: &amp;str = a.as_str();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;转载请注明出处链接&lt;/strong&gt; &lt;a href=&#34;http://ykyi.net/2019/10/rust%E4%B8%AD%E7%9A%84str%E5%92%8Cstring%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB/&#34;&gt;http://ykyi.net/2019/10/rust%E4%B8%AD%E7%9A%84str%E5%92%8Cstring%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB/&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>linux怎么把一个正在前台运行的进程用nohup放入后台运行</title>
      <link>https://ykyi.net/?p=1592/</link>
      <pubDate>Fri, 14 Jun 2019 09:06:00 +0000</pubDate>
      <guid>https://ykyi.net/?p=1592/</guid>
      <description>&lt;p&gt;假设进程在控制台运行。&lt;br&gt;
三个步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ctrl + z 停止正在运行的进程&lt;/li&gt;
&lt;li&gt;$ bg 命令把该进程放入后台&lt;/li&gt;
&lt;li&gt;disown -h [job的序号] 后台的进程有类似%1, %2, %3的序号。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;至此，一个正在控制台前台运行进程被放入后台，且忽略SIGHUP信号。这样，即使关闭了控制台，也不会杀死这个进程了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>python自制包并用pip免提交到pypi仅安装到本机</title>
      <link>https://ykyi.net/?p=1588/</link>
      <pubDate>Sun, 02 Jun 2019 14:31:10 +0000</pubDate>
      <guid>https://ykyi.net/?p=1588/</guid>
      <description>&lt;p&gt;不得不说python的自制包的相关工具真是多且混乱，什么setuptools,什么distutils，什么wheel，什么egg！！怎么有这么多啊？？&lt;/p&gt;
&lt;p&gt;而且我的需求且且是创建一个自制包管理自己常用的代码，也必不想提交到PyPI，仅仅只需要安装到本机就行。&lt;/p&gt;
&lt;p&gt;下面就是几个关键步骤。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;文件目录布局&lt;br&gt;
├── package1&lt;br&gt;
│ └──-├── &lt;strong&gt;init&lt;/strong&gt;.py&lt;br&gt;
| |── mod1.py&lt;br&gt;
│ └── mod2.py&lt;br&gt;
├── setup.py&lt;br&gt;
|── README.md&lt;/li&gt;
&lt;li&gt;编写setup.py文件，类似如下：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&#34;language-python &#34;&gt;from setuptools import setup, find_packages

setup(
    name=&#34;kamustools&#34;,
    version=&#34;1.0.1&#34;,
    author=&#34;Kamuszhou&#34;,
    author_email=&#34;zausiu@gmail.com&#34;,
    description=&#34;tools used by kamuszhou exclusively.&#34;,
    license=&#34;BSD&#34;,
    keywords=&#34;kamus&#34;,
    url=&#34;https://ykyi.net&#34;,
    packages=find_packages(),
    long_description=&#34;Long descrition is actually short...&#34;,
    classifiers=[
        &#34;Development Status :: 3 - Alpha&#34;,
        &#34;Topic :: Utilities&#34;,
        &#34;License :: OSI Approved :: BSD License&#34;,
    ],
)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&#34;3&#34;&gt;
  &lt;li&gt;
    python3 setup.py sdist bdist_wheel
  &lt;/li&gt;
  &lt;li&gt;
    pip install ./dist/kamustools-1.0.1.tar.gz
  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;就这四步，其他各种功能，以后要用了再慢慢看吧，实在太庞杂了。满足我自己需求的这四个简单步骤就记录在这里。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wikipedia维基百科为什么不放广告，是因为版权原因吗？</title>
      <link>https://ykyi.net/?p=1578/</link>
      <pubDate>Mon, 29 Apr 2019 03:37:52 +0000</pubDate>
      <guid>https://ykyi.net/?p=1578/</guid>
      <description>&lt;p&gt;答：不！维基百科不投放广告，不是因为版权原因。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Wikipedia:Funding_Wikipedia_through_advertisements&#34;&gt;https://en.wikipedia.org/wiki/Wikipedia:Funding_Wikipedia_through_advertisements&lt;/a&gt; 维基官方对投放广告的官方解释：17点理由不投放广告，没有一点提到版权。&lt;/p&gt;
&lt;p&gt;通篇只有一处提到版权，是创始人Jimmy Wales的一段话：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I believe that if we looked at putting ads into the search results page (only), with the money earmarked for specific purposes (with strong community &amp;gt; input into what those would be, either liberation of copyrights ….&lt;br&gt;
我相信，如果我们把广告放到搜索结果中，由此筹到的钱可用于特殊用途（社区的大量投入将是版权的解放）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;有人说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;像这种权威的百科站点，例如莫种性病的解释词条边上出现一个莆田医院的广告，会怎样？难以想象！这种事也就百度做得出来吧。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;上面链接中维基官方给出的不放广告的解释中就有几点的意思一致。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ads cheapen the encyclopedia 会让维基掉价;&lt;/li&gt;
&lt;li&gt;Threat to neutrality of content 影响内容中立;&lt;/li&gt;
&lt;li&gt;Conflict of interest 和用户利益冲突.&lt;/li&gt;
&lt;li&gt;Inappropriate ads 广告内容可能不恰当&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;上面的官方链接还有一条很强的证据能证明维基不放广告和版权无关。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The right to fork. It is inherent in the use of an open license that projects can fork. Thus far the largest fork away from Wikimedia was by a large part of the Spanish Wikipedia community who left because advertising was being considered. &lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>flask框架的回复中显示中文utf8字符，而不是unicode-escape字符串</title>
      <link>https://ykyi.net/?p=1565/</link>
      <pubDate>Mon, 03 Dec 2018 11:41:55 +0000</pubDate>
      <guid>https://ykyi.net/?p=1565/</guid>
      <description>&lt;p&gt;今天在用flask框架写http服务的时候，发现调用flask的jsonify函数得到的http回复包中的字文是用unicode-escape string表示的。如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;&#34;&gt;u5b57\u5173\u6ce8\u6211\u4eec\uff01
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有些RESTful工具能够把unicode-escape字符串转成utf8，能够正常显示出中文。但很多编辑器和其它工具只能显示原本的unicode转义字符串，大大妨碍调试。解决方案是用flask的另一个函数：make_response解决这个问题。代码如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-python &#34;&gt;from flask import Flask, jsonify, make_response


def mk_utf8resp(js):
    &#39;&#39;&#39;
    传入一个字典，返回一个json格式的http回复。
    &#39;&#39;&#39;
    resp = make_response(json.dumps(js, ensure_ascii=False))
    resp.headers[&#39;Content-Type&#39;] = &#39;application/json&#39;
    return resp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;把jsonify(js)换成mk_utf8resp(js)，问题解决。&lt;/p&gt;</description>
    </item>
    <item>
      <title>netstat -s统计输出的所有字段详细解释</title>
      <link>https://ykyi.net/?p=1557/</link>
      <pubDate>Fri, 23 Nov 2018 08:45:32 +0000</pubDate>
      <guid>https://ykyi.net/?p=1557/</guid>
      <description>&lt;p&gt;今天工作上碰到一个问题需要知道udp的丢包数据。实际上我不相信能简单地得到udp的丢包精确数据。理由是，网卡负载太高时有些包连网卡都没收到，根本不可能来得及汇报给内核。另外，如果是路由器把udp丢了，那udp的目的端机器当然更不可能感知到有丢包了。&lt;/p&gt;
&lt;p&gt;这时，同事说netstat -us (–statistic)可以看到udp的丢包。这里的u选项指的是只展示udp相关的统计，s选项自然表示的是统计了。如果不用u选项，则出显示所有统计数据。下面是我的机器上的输出。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;Ip:
    203440255187 total packets received
    0 forwarded
    0 incoming packets discarded
    201612429535 incoming packets delivered
    1064529177 requests sent out
    15 fragments dropped after timeout
    3058122492 reassemblies required
    1230296840 packets reassembled ok
    15 packet reassembles failed
Icmp:
    14869220 ICMP messages received
    3965512 input ICMP message failed.
    ICMP input histogram:
        destination unreachable: 6054246
        timeout in transit: 687
        echo requests: 8570532
        echo replies: 243755
    12913011 ICMP messages sent
    0 ICMP messages failed
    ICMP output histogram:
        destination unreachable: 4097869
        time exceeded: 5
        echo request: 244605
        echo replies: 8570532
IcmpMsg:
        InType0: 243755
        InType3: 6054246
        InType8: 8570532
        InType11: 687
        OutType0: 8570532
        OutType3: 4097869
        OutType8: 244605
        OutType11: 5
Tcp:
    111681768 active connections openings
    4186820 passive connection openings
    24951865 failed connection attempts
    55064041 connection resets received
    275 connections established
    1033901799 segments received
    1776166765 segments send out
    12156205 segments retransmited
    6705 bad segments received.
    106348033 resets sent
Udp:
    198894689917 packets received
    472986510 packets to unknown port received.
    1146976531 packet receive errors
    116750744 packets sent
    110301286 receive buffer errors
    0 send buffer errors
UdpLite:
TcpExt:
    423 invalid SYN cookies received
    693 packets pruned from receive queue because of socket buffer overrun
    19 packets pruned from receive queue
    11309370 TCP sockets finished time wait in fast timer
    106 packets rejects in established connections because of timestamp
    10210477 delayed acks sent
    20811 delayed acks further delayed because of locked socket
    Quick ack mode was activated 8856 times
    17118697 packets directly queued to recvmsg prequeue.
    301717551 bytes directly in process context from backlog
    152118951904 bytes directly received in process context from prequeue
    104771733 packet headers predicted
    15179703 packets header predicted and directly queued to user
    218747377 acknowledgments not containing data payload received
    102637644 predicted acknowledgments
    7293 times recovered from packet loss by selective acknowledgements
    Detected reordering 40 times using FACK
    Detected reordering 27 times using SACK
    Detected reordering 1088 times using time stamp
    476 congestion windows fully recovered without slow start
    5287 congestion windows partially recovered using Hoe heuristic
    236 congestion windows recovered without slow start by DSACK
    151673 congestion windows recovered without slow start after partial ack
    1 timeouts after reno fast retransmit
    4 timeouts after SACK recovery
    10540 timeouts in loss state
    7232 fast retransmits
    649 forward retransmits
    1871 retransmits in slow start
    11612658 other TCP timeouts
    TCPLossProbes: 93185
    TCPLossProbeRecovery: 14667
    2431 packets collapsed in receive queue due to low socket buffer
    8814 DSACKs sent for old packets
    3350 DSACKs received
    1 DSACKs for out of order packets received
    90851 connections reset due to unexpected data
    214 connections reset due to early user close
    352 connections aborted due to timeout
    TCPDSACKIgnoredNoUndo: 1571
    TCPSpuriousRTOs: 7
    TCPSackShifted: 94
    TCPSackMerged: 131
    TCPSackShiftFallback: 21183
    TCPTimeWaitOverflow: 1876775
    TCPRcvCoalesce: 15711184
    TCPOFOQueue: 3194
    TCPChallengeACK: 2337394
    TCPSYNChallenge: 13608
    TCPSpuriousRtxHostQueues: 1982796
IpExt:
    InBcastPkts: 46443933
    InOctets: 44312451521655
    OutOctets: 1915626725817
    InBcastOctets: 6827280595
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;喂，要是转载文章。麻烦贴一下出处 ykyi.net 采集爬虫把链接也抓走&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux系统级/进程级最多打开文件数,FD文件描述符数</title>
      <link>https://ykyi.net/?p=1551/</link>
      <pubDate>Thu, 22 Nov 2018 11:55:39 +0000</pubDate>
      <guid>https://ykyi.net/?p=1551/</guid>
      <description>&lt;p&gt;如何增加Linux系统最大文件打开数目呢？&lt;/p&gt;
&lt;h3 id=&#34;查看系统最大可打开文件数&#34;&gt;查看系统最大可打开文件数&lt;/h3&gt;
&lt;p&gt;以下命令查看操作系统级最多可打开文件数,fd数目&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;$ cat /proc/sys/fs/file-max
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我用ubuntu 16输出:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;573738
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;怎么调整系统最大可打开文件数&#34;&gt;怎么调整系统最大可打开文件数&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;# sysctl -w fs.file-max=1000000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要用root用户执行以上命令，设最大为一百万。&lt;br&gt;
但在命令行上修改了这个配置，会在下一次操作系统重启后重置为以前的值。要一劳永逸的改变系统最大打开文件数，需要修改 /etc/sysctl.conf 文件。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;fs.file-max = 1000000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在/etc/sysctl.conf文件中增加上述一行。&lt;/p&gt;
&lt;h3 id=&#34;ulimit命令查看调整进程级最大文件打开数&#34;&gt;ulimit命令查看/调整进程级最大文件打开数&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;$ ulimit -Sn
1024
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个命令查看一个ulimit的软极限值(soft limit)，本用户起的进程的最大文件打开数的限制。我的ubuntu 16显示进程最多开1024个fd。如果要提高每个进程可同时打开的文件数，需要更改这个值。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;&#34;&gt;$ ulimit -Sn 2048
bash: ulimit: open files: cannot modify limit: Invalid argument
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但我想把每个进程可同时打开的文件数增加到以前的两倍时，报错了。这是因为，软极限值(soft limit)不能够越过(Hard Limit)。我看了一下Hard limit，也是1024&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;&#34;&gt;$ ulimit -Hn
1024
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那没办法罗，需要以root用户登录更改Hard Limit。&lt;/p&gt;
&lt;h3 id=&#34;怎么修改普通用户的硬极限hard-limit&#34;&gt;怎么修改普通用户的硬极限hard Limit&lt;/h3&gt;
&lt;p&gt;用root账户登录后，编辑 /etc/security/limits.conf文件，假如普通用户名是kamuszhou。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;kamuszhou hard nofile 10000
kamuszhou soft nofile 5000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上配置修改kamuszhou普通用户的最多打开文件数的hard limit为10000，soft limit为5000。&lt;br&gt;
对于ubuntu 16，如果使用图形桌面，还需要修改 /etc/systemd/system.conf 和 /etc/systemd/user.conf。&lt;br&gt;
加上这么一行：&lt;/p&gt;</description>
    </item>
    <item>
      <title>如何定制一个python的logging Handler</title>
      <link>https://ykyi.net/?p=1545/</link>
      <pubDate>Tue, 20 Nov 2018 11:16:45 +0000</pubDate>
      <guid>https://ykyi.net/?p=1545/</guid>
      <description>&lt;p&gt;上个月用python的gevent协程库写了一个tcp服务。日志库使用python标准日志库logging。一个月后，发现一个偶发的bug。这个bug发生时，用python的标准日志库自带的FileHandler写的日志会发往socket占用的文件描述符fd。结果就是，客户端收到了本要打印到磁盘上的日志。花了不少时间定位排查这个bug，仍然没有结果。我开始怀疑是gevent协程库和python的标准日志库logging有冲突。协程库会错误的把logging打开的文件描述符fd关闭并分配给新创建的socket，于是日志就打印到socket占用的fd了。&lt;/p&gt;
&lt;p&gt;后来，写了一个检测脚本用来监控这个情况发生的概率。该脚本每分钟会检查进程占用的所有fd，一但发现用来打印本地日志的文件fd不见了，就重启服务进程。核心代码如下:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;lsof -p $pid | grep -q ${log_file_name}
if [ $? != 0 ]
then
    # 报警代码 ...
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;发现bug发生的频率大概是一个星期一次。但这毕竟根本上解决不了问题啊，又找不到bug的原因，怎么办？&lt;/p&gt;
&lt;h3 id=&#34;那就自定义一个file-handler吧&#34;&gt;那就自定义一个File Handler吧！&lt;/h3&gt;
&lt;p&gt;决定自定义一个File Handler，这个File Handler工作在另外一个单独的进程，这样无论如何日志用的fd都不会跟主进程的各种socket用的fd冲突了吧。&lt;br&gt;
代码如下，主要用到的技术进程通讯和用python的&lt;code&gt;__getattribute__&lt;/code&gt;魔法把截获类实例的方法调用。这样，只需要把旧的代码中的File Handler(我用了TimedRotatingFileHandler)换成自定义的Handler Class，所有其他旧代码都无需改动。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-python &#34;&gt;#!/usr/bin/env python3

&#39;&#39;&#39;
created by kamuszhou*AT*tencent.com, zausiu*AT*gmail.com http://ykyi.net
Nov 20, 2018
&#39;&#39;&#39;

import logging
import logging.handlers
from functools import partial
from multiprocessing import Process, Queue


class MySpecialHandler(logging.StreamHandler):
    def __init__(self, *args, **kargs):
        self._q = Queue()
        self._p = Process(target=MySpecialHandler.__run, args=(self._q,))
        self._p.start()
        self._q.put((&#39;__init__&#39;, args, kargs))

    def join(self):
        self._p.join()

    def __run(q):
        handler = None
        while True:
            # op, params = q.get()
            method, args, kwargs = q.get()
            if method == &#39;__init__&#39;:
                handler = logging.handlers.TimedRotatingFileHandler(*args, **kwargs)
            else:  # 主进程的日志调用实际上被转到这里
                getattr(handler, method)(*args, **kwargs)

    def __proxy(self, name, *args, **kwargs):
        # 把调用的方法名和方法参数通过Queue传到专门的日志进程。
        self._q.put((name, args, kwargs))
        fun = logging.StreamHandler.__getattribute__(self, name)
        # print(&#39;call method: &#39;, name, args, kwargs)
        # 如果是setLevel函数，再调用一次父类的方法
        if name in {&#39;setLevel&#39;}:
            return fun(*args, **kwargs)

    def __getattribute__(self, name):
        &#39;&#39;&#39;
        Hook大法！截获所有方法
        &#39;&#39;&#39;
        attr = logging.StreamHandler.__getattribute__(self, name)
        if hasattr(attr, &#39;__call__&#39;) and name not in {&#39;join&#39;, &#39;emit&#39;}:
            return partial(MySpecialHandler.__proxy, self, name)
        else:
            return attr


if __name__ == &#39;__main__&#39;:
    handler = MySpecialHandler(&#39;/data/tmp/ttt.log&#39;, when=&#39;D&#39;, interval=1, backupCount=90)
    handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter(&#39;%(asctime)s: %(levelname)s %(message)s&#39;)
    handler.setFormatter(formatter)
    logger = logging.getLogger(__name__)
    logger.propagate = False  # Don&#39;t propagate the logging to ROOT
    logger.setLevel(logging.DEBUG)
    logger.addHandler(handler)
    logger.debug(&#39;debug testtttttttt&#39;)
    logger.info(&#39;info testtttttttttt&#39;)
    logger.warn(&#39;warn testtttttttttt&#39;)
    logger.error(&#39;error testtttttttt&#39;)
    logger.critical(&#39;critical testttttt&#39;)
    handler.join()

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里自定义的日志进程类只是一个很粗糙的实现，一但跑起来，只能手动杀进程。反正我的使用场景是一个服务。所以，我也懒得加‘优雅的退出代码’。&lt;/p&gt;</description>
    </item>
    <item>
      <title>伯努利(Binomial)分布和伯努利试验的区别，负伯努利分布及几何分布,超几何分布</title>
      <link>https://ykyi.net/?p=1469/</link>
      <pubDate>Tue, 13 Nov 2018 11:49:15 +0000</pubDate>
      <guid>https://ykyi.net/?p=1469/</guid>
      <description>&lt;p&gt;[mathjax]我又重新把概率，统计书拿起来了。这次是真的，要把机器学习（统计学习)学好。显然，学好机器学习并不是一件容易的事情。需要要扎实的数学基础。好在我的数学储备还勉强可以，但远算不上“基础扎实”。所以，我有了一个长期远景规划，重新开始学习吧！&lt;/p&gt;
&lt;p&gt;今天看了伯努力分布，负伯努利分布，超几何分布，几何分布这几个知识点。下面我一边写回顾今天学到的，一边写文章。&lt;/p&gt;
&lt;h4 id=&#34;伯努利分布和伯努利试验的区别&#34;&gt;伯努利分布和伯努利试验的区别&lt;/h4&gt;
&lt;p&gt;伯努利试验(Binomial Experiment)指的仅仅是”一次试验”，或者成功，或者失败。伯奴利分布是一个常用分布，这是完全不同的两个概念。&lt;br&gt;
每次伯努利试验的成功概率记为p，又把重复很多次伯努利试验称为伯努利过程(Binomial Process)。一个重复了n次伯努利试验的伯努利过程中，成功的试验次数记为X，这个X则是伯努利随机变量。X的概率分布被称为伯努利分布。&lt;br&gt;
伯努利分布：&lt;/p&gt;
&lt;p&gt;$$b(x;n,p) = {n \choose x} p^k (1-p)^{ n-k}$$&lt;/p&gt;
&lt;p&gt;其中，n表示试验次数，p表示每次独立试验成功的概率，x表示成功次数。&lt;/p&gt;
&lt;h3 id=&#34;什么是负伯努利分布negative-binomial-distribution&#34;&gt;什么是负伯努利分布(Negative Binomial Distribution)&lt;/h3&gt;
&lt;p&gt;伯努利分布和负伯努利分布的大多数设定都是一样的，都不断重复伯努利试验，要么成功要么失败。&lt;br&gt;
不同点是：伯努利分布的随机变量X，表示的是在前n次伯努利试验中成功了x次；而负伯努利的随机变量x，表示的是要达成k次成功试验，需要试验x次（即第x次试验成功，前x-1次试验成功了k-1次）。伯努利分布限定了试验次数记为n，负伯努利限定了成功次数记为k。&lt;br&gt;
负伯努利分布：&lt;/p&gt;
&lt;p&gt;$$b^*(x;k, p) = {{x-1} \choose {k-1}}p^kq^x-k$$&lt;/p&gt;
&lt;h3 id=&#34;几何分布和超几何分布&#34;&gt;几何分布和超几何分布&lt;/h3&gt;
&lt;p&gt;再以伯努利分布为讨论的基础，仅更改一处，即把伯努利过程中的放回抽样(with replacement)改成不放回抽样(without replacement)，即可得到超几何分布。&lt;br&gt;
以负伯努利分布为讨论的基础，仅更改一处，即k设为1，表示成功一次。即不断重复伯努利试验，直到第一次成功就结束，得到了几何分布。&lt;/p&gt;
&lt;h3 id=&#34;伯努利分布负伯努利分布的命名&#34;&gt;伯努利分布，负伯努利分布的命名&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;为什么叫伯努利分布&lt;br&gt;
因为伯努利展开式$$(q+p)^n$$的n+1个项对应伯努利分布取各个值时的情况。&lt;/li&gt;
&lt;li&gt;为什么叫负伯努利分布&lt;br&gt;
因为展开式$$p^k(1-p)^(-k)$$中的每个项对应$$b^*(x;k,p)$$取x=k, k+1, k+2, …时的情况。&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>安装MathJax-LaTeX插件，让wordpress显示数学公式</title>
      <link>https://ykyi.net/?p=1483/</link>
      <pubDate>Tue, 13 Nov 2018 09:14:27 +0000</pubDate>
      <guid>https://ykyi.net/?p=1483/</guid>
      <description>&lt;p&gt;最近看统计学，涉及很多数学公式。于是，想找到一款wordpress的插件可以显示数学公司。&lt;/p&gt;
&lt;p&gt;当然，于是就找到了 &lt;strong&gt;MathJax-LaTex&lt;/strong&gt;这个插件。虽然插件名字中有LaTex，但实际上不仅仅可以用LaTex语法描述数学公式，亦可用AsciiMath，以及MathML。&lt;br&gt;
本以为像其它所有wordpress插件一样，安装很简单，很容易就能上手使用。没想到还是花了一些时间。&lt;/p&gt;
&lt;p&gt;MathJax-LaTex插件依赖MathJax这个javascript开源工程。原因貌似是MathJax默认用的CDN在大陆被墙了，还是因为浏览器的同源策略被浏览器禁了??我懒得重现排查真正原因了。总之，我用MathJax-LaTex默认配置没有成功，于是我自己手动下载并安装到自己的服务器，运行OK。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;首先到 &lt;a href=&#34;https://github.com/mathjax/MathJax&#34;&gt;https://github.com/mathjax/MathJax&lt;/a&gt;{.wp-editor-md-post-content-link} 下载源代码。熟悉git的同学可以用git下载，亦可用右边的 &lt;em&gt;Clone or Dowload&lt;/em&gt; 按钮下载zip包。&lt;/li&gt;
&lt;li&gt;把zip包上传到自己的服务器，找一个目录解压缩。&lt;/li&gt;
&lt;li&gt;打开MathJax-LaTex的配置web页面，如下图如示，去掉Use MathJax CDN Service 的勾，不要用MathJax自己的CDN；然后，在Custom MathJax location选项中填上自己的路径。假如刚才zip包MathJax解压缩到的目录是/tools，那么就填上 &lt;em&gt;/tools/MathJax-2.7.5/MathJax.js&lt;/em&gt; 。&lt;br&gt;
&lt;a href=&#34;http://ykyi.net/zausiu/imgs/MathJax-LaTex.png&#34; title=&#34;MathJax-LaTex-Conf&#34;&gt;&lt;img decoding=&#34;async&#34; src=&#34;http://ykyi.net/zausiu/imgs/MathJax-LaTex.png&#34; alt=&#34;MathJax-LaTex-Conf&#34; title=&#34;MathJax-LaTex-Conf&#34; /&gt;&lt;/a&gt;{.wp-editor-md-post-content-link}&lt;/li&gt;
&lt;li&gt;然后创建一篇新博文，现在可以录入数学公式啦。装逼必备！比如下面的伯努利分布的公式： [mathjax]&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;$$b(x;n,p) = {n \choose x} p^k (1-p)^{ n-x}$$&lt;/p&gt;
&lt;p&gt;要输入上述方程式，在文章开头输入**[mathJax]** ,这个标志让MathJax-LaTex插件加载显示数学公式相关的javascript代码。然后敲两个美元号 &lt;code&gt;$$&lt;/code&gt;，敲入公式 b(x;n,p) = {n \choose k} p^k (1-p)^{ n-k}，再敲入两个美元号结尾。即用双美元号&lt;code&gt;$$&lt;/code&gt;把公式围起来。亦可用&lt;code&gt;[&lt;/code&gt;latex&lt;code&gt;][&lt;/code&gt;/latex&lt;code&gt;]&lt;/code&gt;这对标签把公式围起来。这对标签这里的公式描述用了 asciiMath语法. n choose k即一个组合。在网上搜索相关语法参考。&lt;/p&gt;
&lt;p&gt;在这个页面可以看到更多用MathJax显示的数学公式的例子，用浏览器的查看源代码功能(ctrl-u)查看使用的语法：&lt;br&gt;
使用LaTex语法： &lt;a href=&#34;http://ykyi.net/zausiu/MathJax-2.7.5/test/sample.html&#34;&gt;http://ykyi.net/zausiu/MathJax-2.7.5/test/sample.html&lt;/a&gt;{.wp-editor-md-post-content-link}&lt;br&gt;
使用AsciiMath语法： &lt;a href=&#34;http://ykyi.net/zausiu/MathJax-2.7.5/test/sample-asciimath.html&#34;&gt;http://ykyi.net/zausiu/MathJax-2.7.5/test/sample-asciimath.html&lt;/a&gt;{.wp-editor-md-post-content-link}&lt;br&gt;
使用MathML语法：&lt;a href=&#34;http://ykyi.net/zausiu/MathJax-2.7.5/test/sample-mml.html&#34;&gt;http://ykyi.net/zausiu/MathJax-2.7.5/test/sample-mml.html&lt;/a&gt;{.wp-editor-md-post-content-link}&lt;/p&gt;</description>
    </item>
    <item>
      <title>C/C&#43;&#43;用万恶的libcurl透过HTTPS发POST&#43;JSON请求</title>
      <link>https://ykyi.net/?p=1454/</link>
      <pubDate>Thu, 21 Jun 2018 02:22:04 +0000</pubDate>
      <guid>https://ykyi.net/?p=1454/</guid>
      <description>&lt;p&gt;相比python, nodejs这样的脚本开发语言已有非常好用的RESTful开发库，很多C/C++程序在调用RESTful接口时，还在使用非常难使用的libcurl纯C接口。下面是用libcurl透过HTTPS发POST请求的代码代段，http body是json字符串：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;&#34;&gt;    #include &amp;lt;curl/curl.h&amp;gt;

    CURL* curl;
    struct curl_slist* headers;
    curl = curl_easy_init();
    headers_ = curl_slist_append(headers, &#34;Content-Type: application/json&#34;);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, &#34;PEM&#34;);
    curl_easy_setopt(curl, CURLOPT_SSLCERT, cert_file_path.c_str());
    curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, &#34;PEM&#34;);
    curl_easy_setopt(curl, CURLOPT_SSLKEY, key_file_path.c_str());
    curl_easy_setopt(curl, CURLOPT_CAINFO, ca_file_path.c_str());
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, -1L);

    // jv_text存了json字符串
    curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, jv_text.c_str());
    curl_easy_setopt(curl_, CURLOPT_URL, path.c_str());

    CURLcode res = curl_easy_perform(curl_);
    if (res != CURLE_OK)   // 没有成功
    {
        LG_ERR(&#34;curl_easy_perform() failed: %s&#34;, curl_easy_strerror(res));
    }
    else  // 成功了
    {
    }
    curl_easy_cleanup(curl);
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>openssl签发证书肘后备急方（cheatsheet）</title>
      <link>https://ykyi.net/?p=1446/</link>
      <pubDate>Wed, 20 Jun 2018 07:03:11 +0000</pubDate>
      <guid>https://ykyi.net/?p=1446/</guid>
      <description>&lt;h3 id=&#34;生成一对新的rsa非对称密钥2048bits长-generate-an-rsa-private-key&#34;&gt;生成一对新的RSA非对称密钥,2048bits长。 generate an RSA private key&lt;/h3&gt;
&lt;p&gt;openssl genrsa -out private.key 2048&lt;/p&gt;
&lt;h3 id=&#34;从私钥中提出公钥-extract-the-public-key&#34;&gt;从私钥中提出公钥。 extract the public key&lt;/h3&gt;
&lt;p&gt;openssl rsa -in mykey.pem -pubout &amp;gt; my_pubkey.pub&lt;/p&gt;
&lt;h3 id=&#34;创建自签名证书create-a-self-singned-certificate&#34;&gt;创建自签名证书。create a self-singned certificate&lt;/h3&gt;
&lt;p&gt;openssl req -config openssl.conf -x509 -sha256 -days 3650 -newkey rsa:4096 -keyout ca.key -out ca.crt&lt;/p&gt;
&lt;h3 id=&#34;签署csrsign-the-csr&#34;&gt;签署CSR。sign the CSR&lt;/h3&gt;
&lt;p&gt;openssl ca -config openssl.conf -days 375 -notext -in test.csr -out test.crt&lt;/p&gt;
&lt;h3 id=&#34;检验签书verify-the-certificate&#34;&gt;检验签书。verify the certificate&lt;/h3&gt;
&lt;p&gt;openssl verify -CAfile ca.crt test.crt&lt;/p&gt;
&lt;h3 id=&#34;生成一个csrgenerate-a-new-private-key-and-csrcertificate-signing-request&#34;&gt;生成一个CSR。Generate a new private key and CSR(Certificate Signing Request)&lt;/h3&gt;
&lt;p&gt;openssl req -config openssl.conf -out CSR.csr -nodes -new -newkey rsa:2048 -nodes -keyout private.key&lt;/p&gt;</description>
    </item>
    <item>
      <title>nginx架设HTTP服务器接受PUT方法上传文件</title>
      <link>https://ykyi.net/?p=1439/</link>
      <pubDate>Tue, 27 Mar 2018 08:46:21 +0000</pubDate>
      <guid>https://ykyi.net/?p=1439/</guid>
      <description>&lt;p&gt;最近用nginx架了个http服务器，通过http上传文件。&lt;br&gt;
nginx的配置如下：&lt;/p&gt;
&lt;pre class=&#34;line-numbers prism-highlight&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-null&#34;&gt;        location ~ ^/wraith {
            root /data/tmp;
            dav_methods PUT;
            dav_access user:r group:r all:r;
            create_full_put_path on;

            limit_except GET {
            }
        }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如上，子目录/wraith将接受PUT方法。&lt;/p&gt;
&lt;pre class=&#34;line-numbers prism-highlight&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-null&#34;&gt;$curl -XPUT --data-binary @${TAR_PATH} --noproxy &#39;*&#39;  http://xxx.xxx.xxx.xxx/wraith/${TAR_FILE}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如上用curl通过http上传文件到服务器的/data/tmp目录下，文件命名为${TAR_FILE}&lt;/p&gt;</description>
    </item>
    <item>
      <title>utf8中文字符串的多模式匹配算法的优化</title>
      <link>https://ykyi.net/?p=1430/</link>
      <pubDate>Mon, 20 Nov 2017 08:44:25 +0000</pubDate>
      <guid>https://ykyi.net/?p=1430/</guid>
      <description>&lt;h1 id=&#34;utf8中文字符串的多模式匹配算法的优化&#34;&gt;utf8中文字符串的多模式匹配算法的优化&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;信息安全部接口组 kamuszhou@tencent.com&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;效果&#34;&gt;效果&lt;/h2&gt;
&lt;p&gt;本节仅展示优化效果，对一些业务逻辑和背景未做解释，读者可直接跳至下一节。&lt;br&gt;
上个月接触到了我组的一个关于在海量文本中匹配字符串业务。读源代码时发现一些问题，并针对这些问题做了优化工作，效果非常明显。&lt;/p&gt;
&lt;p&gt;测试的硬件环境是只用一颗主频2.4G的Intel至强处理器核心。OS是tlinux2。该业务目前载入11万3千条规则。优化前后的效果如下：&lt;/p&gt;
&lt;p&gt;|载入 | 旧算法 |旧算法简版| 新算法 | 提升效果 |&lt;br&gt;
|:—:|:——:|:——–:|:——-:|:——-:|&lt;br&gt;
|速度 | 26分钟 | 3分钟 | 3秒 |60倍或250倍|&lt;br&gt;
|内存 | 4327M | 4327M | 不到200M| 20倍 |&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;表中的“旧算法简版”指去掉了一个繁琐的预计算步骤&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;|处理速度 | 旧算法 | 新算法 | 提升效果 |&lt;br&gt;
|:—:|:——:|:——–:|:——-:|&lt;br&gt;
|用11万3千条规则作为待检测文本|52秒|2秒|26倍|&lt;br&gt;
|10倍四大名著共88M,平均每行143个汉字|59秒|10秒|近6倍|&lt;br&gt;
|文字选自四大名著共87M,平均每行10个汉字|161秒|5秒|32倍|&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;用11万3千条规则作为待检测文本使得新旧算法都会密集地走到“命中逻辑”，旨在比较“命中逻辑”的性能。&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;用四大名著作为待检测文本，使得新旧算法几乎不会走到“命中逻辑”，旨在比较算法处理正常文本时的性能。而每次处理文本的长度亦可能影响到性能表现。如表所示，处理短文本（10个汉字）时，新算法的优势有所降低，可解释为旧算法为启动每一次处理消耗较大的资源，而如果处理的文本较长时，这个资源消耗分摊到每个待处理字符就相对不那么明显了。&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在一台24核的M2机器上，理论估计新算法一天可以处理36,495,360M文本，36个T~&lt;/p&gt;
&lt;h2 id=&#34;业务简述&#34;&gt;业务简述&lt;/h2&gt;
&lt;p&gt;该业务的核心问题简单地近似概括为：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;有几十万甚至更多的模式(短字符串)集合P={P1, P2, …, Pn}，输入一个utf8编码的字符串string，输出有哪些模式Px在string中出现。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;实际问题比上面的描述稍微复杂一点点。业务需要通过找到的模式判断是否命中预定的规则。一个模式串或多个模式都可以组成规则。比如，单独的一个Px组成一条规则，多个不同的模式则会组合成一个 &lt;strong&gt;与&lt;/strong&gt; 关系的规则（目前业务只支持与关系，支持更复杂的匹配规则是将来需要增强的地方）。比如，有下面几条规则：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;铁王座&lt;/li&gt;
&lt;li&gt;雪诺 &amp;amp; 提利昂&lt;/li&gt;
&lt;li&gt;雪诺 &amp;amp; 艾莉亚 &amp;amp; 2&lt;/li&gt;
&lt;li&gt;雪诺 &amp;amp; 龙母 &amp;amp; 床&lt;/li&gt;
&lt;li&gt;雪诺 &amp;amp; 夜王 &amp;amp; 异鬼军团 &amp;amp; 守夜人&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;下文的讨论将继续引用这个规则列表。&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>服务器端的tcp有大量TIME_WAIT怎么办</title>
      <link>https://ykyi.net/?p=1409/</link>
      <pubDate>Fri, 20 Oct 2017 06:03:06 +0000</pubDate>
      <guid>https://ykyi.net/?p=1409/</guid>
      <description>&lt;p&gt;公司的群里讨论tcp的TIME_WAIT的问题。TIME_WAIT这个状态可是面试时经常问的知识点啊。&lt;br&gt;
讨论的问题是：有一个服务器，它对外网提供服务，同时它作为客户端连接很多后端的其它服务器。这位同事连后端其它服务器时用了短tcp连接。结果出现了大量的tcp TIME_WAIT状态，吞吐量上不去，怎么办？&lt;/p&gt;
&lt;p&gt;先说结论：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如果该服务器要处理外网IP的入流量，那最好的办法应该是用tcp长链接改造它与后端服务器的连接。如果用中间件，比如上zeromq那更省心了。&lt;/li&gt;
&lt;li&gt;如果不想做改动，并且在应用层确认已经交互已经完成，则可以用shutdown()直接发RST结束tcp会话，而不走正常的4次挥手。查阅shutdown系统调用的文档获知如何发RST。&lt;/li&gt;
&lt;li&gt;如果该服务器不需要处理处网IP请求的话，那么，启用port reuse 即打开net.ipv4.tcp_tw_reuse不会有太大问题(如果处理外网请求就有问题，和NAT相关，见&lt;a href=&#34;https://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux&#34;&gt;https://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux&lt;/a&gt;)，或者更好的，把/proc/sys/net/ipv4/tcp_fin_timeout改小，改成1或者2。让TIME_WAIT只保持很短的时间。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;首先，需要知道一个tcp会话由 src_ip, src_port, dest_ip, dest_port 四元组确定。&lt;br&gt;
我们公司的IDC环境中， 上述的服务器作为客户端再发起tcp连接联后端服务器，则 src_ip 固定了， dest_ip是后端服务器的ip, port是后端服务器监听端口。这样只有 src_port 是可变化的，但port只有16个bits还不能用well-known ports，这样就更少了。&lt;/p&gt;
&lt;p&gt;再说，主动关闭时，tcp连接需要进入TIME_WAIT状态，保持两倍MSL时长，是为了处理两种情况：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;让当前这个会话的迷路包在网路中消失。这样不会干扰到新建的会话。&lt;/li&gt;
&lt;li&gt;确保主动关闭方的FIN-ACK包，如果丢失的话，还能重发。&lt;br&gt;
1981年的TCP RFC上把MSL设成两分钟，https://tools.ietf.org/html/rfc793&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Maximum Segment Lifetime, the time a TCP segment can exist in&lt;br&gt;
the internetwork system. Arbitrarily defined to be 2 minutes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;MSL设置这么长，因为以前的网络环境差啊。不过现在因为移动互联网，比较差的网络状态也是非常常见的。但RFC允许实现方减少MSL值。事实上linux的MSL写死在代码中为1分钟并且不可在运行期配置。&lt;br&gt;
如果tcp连接的双方都在性能高速稳定的内网中，这个MSL就太长了。&lt;/p&gt;
&lt;p&gt;调试时，还发现如果port用完了，connect的时候内核代码会用自旋锁忙等检查port资源。有linux内核开发基础的开发者都知道spin_lock的时候是不会让出cpu的，于是cpu全被spin_lock吃掉了。一直要等到有port被释放。再后来又发现，如果scoket没有设定SO_REUSEADDR选项，则connect()系统调用会返回EADDRINUSE。&lt;/p&gt;
&lt;p&gt;tcp的连接双方都是确定且长期的，用什么tcp短连接呢？？改造吧~~~&lt;/p&gt;</description>
    </item>
    <item>
      <title>用lftp为ftp服务器做镜像</title>
      <link>https://ykyi.net/?p=1401/</link>
      <pubDate>Wed, 27 Sep 2017 11:54:46 +0000</pubDate>
      <guid>https://ykyi.net/?p=1401/</guid>
      <description>&lt;h3 id=&#34;用lftp为ftp服务器做镜像&#34;&gt;用lftp为ftp服务器做镜像&lt;/h3&gt;
&lt;p&gt;命令是这样的:&lt;/p&gt;
&lt;pre class=&#34;line-numbers prism-highlight&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-null&#34;&gt;$ lftp -d -u user_name,password ftp_server_host -e &#34;mirror -c -e --parallel=5 / /path/to/mirror&#34;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解释一下这里的选项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;-d 调试模试，看到详细的输出&lt;/li&gt;
&lt;li&gt;-u 用户名和密码，用,隔开&lt;/li&gt;
&lt;li&gt;-e 让lftp执行lftp自有的一些命令&lt;/li&gt;
&lt;li&gt;mirror 执行做镜像命令&lt;/li&gt;
&lt;li&gt;-c continue a mirror job if possible 继续做镜像，如果可能的话。难道不用这个选项，做镜像的过程有可能被中断？&lt;/li&gt;
&lt;li&gt;-e 如果一个文件在ftp站点上没有，但在本机上有，则删除这个文件&lt;/li&gt;
&lt;li&gt;–parallel 并发数&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&lt;br&gt;
mirror 命令还有一个 -R 参数，这样的话，会put文件到ftp服务器，效果和上例相反。&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>访问ES最简单示例</title>
      <link>https://ykyi.net/?p=1388/</link>
      <pubDate>Fri, 25 Aug 2017 03:32:09 +0000</pubDate>
      <guid>https://ykyi.net/?p=1388/</guid>
      <description>&lt;p&gt;这些天架了一个ES集群，用来分析积累了海量日志数据。我用sphinx写了一个简单文档，发布在内网。下面是复制过来的部分内容，不幸的是很多格式信息都丢失了。做了点简单修改，去掉了敏感信息。&lt;/p&gt;
&lt;p&gt;///////////////////////////////////////////////////////////&lt;/p&gt;
&lt;p&gt;本示例仅示范最为基础的应用，协助读者调通最简单的查询。 详细灵活的使用方法非本文档能够覆盖，需参见官方详细文档或咨询你常用的搜索引擎。&lt;/p&gt;
&lt;ol class=&#34;arabic simple&#34;&gt;
  &lt;li&gt;
    使用&lt;span class=&#34;highlighted&#34;&gt;curl&lt;/span&gt;命令行工具
  &lt;/li&gt;
  &lt;li&gt;
    使用es官方python库 &lt;ol class=&#34;arabic&#34;&gt;
      &lt;li&gt;
        RESTful接口
      &lt;/li&gt;
      &lt;li&gt;
        官方python库
      &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;
&lt;div id=&#34;curl&#34; class=&#34;section&#34;&gt;
  &lt;h2&gt;
    使用&lt;span class=&#34;highlighted&#34;&gt;curl&lt;/span&gt;命令行工具
  &lt;/h2&gt;
  &lt;div class=&#34;line-block&#34;&gt;
    &lt;div class=&#34;line&#34;&gt;
      NOTICE:
    &lt;/div&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;line&amp;quot;&amp;gt;
  [*略去较为敏感的鉴权部分*]
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
  &lt;div class=&#34;line-block&#34;&gt;
  &lt;/div&gt;
  &lt;ul class=&#34;simple&#34;&gt;
    &lt;li&gt;
      在访问日志中检索一个keyword，无论keyword出现在哪个字段中。 如下示例：所有文档，superuser出现在其中任意字段中都会被召回。注意酌情更换URI中的参数。 实际上，把_all替换成user_name，则只在user_name字段中检索。这里使用的是lucene语法， 参见：&lt;a class=&#34;reference external&#34; href=&#34;https://lucene.apache.org/core/2_9_4/queryparsersyntax.html&#34;&gt;https://lucene.apache.org/core/2_9_4/queryparsersyntax.html&lt;/a&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;div class=&#34;highlight-bash&#34;&gt;
    &lt;table class=&#34;highlighttable&#34;&gt;
      &lt;tr&gt;
        &lt;td class=&#34;linenos&#34;&gt;
          &lt;div class=&#34;linenodiv&#34;&gt;
            &lt;pre&gt;1&lt;/pre&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class=&#34;code&#34;&gt;
  &lt;div class=&#34;highlight&#34;&gt;
    &lt;pre&gt;&lt;span class=&#34;highlighted&#34;&gt;curl&lt;/span&gt; https://endpoint/_search?q&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;_all:superuser
&lt;/pre&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;ul class=&#34;simple&#34;&gt;
  &lt;li&gt;
    使用ES的DSL语法，在访问日志中检索出现在指定字段中的keyword。 如下示例：superuser出现在user_name字段中。
  &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight-bash&#34;&gt;
  &lt;table class=&#34;highlighttable&#34;&gt;
    &lt;tr&gt;
      &lt;td class=&#34;linenos&#34;&gt;
        &lt;div class=&#34;linenodiv&#34;&gt;
          &lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10&lt;/pre&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class=&#34;code&#34;&gt;
  &lt;div class=&#34;highlight&#34;&gt;
    &lt;pre&gt;&lt;span class=&#34;highlighted&#34;&gt;curl&lt;/span&gt; https://endpoint/_search?pretty -H &lt;span class=&#34;s2&#34;&gt;&#34;Content-Type: application/json&#34;&lt;/span&gt; -X POST -d &lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;   &#34;query&#34;:{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;       &#34;bool&#34;:{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;             &#34;filter&#34;:[&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;                 { &#34;term&#34;:{ &#34;user_name&#34;: &#34;superuser&#34; } }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;             ]&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;       }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;   }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;}&#39;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;
  上述检索方法使用了ES中的filter语法，filter是较快的一种查询方式。如果需要检索的字段需要分词，则只能使用 match语法，如下：
&lt;/p&gt;
&lt;div class=&#34;highlight-bash&#34;&gt;
  &lt;table class=&#34;highlighttable&#34;&gt;
    &lt;tr&gt;
      &lt;td class=&#34;linenos&#34;&gt;
        &lt;div class=&#34;linenodiv&#34;&gt;
          &lt;pre&gt;1
2
3
4
5
6
7
8&lt;/pre&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class=&#34;code&#34;&gt;
  &lt;div class=&#34;highlight&#34;&gt;
    &lt;pre&gt;&lt;span class=&#34;highlighted&#34;&gt;curl&lt;/span&gt; ./kamus.key https://endpoint/_search?pretty -H &lt;span class=&#34;s2&#34;&gt;&#34;Content-Type: application/json&#34;&lt;/span&gt; -X POST -d &lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;   &#34;query&#34;:{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;       &#34;match&#34;:{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;             {&#34;user_name&#34;: &#34;superuser&#34;}&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;       }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;   }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;}&#39;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;ul class=&#34;simple&#34;&gt;
  &lt;li&gt;
    为检索增加时间限制 如需要指定时间区间：
  &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight-bash&#34;&gt;
  &lt;table class=&#34;highlighttable&#34;&gt;
    &lt;tr&gt;
      &lt;td class=&#34;linenos&#34;&gt;
        &lt;div class=&#34;linenodiv&#34;&gt;
          &lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20&lt;/pre&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class=&#34;code&#34;&gt;
  &lt;div class=&#34;highlight&#34;&gt;
    &lt;pre&gt;&lt;span class=&#34;highlighted&#34;&gt;curl&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;https://endpoint/_search?pretty&#34;&lt;/span&gt; -d &lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  &#34;query&#34;:{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;       &#34;bool&#34;:{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;               &#34;must&#34;:{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;                    &#34;match&#34;:{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;                                &#34;user_name&#34;:&#34;superuser&#34;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;                            }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;               },&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;               &#34;filter&#34;:{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;                     &#34;range&#34;:{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;                          &#34;req_time&#34;:{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;                                        &#34;gte&#34;:&#34;2017-01-01 00:00:00&#34;,&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;                                        &#34;lt&#34;:&#34;2017-08-08 00:00:00&#34;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;                                     }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;                       }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;                }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;        }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;} &#39;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;ul class=&#34;simple&#34;&gt;
  &lt;li&gt;
    分页 ES的分页使用”from”和”size”参数。例如，每页10条，返回第1页。
  &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight-bash&#34;&gt;
  &lt;table class=&#34;highlighttable&#34;&gt;
    &lt;tr&gt;
      &lt;td class=&#34;linenos&#34;&gt;
        &lt;div class=&#34;linenodiv&#34;&gt;
          &lt;pre&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11&lt;/pre&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td class=&#34;code&#34;&gt;
  &lt;div class=&#34;highlight&#34;&gt;
    &lt;pre&gt;&lt;span class=&#34;highlighted&#34;&gt;curl&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;https://endpoint/_search?pretty&#34;&lt;/span&gt;  -d &lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;     &#34;from&#34;: 0,&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;     &#34;size&#34;: 10,&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;     &#34;query&#34;: {&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;         &#34;term&#34;: {&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;              &#34;user_name&#34;: &#34;superuser&#34;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;         }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;     }&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;
  由于ES的实现机制，ES并不鼓励使用分页，在size较大且from的页码也较大时，ES可能无法及时响应。
&lt;/p&gt;
&lt;ul class=&#34;simple&#34;&gt;
  &lt;li&gt;
    如果需要返回所有命中文档 如果命中文档超过一千，用上述方法不容易拿到所有结果。需要使用 &lt;strong&gt;scroll and scan&lt;/strong&gt; 方法。 参见 &lt;a class=&#34;reference external&#34; href=&#34;https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html&#34;&gt;https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html&lt;/a&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;line-block&#34;&gt;
&lt;/div&gt;
&lt;ul class=&#34;simple&#34;&gt;
  &lt;li&gt;
    其他高级应用 如bool操作，以及复杂灵活的查询条件组合请参加官网文档。
  &lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>It’s not lupus 是个什么梗，什么意思呢</title>
      <link>https://ykyi.net/?p=1379/</link>
      <pubDate>Thu, 03 Aug 2017 03:08:55 +0000</pubDate>
      <guid>https://ykyi.net/?p=1379/</guid>
      <description>&lt;p&gt;著名黑客于旸, AKA tkyu, tk教主在论坛里的头像是一个狰狞面孔的人，头像下面有一行英文：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It’s not Lupus&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这句话是什么意思呢？原来来自2007年福克斯Fox的一部电视连续剧 &lt;a href=&#34;http://knowyourmeme.com/memes/it-s-not-lupus&#34;&gt;House&lt;/a&gt;。&lt;br&gt;
剧中主人公是普林斯敦大学教学医院的医学天才(Dr. House)，他反传统并且不愿意与人交往。他的工作伙伴是一些年轻的医生。&lt;br&gt;
年轻的医生在搞不清楚病人发病原因的时候，就认为这可能是Lupus(狼疮)。因为Lupus这个病需要好几年才能够被确诊。这时，Dr House就说： “It’s not lupus”或“It’s never lupus”。直到有一天，确实出现了一个Lupus案例。&lt;br&gt;
我猜，tk教主引用_It’s not Lupus_这句话可能暗指他也是Dr House一样的天才吧~&lt;/p&gt;</description>
    </item>
    <item>
      <title>发现linux命令/工具find的一个”bug”</title>
      <link>https://ykyi.net/?p=1375/</link>
      <pubDate>Wed, 02 Aug 2017 08:02:19 +0000</pubDate>
      <guid>https://ykyi.net/?p=1375/</guid>
      <description>&lt;p&gt;今天用find命令找一个目录下面所有大小小于1K的普通文件. 我的命令是这么写的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ find ~ -type f -a -size -1K | wc -l
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;发现得到的数字明显比预想的小很多。但命令没错呀&lt;del&gt;百思不得其解之下，又试了一下另一种写法。这时，就正常了，真奇怪啊&lt;/del&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ find ~ -type f -a -size -1024c | wc -l
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这次就正常了！！！&lt;br&gt;
我反复查文档：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;c for bytes&lt;br&gt;
K for Kilobytes (units of 1024 bytes)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对啊&lt;del&gt;没错啊。 1K就是1024byte。哪里出问题了，哪出出错了呢？难道是linux的bug吗？我换了一个发行版的linux，发现还是同样的情况。这就郁闷了&lt;/del&gt;&lt;br&gt;
再次查看文档，这次详细读文档了！终于发现问题所在了：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The + and – prefixes signify greater than and less than, as usual. Bear in mind that the size is rounded up to the next&lt;br&gt;
unit. Therefore -size -1M is not equivalent to -size -1048576c. The former only matches empty files, the latter matches&lt;br&gt;
files from 1 to 1,048,575 bytes.&lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>读吴军的”硅谷来信：第230封 为什么中国不会掉入中等收入陷阱”之疑惑</title>
      <link>https://ykyi.net/?p=1362/</link>
      <pubDate>Sun, 04 Jun 2017 04:58:25 +0000</pubDate>
      <guid>https://ykyi.net/?p=1362/</guid>
      <description>&lt;p&gt;吴军是我很佩服的一位科学家兼科技作家。他的学误之渊博，让人惊叹。&lt;/p&gt;
&lt;p&gt;最近，我看了吴军大神的”硅谷来信：第230封 为什么中国不会掉入中等收入陷阱”。这篇文章分上，下两篇。下篇的末段部分提到一个针对“缩小国有企业规模”的观点，原文如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;缩小国有企业规模。这件事不需要做，虽然中国的国有企业相比一些明星私营企业显得效率低一些，但是人均产值依然&lt;br&gt;
高过私营企业的平均水平。更重要的是，国有企业是目前中国经济走向世界的排头兵，因为它们可以不计成本地向海外扩张。&lt;br&gt;
相比之下，中国私营企业除了华为、联想等少数企业，大部分私营老板是舍不得自己掏腰包，对走&lt;br&gt;
向世界进行长期大规模投资的。所谓的BAT（百度、阿里巴巴、腾 讯）虽然自己挣钱不少，但依然&lt;br&gt;
是窝里横的公司，而且直到今天也没有认认真真做国际化的事情。这些公司尚且指望不上，何况其它私营企业了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这段话有相当多的问题：&lt;/p&gt;
&lt;h1 id=&#34;国企人均产值依然高过私营企业平均水平&#34;&gt;国企人均产值依然高过私营企业平均水平。&lt;/h1&gt;
&lt;p&gt;注意，这里是人均产值，不是企业效率。国有企业垄断占据了几乎所有赚钱的行业：烟草，金融，能源，电信，人均产值能不高吗？但如果比生产效率呢？&lt;/p&gt;
&lt;h1 id=&#34;国企可以不计成本地向海外扩张&#34;&gt;国企可以不计成本地向海外扩张。&lt;/h1&gt;
&lt;p&gt;“不计成本”地扩张？？成本100美元，卖10美元？？？不计成本是好事吗？民营企业卖扣子卖眼镜卖衬衣卖打火机辛苦积累的外汇，国企不计成本的挥霍，难道是好事，不应该是国企的缺点吗？&lt;/p&gt;
&lt;h1 id=&#34;吴军大神认为私营企业不做海外扩张但吴大神先排除掉华为联想&#34;&gt;吴军大神认为私营企业不做海外扩张，但吴大神先排除掉华为联想&lt;/h1&gt;
&lt;p&gt;2000年以后，满世界的made in china的小商品，难道不是私营企业做的？&lt;br&gt;
华为，联想是民企的代表企业，特别是华为，为何华为联想不算数？十五年前，同在深圳的民企华为和国企中兴尚且在同一量级，如今，民企华为的体量可是中兴的十倍之巨还多。&lt;br&gt;
那不说华为，联想。小米，oppo，vivo们在南亚，东南亚把三星打得满地找牙，算不算民企的海外扩张。制造业的“三一重工”算不算私营企业，可搜索新闻“三一重工强攻新兴市场，海外收入占比升至50%”，这还是三年前，2014年的数据。&lt;br&gt;
大疆几乎吃下了全世界民用无人机市场，算不算海外扩张么。&lt;br&gt;
再说一家小而美的互联网公司，猎豹移动，这家公司的海外营收可超过了70%。&lt;br&gt;
还有当下火热的共享单车。ofo,mobike们刚起步就已经把业务扩张到了北美和欧洲。&lt;br&gt;
中小型公司里积极开拓海外市场的并不在少数吧。吴大神装做不知道？&lt;/p&gt;
&lt;p&gt;况且该文的中段有提到&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你只能看到中国的商人去拉美 国家上门买酒，看不见他们的商人到中国推销酒。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;又有：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;中国的商人往返于世界各地，积极开拓海外市场。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这里提到的中国商人不多是民营企业家吗，难道都是国企高官？如果这里的商人多指私营企业家，那作者的观点岂不是前后矛盾。&lt;/p&gt;
&lt;h1 id=&#34;所谓的bat百度阿里巴巴腾-讯虽然自己挣钱不少但依然是窝里横的公司而且直到今天也没有认认真真做国际化的事情&#34;&gt;所谓的BAT（百度、阿里巴巴、腾 讯）虽然自己挣钱不少，但依然是窝里横的公司，而且直到今天也没有认认真真做国际化的事情。&lt;/h1&gt;
&lt;p&gt;互联网先在美国繁荣发展，国内互联网公司的前步较晚。在最初期，BAT们刚刚出生，尚且为了生存，忙于和在华的巨头微软，谷哥，亚马逊，雅虎，ebay激烈竞争。不能苛求国内市场还没占领就海外扩张吧？&lt;br&gt;
那看现在，百度在硅谷成立了AI实验室，腾讯在西雅图微软的大门口也成立AI实验室与微软直接竞争，阿里云在世界范围内力战亚马逊算不算海外扩张？&lt;br&gt;
更不用说BAT的海外资本运作了，腾讯在2000年前就投资了Roit Games开发出世界第一网游LOL，去年收购super cell，今年入股tesla，算不算海外扩张？BAT的海外投资比比皆是。&lt;/p&gt;
&lt;h1 id=&#34;bat尚且指望不上何况其它私企&#34;&gt;BAT尚且指望不上，何况其它私企&lt;/h1&gt;
&lt;p&gt;退一万步，假设BAT确实没有任何出海商业活动，“何况其它私企”这句话的逻辑在哪？BAT只能代表互联网行业，而私营企业长满了国内每个允许民资进入的行业。BAT能代表他们吗？&lt;/p&gt;
&lt;p&gt;我想，一定是因为吴军高贵的谷歌血统，狗眼看人低。和谷歌比，国内的民营企业家们，都是泥腿子，吴军就是看不起你！&lt;/p&gt;</description>
    </item>
    <item>
      <title>我理解的区块链技术</title>
      <link>https://ykyi.net/?p=1349/</link>
      <pubDate>Tue, 16 May 2017 12:01:10 +0000</pubDate>
      <guid>https://ykyi.net/?p=1349/</guid>
      <description>&lt;p&gt;同事叫我写点对区块链的看法。我大概在四年前比特币火热的时候看了一些相关的资料，就随便写一点吧。&lt;/p&gt;
&lt;h1 id=&#34;blockchain-technology&#34;&gt;Blockchain Technology&lt;/h1&gt;
&lt;h2 id=&#34;什么是区块链&#34;&gt;什么是区块链&lt;/h2&gt;
&lt;p&gt;区块链技术最早可追述到1991年 by Stuart Haber &amp;amp; W. Scott Stornetta.&lt;br&gt;
以2008年Satoshi Nakamoto对区块链技术的阐述及第二年2009年创建了比特币&lt;br&gt;
标志了区域链技术的成熟。&lt;br&gt;
维基百科给出的定义是:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A distributed database that maintains a continuously growing&lt;br&gt;
list of records, called blocks, secured from tampering and revision.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;区块链是一个分布式的数据库。它的数据被组织成不断增长的记录链表。&lt;br&gt;
其中记录被称为“区块”。区块被加密，保证不被篡改。&lt;/p&gt;
&lt;p&gt;以BitCoin举例:&lt;br&gt;
比特币是一个巨大的分布式的记账系统，该分布式系统的每一个结点都记录了在&lt;br&gt;
比特币网络上发生的每一笔交易。如果要篡改数据，除非能控制这个网络上的绝&lt;br&gt;
大部分结点并且同时修改这些结点的相关加密数据。&lt;/p&gt;
&lt;h2 id=&#34;关键技术&#34;&gt;关键技术&lt;/h2&gt;
&lt;p&gt;区块链技术最大的创新即在一个&lt;strong&gt;去中心化&lt;/strong&gt;的系统中解决了数字货币的Double Spending&lt;br&gt;
的问题。&lt;/p&gt;
&lt;p&gt;更一般地讲：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;区域链技术使用去中心化网络解决了之前需要中心服务器的计账问题&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;what-is-double-spending&#34;&gt;What is Double Spending&lt;/h4&gt;
&lt;p&gt;如果我们用实物货币交易，交易的任何一方不能同时拥有商品和实物货币。但数字货币&lt;br&gt;
却是可以通过非常廉价地复制获得。在区块链技术出现之前，解决这个问题都是用一个&lt;br&gt;
中心机构解决。交易参与方无条件信任这个中心机构，由它判断并决定某个数字货币的归属。&lt;br&gt;
显然这里有一个单点故障的潜在危险。&lt;/p&gt;
&lt;h2 id=&#34;使用常景&#34;&gt;使用常景&lt;/h2&gt;
&lt;p&gt;最大的使用常景还是金融领域，比如数字货币和银行间的清算系统。&lt;br&gt;
对于任何涉及&lt;strong&gt;信任，计账，审计，防篡改&lt;/strong&gt;的系统，都可以用区块链技术提供一个去中心的&lt;br&gt;
实现，而不是传统地信任一个中心机构的解决方案。&lt;br&gt;
比如一个基于区块链技术的全民投票系统。&lt;/p&gt;
&lt;h2 id=&#34;未来发展&#34;&gt;未来发展&lt;/h2&gt;
&lt;p&gt;据埃森哲的数据，2016年区域链技术在金融的项目中领域获得了13.5%的采用率，进入初期采用&lt;br&gt;
阶段，于2018-2024年进入快速增长阶段，2025年进入成熟期。&lt;br&gt;
&lt;a href=&#34;https://www.raconteur.net/business/the-future-of-blockchain-in-8-charts&#34;&gt;The future of blockchain in 8 charts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在我看来，区块链技术只在金融领域有很大的发展前景，而在其它领域则没有什么优势。理由是，区块链技术的一个重要假设是：不能信任一个权威的中心服务方。但在大多数场景中，引入一个权威的中心服务方是可以接受的有时还是必须的，且开发难度要低。&lt;/p&gt;</description>
    </item>
    <item>
      <title>如何战胜抑郁症</title>
      <link>https://ykyi.net/?p=1343/</link>
      <pubDate>Tue, 16 May 2017 11:43:43 +0000</pubDate>
      <guid>https://ykyi.net/?p=1343/</guid>
      <description>&lt;p&gt;一篇关于抑郁症的建议：&lt;/p&gt;
&lt;p&gt;我的抑郁症持续了比较长的时间，大概从2007年到2014年之间断断续续发作。&lt;br&gt;
最终在2014年年初慢慢走出来。现在几乎不失眠了。&lt;br&gt;
我在发病期间看了非常多的资料，找很多人聊天。思考怎么治好这该死的病。&lt;br&gt;
据我了解，现代医学对抑郁症的发病原因还没有研究得很透，认为非常非常多的因素都会造成抑郁症包括遗传。对病理的研究更是很肤浅，毕竟现代科学对大脑的工作方式还是知之甚少的。但各药厂生产了很多抗抑郁的药物，这些药物的效果因人而异。但基本上都不大可能单靠药物就能治好的。如果没能确定病因，没解决掉源头问题，怎么可能治好呢。但要找到病因却不容易，前面有提到，现代医学在这方面的研究还不够。所以，医生的帮助也是有限的。&lt;/p&gt;
&lt;p&gt;我的建议是：&lt;br&gt;
1，首先意识到治好这病需要自己付出很多努力，不能依赖其他人比如找到一个神医&lt;br&gt;
2，评估自己以前的处事方式，我以前对自己要求太严格，总是争分夺秒地不停学习。我给自己设了很多假想敌，总想超过他们。我觉得我中学时读书比你们厉害，我怎么能输给你。为了改变自己这个思维方式，我看了一些哲学思辨的书，还包括一点点宗教神学，主要是佛教。我试图让自己站在一个更大更高的视角看自己以前的工作生活思维方式有多少意义。最终我觉得我不应该有太多锋芒，对于整个宇宙来说，面对自然规律时，个人实在太渺小了。&lt;br&gt;
3，认识新朋友，主动社交。不要只认识精英。三教九流的人都去认识，和他们聊天，了解他们的生活和思考方式。精英阶层的思想大多是竞争进取的，如果自己的圈子都是精英，会让自己的思维局限于此，对治疗抑郁症是不利的。我那时租车搬家时就不失时间和面包车司机聊天，了解他们的生活状态，忧虑和幸福。不同阶层人的生活和思维是大不相同的。他们也要生活，他们也有自己的喜怒哀乐，为何自己自认为各方面都强过他们却生活得如此狼狈。我在2013年在网络上认识了一个粤北的农场主，我专门在假期去他的农场住了四五天，感受农场的宁静和那边的村民生活。&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>https://ykyi.net/?p=1327/</link>
      <pubDate>Tue, 17 Jan 2017 09:35:16 +0000</pubDate>
      <guid>https://ykyi.net/?p=1327/</guid>
      <description>&lt;h2 align=&#34;center&#34;&gt;
  &lt;span lang=&#34;EN-US&#34;&gt;1. &lt;/span&gt;前言：
&lt;/h2&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt; &lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt; &lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;ZeroMq aka zmq&lt;/span&gt;是最知名的网络消息中间件之一。使有&lt;span lang=&#34;EN-US&#34;&gt;zmq&lt;/span&gt;的开源软件中最知名的莫过于&lt;span lang=&#34;EN-US&#34;&gt;Apache&lt;/span&gt;基金会下的&lt;span lang=&#34;EN-US&#34;&gt;Storm&lt;/span&gt;。我厂内部使用&lt;span lang=&#34;EN-US&#34;&gt;zmq&lt;/span&gt;的有即通的&lt;span lang=&#34;EN-US&#34;&gt;yaaf&lt;/span&gt;框架。&lt;/p&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt;   ZMQ&lt;/span&gt;社区在&lt;span lang=&#34;EN-US&#34;&gt;2013&lt;/span&gt;年&lt;span lang=&#34;EN-US&#34;&gt;9&lt;/span&gt;月发布了&lt;span lang=&#34;EN-US&#34;&gt;zmq4&lt;/span&gt;。&lt;span lang=&#34;EN-US&#34;&gt;zmq4&lt;/span&gt;最大的新功能即提供了一套安全机制，其中有&lt;span lang=&#34;EN-US&#34;&gt;IP&lt;/span&gt;黑白名单，用户名&lt;span lang=&#34;EN-US&#34;&gt;/&lt;/span&gt;密码鉴权，&lt;span lang=&#34;EN-US&#34;&gt;ECC(Elliptic Curve Cryptography)&lt;/span&gt;证书鉴权，以及通讯的加密&lt;span lang=&#34;EN-US&#34;&gt;(&lt;/span&gt;类似&lt;span lang=&#34;EN-US&#34;&gt;TSL)&lt;/span&gt;。&lt;/p&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt;   &lt;/span&gt;本文主要介绍&lt;span lang=&#34;EN-US&#34;&gt;zmq4.0&lt;/span&gt;的安全机制。&lt;/p&gt;
&lt;h2 style=&#34;text-align: center;&#34;&gt;
  &lt;span lang=&#34;EN-US&#34;&gt;2. &lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;ECC&lt;/span&gt;的故事：
&lt;/h2&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt;   &lt;/span&gt;这里的&lt;span lang=&#34;EN-US&#34;&gt;ECC&lt;/span&gt;不是我厂历史上的电商事业群，而是椭圆曲线加密算法。&lt;span lang=&#34;EN-US&#34;&gt;ECC&lt;/span&gt;据说被&lt;span lang=&#34;EN-US&#34;&gt;NSA(&lt;/span&gt;美国安全局&lt;span lang=&#34;EN-US&#34;&gt;)&lt;/span&gt;操作，在算法中设置了后门。不过好在不是只有一种椭圆曲线，而是有无数种，不同的曲线有不同的优点和缺点，只是其中由&lt;span lang=&#34;EN-US&#34;&gt;NIST(&lt;/span&gt;美国标准和技术研究署&lt;span lang=&#34;EN-US&#34;&gt;)&lt;/span&gt;推荐的曲线被怀疑设置了后门。&lt;/p&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt;   ZMQ&lt;/span&gt;使用的椭圆曲线算法是&lt;span lang=&#34;EN-US&#34;&gt;&lt;a href=&#34;http://cr.yp.to/ecdh.html&#34;&gt;Curve25519&lt;/a&gt; ,&lt;/span&gt;它有开源实现而且没有专利保护。&lt;span lang=&#34;EN-US&#34;&gt;zmq&lt;/span&gt;用了长度为&lt;span lang=&#34;EN-US&#34;&gt;256bits&lt;/span&gt;的密钥，强度相当于&lt;span lang=&#34;EN-US&#34;&gt;RSA 3072&lt;/span&gt;比特的密钥长度。&lt;/p&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt;   ECDH(Elliptic Curve Diffie-Hellman)&lt;/span&gt;则是一个密钥协商协议。非常简单地讲，当&lt;span lang=&#34;EN-US&#34;&gt;A&lt;/span&gt;与&lt;span lang=&#34;EN-US&#34;&gt;B&lt;/span&gt;在一个不受信任的网络中通讯前，&lt;span lang=&#34;EN-US&#34;&gt;A&lt;/span&gt;和&lt;span lang=&#34;EN-US&#34;&gt;B&lt;/span&gt;先生成一对公私钥，并且&lt;span lang=&#34;EN-US&#34;&gt;A&lt;/span&gt;和&lt;span lang=&#34;EN-US&#34;&gt;B&lt;/span&gt;通过某个完全的渠道事先知道对方的公钥，然后&lt;span lang=&#34;EN-US&#34;&gt;A&lt;/span&gt;和&lt;span lang=&#34;EN-US&#34;&gt;B&lt;/span&gt;在握手阶段协商出一个双方公知的私钥供加密接下来的通讯。&lt;/p&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt;    &lt;/span&gt;可以理解成&lt;span lang=&#34;EN-US&#34;&gt;zmq&lt;/span&gt;设计了一个专门为自己定制的精简的&lt;span lang=&#34;EN-US&#34;&gt;TLS&lt;/span&gt;，更多的理论细节在&lt;span lang=&#34;EN-US&#34;&gt;&lt;a href=&#34;http://curvezmq.org/page:read-the-docs&#34;&gt;http://curvezmq.org/page:read-the-docs&lt;/a&gt;&lt;/span&gt;，&lt;/p&gt;
&lt;p&gt;作为一个码农，下面用代码介绍使用&lt;span lang=&#34;EN-US&#34;&gt;zmq4&lt;/span&gt;的Curve安全机制&lt;/p&gt;
&lt;h2 style=&#34;text-align: center;&#34;&gt;
  &lt;span lang=&#34;EN-US&#34;&gt;3. &lt;/span&gt;证书鉴权&lt;span lang=&#34;EN-US&#34;&gt;,&lt;/span&gt;通讯加密&lt;span lang=&#34;EN-US&#34;&gt;,&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;IP &lt;/span&gt;白名单
&lt;/h2&gt;
&lt;p&gt;编译&lt;span lang=&#34;EN-US&#34;&gt;zmq4.x&lt;/span&gt;以后，会生成一个名叫&lt;span lang=&#34;EN-US&#34;&gt;curve_keygen&lt;/span&gt;的程序，用它可以生成&lt;span lang=&#34;EN-US&#34;&gt;zmq &lt;/span&gt;的证书。证书是一个一般的文本文件，如下是一个&lt;span lang=&#34;EN-US&#34;&gt;curve_keygen&lt;/span&gt;生成的&lt;span lang=&#34;EN-US&#34;&gt;zmq&lt;/span&gt;证书的例子。&lt;/p&gt;
&lt;div class=&#34;km_insert_code&#34;&gt;
  &lt;pre class=&#34;brush:other&#34;&gt;#   ****  Generated on 2017-01-02 14:24:20 by CZMQ  ****
#   ZeroMQ CURVE **Secret** Certificate
#   DO NOT PROVIDE THIS FILE TO OTHER USERS nor change its permissions.
&lt;p&gt;metadata
    email = &amp;ldquo;&lt;a href=&#34;mailto:kamuszhou@tencent.com&#34;&gt;kamuszhou@tencent.com&lt;/a&gt;&amp;rdquo;
curve
    public-key = &amp;ldquo;!Upjrn]2Dk)jQkYREsceBnpgoIL7koE{CVnV1j4D&amp;rdquo;
    secret-key = &amp;ldquo;ZPT#=l/#Rtg:TeLbofh:uPi7#/w(GDZq[0^qPZA1&amp;rdquo;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>原来比特位也有大小端endinness.字节序和比特序的故事</title>
      <link>https://ykyi.net/?p=1318/</link>
      <pubDate>Tue, 13 Sep 2016 11:52:46 +0000</pubDate>
      <guid>https://ykyi.net/?p=1318/</guid>
      <description>&lt;pre&gt;我一直以为&lt;strong&gt;大小端endianness&lt;/strong&gt;只针对字节，不针对比特位。
我一直以为全世界所有的cpu解释bit序都是一样的。

昨天才知道endianness也针对bit。
于是就想不明白了。
因为观察到用 htonl 函数转换endianness后，bit位没有变化，只有字节顺序改了呀。&lt;/pre&gt;
&lt;p&gt;于是google呀，找到这篇好文：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.linuxjournal.com/article/6788?page=0,0&#34;&gt;http://www.linuxjournal.com/article/6788?page=0,0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;“&lt;a href=&#34;http://www.linuxjournal.com/article/6788?page=0,0&#34;&gt;Byte and Bit Order Dissection&lt;/a&gt;”(字节序和比特序深入剖析)&lt;/p&gt;
&lt;p&gt;看了这篇文章，才知道 bit序的翻转是由硬件完成的。原来以前这方面很多概念都没理解对。&lt;/p&gt;</description>
    </item>
    <item>
      <title>apt-get通过http代理连接网络</title>
      <link>https://ykyi.net/?p=1299/</link>
      <pubDate>Tue, 22 Sep 2015 03:17:41 +0000</pubDate>
      <guid>https://ykyi.net/?p=1299/</guid>
      <description>&lt;p&gt;编辑/etc/apt/apt.conf加入下面这行:&lt;/p&gt;
&lt;p&gt;Acquire::http::Proxy &amp;ldquo;&lt;a href=&#34;http://web-proxy.oa.com:8080&#34;&gt;http://web-proxy.oa.com:8080&lt;/a&gt;&amp;rdquo;;&lt;br&gt;
按照你的http服务器的地址做相应修改&lt;/p&gt;</description>
    </item>
    <item>
      <title>HTTP2简单教程</title>
      <link>https://ykyi.net/?p=1282/</link>
      <pubDate>Fri, 03 Apr 2015 08:22:39 +0000</pubDate>
      <guid>https://ykyi.net/?p=1282/</guid>
      <description>&lt;p&gt;译自：&lt;a href=&#34;http://qnimate.com/post-series/http2-complete-tutorial/&#34;&gt;http://qnimate.com/post-series/http2-complete-tutorial/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;HTTP1.1是在1999年的时候被引入业界的。从当时到现在，WEB已经发生了相当大的变化。很多人开始用移动设备上网，有些移动环境下网络质量非常不稳定。另外，WEB页面的内容也相当的丰富了。这些都负面影响了WEB页面的加载时间。因此，需要一个新的协议来加速WEB的加载。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2&lt;strong&gt;&lt;strong&gt;和&lt;/strong&gt;&lt;/strong&gt;SPDY****的区别：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SPDY是谷歌于2009年创造的协议，旨在WEB延迟以及增强安全性。&lt;/p&gt;
&lt;p&gt;HTTP/2是SPDY的一个克隆。谷歌已经停止了继续开发SPDY，并且把工作转移到了HTTP/2上来。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2****的目标：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;减少加载延时。&lt;/li&gt;
&lt;li&gt;减少TCP连接数。&lt;/li&gt;
&lt;li&gt;增强的网络安全。&lt;/li&gt;
&lt;li&gt;保持和HTTP/1.1的兼容。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2****的功能：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;多路复用Multiplexing：很多个异步的HTTP请求只使用一个TCP的连接。&lt;/li&gt;
&lt;li&gt;服务端PUSH：对于一个请求可能有多个回复。&lt;/li&gt;
&lt;li&gt;头部压缩：压缩头部(headers)。&lt;/li&gt;
&lt;li&gt;请求分级：对同一个域名的请求可作优先级分级。&lt;/li&gt;
&lt;li&gt;二进制协议：HTTP/2是一个二进制协议，而HTTP/1.1是一个文本协议。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2&lt;strong&gt;&lt;strong&gt;解决了&lt;/strong&gt;&lt;/strong&gt;HTTP/1.1****的哪些问题：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;HTTP管道(HTTP pipelining)：一些HTTP1.1客户端使用了HTTP管道技术来减少TCP连接数。HTTP管道指的是多个HTTP请求被发往同一个TCP连接，而不等待前一个请求的回复。但是服务端发送回复时的顺序和收到的请求的顺序一样。因此，造成了HOL阻塞问题(head-of-line blocking)。HOL Blocking简单地说是一个回复的延迟会使得排在它后面的回复都会延迟。HTTP/2透过引用多路复用(Multiplexing)解决了这个问题。多个HTTP请求和多个HTTP回复都使用同一个TCP连续，而且HTTP回复的顺序不需要保持HTTP请求到达的顺序。&lt;/li&gt;
&lt;li&gt;同一个域名的多个TCP连接：在使用HTTP/1.1时，需要对同一个域名起多个TCP连接来增加吞吐量。而使用HTTP/2时，对于每个域名，只充许有一个TCP连接（only one TCP connection per domain is allowed）。所有的请求和回复都通过唯一的一个TCP连接进行。&lt;/li&gt;
&lt;li&gt;TCP连接的关闭时间：使用HTTP1.1时，一个TCP连接在请求完成时立刻被关闭。但对于HTTP/2，TCP连接能存活相当成地一段时间。&lt;/li&gt;
&lt;li&gt;头部压缩：HTTP/1.1是没有头部压缩的，但HTTP/2引入头部压缩进一步的减少了延时。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2&lt;strong&gt;&lt;strong&gt;如何兼容&lt;/strong&gt;&lt;/strong&gt;HTT/1?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;HTTP/2客户端在不确定对方服务器是否支持HTTP/2时，会用HTTP/1协议向服务器发送请求时带上Upgrade: HTTP/2.0这个头部。如果对方服务器支持HTTP/2，就会回复HTTP1.1 101，表示切换协议(Switching Protocols status)。而对于老旧的服务器则简单地返回HTTP/1.1的状态。&lt;/p&gt;
&lt;p&gt;HTTP/2客户端可以记下哪些服务器支持HTTP/2，这样，下次就可以直接发起HTTP/2请求，而不必再经过一个询问和回复(Upgrade Round Trip).&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2****中的多路复用是怎么回事？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;HTTP/2使用多路复用，多个请求和回复全异步的通过同一个TCP连接收发。&lt;/p&gt;
&lt;p&gt;HTTP/2是一个二进制的协议。每一个请求和回复都被分配了一个流标志(Stream ID)，而且请求和回复被切成了很多帧(Frame)，属于同一个请求或回复帧的Stream ID相同。因为有了这个Stream ID和Frame的机制，请求和回复可以在服务器和客户程序两端同时全异步的发送。因此，HTTP2没有了Head-of-line Blocking的问题。&lt;/p&gt;
&lt;p&gt;每一个Stream还可以被赋于一个优先级，服务器可以分配更多的系统资源处理高优级的Stream。&lt;/p&gt;
&lt;p&gt;HTTP/2还有一个传输层级别的流控。它协商了客户程序和服务器两端最多使用多少个Stream,服务器能处理的最大尺寸的Stream以及整个连接最多处理多少字节，以及数据被发送的速率。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;HTTP/2中的服务器推送(Server Push)和承诺(Promise)&lt;/p&gt;
&lt;p&gt;当服务器“感觉”到客户程序需要更多的资源时，就会给客户程序发送一个Promise Stream ，提醒客户程序需要什么资源。这些stream比一般的stream的优先级要高。&lt;/p&gt;
&lt;p&gt;这项技术在加载网页时非常用户，因为网页的大量css和javascrpit可能通过这种方式发送。而HTTP/1的作法是把css和js都combine到一起。&lt;/p&gt;
&lt;p&gt;服务器发送Promise Stream时提醒的资源遵守同源策略(same origin policy)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2****中的头部压缩：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;HTTP/2的头部压缩和HTTP/1.1中早有的用gzip压缩Body不一样。使用HTTP/2时，在客户程序和服务器两端，都会保存一张表，记录了收到过的头部。它们在发送HTTP时不会重复发送一样的头部，当再次发送相同的头部时，只会发送该头部对应的表的索引号。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Geneva, sans-serif; font-size: 12px; line-height: 22.8000011444092px;&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>git小技巧，gitignore只忽略当前目录下的某文件等等</title>
      <link>https://ykyi.net/?p=1261/</link>
      <pubDate>Mon, 28 Jul 2014 08:09:14 +0000</pubDate>
      <guid>https://ykyi.net/?p=1261/</guid>
      <description>&lt;p&gt;&lt;font size=&#34;3&#34;&gt;#. 编写git的gitignore文件时如何只忽略当前目录下的某文件呢&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&#34;3&#34;&gt;在文件名前加斜线 / 即可&lt;/font&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;font size=&#34;3&#34;&gt;# git pull如何从remote中拉下来所有分支&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&#34;3&#34;&gt;git pull –all&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&#34;3&#34;&gt;git branch -a 查看目前所有分支，包括tracking branch&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&#34;3&#34;&gt;再用 git branch –track branch_name start_point 开一个本地分支，并且设好该本地分支的upstream&lt;/font&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;font size=&#34;3&#34;&gt;# git 10小时&lt;strong&gt;免输git密码&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;pre style=&#34;margin-top: 0px; padding: 5px; border: 0px; overflow: auto; width: auto; max-height: 600px; font-family: Consolas, Menlo, Monaco, &#39;Lucida Console&#39;, &#39;Liberation Mono&#39;, &#39;DejaVu Sans Mono&#39;, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, monospace, sans-serif; word-wrap: normal; color: rgb(34, 34, 34); background-color: rgb(238, 238, 238);&#34;&gt;&lt;code style=&#34;margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, &#39;Lucida Console&#39;, &#39;Liberation Mono&#39;, &#39;DejaVu Sans Mono&#39;, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, monospace, sans-serif; white-space: inherit;&#34;&gt;git config --global credential.helper &#34;cache --timeout=36000&#34;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;font size=&#34;3&#34;&gt;如果需要清空存下来的密码：&lt;/font&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux 如何知道有哪些硬件，该装哪个驱动</title>
      <link>https://ykyi.net/?p=1255/</link>
      <pubDate>Wed, 23 Jul 2014 03:12:12 +0000</pubDate>
      <guid>https://ykyi.net/?p=1255/</guid>
      <description>&lt;p&gt;Linux 如何知道有哪些硬件，该装哪个驱动&lt;/p&gt;
&lt;p&gt;公司明文不准安装虚拟机了，被查到就是死罪。于是我在自己的笔记本上安装了Debian Linux。&lt;/p&gt;
&lt;p&gt;结果无线网卡识别不了~~&lt;/p&gt;
&lt;p&gt;次奥~&lt;/p&gt;
&lt;p&gt;怎么破呢？&lt;/p&gt;
&lt;p&gt;这么破:&lt;/p&gt;
&lt;pre style=&#34;margin-top: 0px; margin-bottom: 10px; padding: 5px; border: 0px; font-size: 13px; vertical-align: baseline; overflow: auto; width: auto; max-height: 600px; font-family: Consolas, Menlo, Monaco, &#39;Lucida Console&#39;, &#39;Liberation Mono&#39;, &#39;DejaVu Sans Mono&#39;, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, monospace, serif; background-color: rgb(238, 238, 238); word-wrap: normal; line-height: 20px;&#34;&gt;&lt;code style=&#34;margin: 0px; padding: 0px; border: 0px; font-size: 13px; vertical-align: baseline; font-family: Consolas, Menlo, Monaco, &#39;Lucida Console&#39;, &#39;Liberation Mono&#39;, &#39;DejaVu Sans Mono&#39;, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, monospace, serif; color: rgb(34, 34, 34); white-space: inherit;&#34;&gt;# lspci
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&#34;margin: 0px 0px 1em; padding: 0px; border: 0px; font-size: 15.333333015441895px; vertical-align: baseline; clear: both; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; line-height: 20px;&#34;&gt;
  该命令列出了所有PCI总线上的硬件设备，稍微看看就能看到自己的无线网卡了。
&lt;/p&gt;</description>
    </item>
    <item>
      <title>用boost的方式在预编译期检查编译器和平台以及其它</title>
      <link>https://ykyi.net/?p=1251/</link>
      <pubDate>Wed, 11 Jun 2014 07:38:33 +0000</pubDate>
      <guid>https://ykyi.net/?p=1251/</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;span style=&#34;font-size: 12.727272033691406px;&#34;&gt;用boost的方式在预编译期检查编译器和平台以及其它&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: 13px; line-height: 1.6em;&#34;&gt;一般C/C++程序员都知道用一些编译器预编译宏来判断编译器的种类的操作系统。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;一般有：&lt;br&gt;
_WIN32 ，不管windows x86 还是 x86_64 都会有_WIN32，注意前面的下划线，如果没有下划线，MSDN的官方定义有这个酷酷的下划线.&lt;br&gt;
__unix__ 是否 unix OS&lt;br&gt;
__linux__ 是否是 linux&lt;br&gt;
__apple__ 是否是平台&lt;/p&gt;
&lt;p&gt;原来咧，BOOST库提供了一个相当丰富的库来做这件事：&lt;br&gt;
这个BOOST库是 Predef &lt;a href=&#34;http://www.boost.org/doc/libs/1_55_0/libs/predef/doc/html/index.html&#34;&gt;http://www.boost.org/doc/libs/1_55_0/libs/predef/doc/html/index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;boost/predef.h&amp;gt;&lt;/p&gt;
&lt;p&gt;看看官方文档的目录：&lt;br&gt;
Table of Contents&lt;/p&gt;
&lt;p&gt;Introduction&lt;br&gt;
Using the predefs&lt;br&gt;
Adding new predefs&lt;br&gt;
Reference&lt;br&gt;
BOOST_ARCH architecture macros&lt;br&gt;
BOOST_COMP compiler macros&lt;br&gt;
BOOST_LANG language standards macros&lt;br&gt;
BOOST_LIB library macros&lt;br&gt;
BOOST_OS operating system macros&lt;br&gt;
Other macros&lt;br&gt;
Version definition macros&lt;br&gt;
Acknoledgements&lt;/p&gt;
&lt;p&gt;包括处理器架构，编译器相关宏，语言相关宏，库相关宏，操作系统相关宏~~~&lt;/p&gt;
&lt;p&gt;I like boost ~~~&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>用Range Adaptor，废弃replace_copy_if之类的函数</title>
      <link>https://ykyi.net/?p=1242/</link>
      <pubDate>Tue, 15 Apr 2014 12:22:48 +0000</pubDate>
      <guid>https://ykyi.net/?p=1242/</guid>
      <description>&lt;p&gt;看看replace_copy_if的一个简单的例子：&lt;/p&gt;
&lt;p&gt;std::vector&lt;int&gt; vec;&lt;/p&gt;
&lt;p&gt;boost::replace_copy_if(rng, std::back_inserter(vec), pred, new_value);&lt;/p&gt;
&lt;p&gt;对于这种写法，如果使用Range Adaptor的话，则可以写成：&lt;/p&gt;
&lt;p&gt;std::vector&lt;int&gt; vec;&lt;/p&gt;
&lt;p&gt;boost::push_back(vec, rng | boost::adaptors::replaced_if(pred, new_value));&lt;/p&gt;
&lt;p&gt;第二种写法有什么好处呢，&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;更高效率。因为std::back_inserter有额外的内存分配开销。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;更灵活。因为第二种写法可以应用更多的适配器，比如： boost::push_back(vec, rng | boost::adaptors::replaced_if(pred, new_value) | boost::adaptors::reversed);&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;更安全。因为第二种写法没有用unbounded output iterator。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>boost::io_service的poll_one和run_one有什么区别</title>
      <link>https://ykyi.net/?p=1225/</link>
      <pubDate>Tue, 18 Mar 2014 11:03:02 +0000</pubDate>
      <guid>https://ykyi.net/?p=1225/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:18px;&#34;&gt;boost::io_service的poll_one会立即返回(non-blocking)，不管有没有已经被触发的处理函数(ready handler)。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:18px;&#34;&gt;而run_one有可能阻塞。如果还没有被触发的处理函数，run_one会阻塞到有一个handler被调用为止。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:18px;&#34;&gt;更多资料： &lt;a href=&#34;http://think-async.com/&#34;&gt;&lt;a href=&#34;http://think-async.com/&#34;&gt;http://think-async.com/&lt;/a&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:18px;&#34;&gt;呃。这篇日志也太短了！！！&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:18px;&#34;&gt;BOOST库真是个好东西啊~~好多写法很有现代脚本语言的taste。~~而且，那么丰富的库让生产效率大大提高了。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>“右值引用”不是”右值”,而是”左值”</title>
      <link>https://ykyi.net/?p=1217/</link>
      <pubDate>Fri, 21 Feb 2014 05:21:27 +0000</pubDate>
      <guid>https://ykyi.net/?p=1217/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;亮瞎你的狗眼了吧~这么拗口。 ！来补一下C++基础吧~~&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;右值引用 rvalue reference&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;右值 rvalue&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;左值 lvalue&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;什么是左值 lvalue呢。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;本质上，左值是一个可以拿到其地址的表达式。左值lvalue里的l,本质上是locatable的缩写，因为lvalue通常可以放置于表达式的左边，于是就有了左left值的说法。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;In C++, an lvalue is an expression whose address can be taken, essentially it&amp;rsquo;s a locator value.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&#34;brush:cpp&#34;&gt;class MetaData
{
public:
	MetaData (int size, const std::string&amp; name)
		: _name( name )
		, _size( size )
	{}

	// copy constructor
	MetaData (const MetaData&amp; other)
		: _name( other._name )
		, _size( other._size )
	{
		cout &amp;lt;&amp;lt; &#34;copy\n&#34;;
	}

	// move constructor
	MetaData (MetaData&amp;&amp; other)
		: _name( other._name )
		, _size( other._size )
	{
		cout &amp;lt;&amp;lt; &#34;move\n&#34;;
	}

	std::string getName () const { return _name; }
	int getSize () const { return _size; }
private:
	std::string _name;
	int _size;
};

class ArrayWrapper
{
public:
	// default constructor produces a moderately sized array
	ArrayWrapper ()
		: _p_vals( new int[ 64 ] )
		, _metadata( 64, &#34;ArrayWrapper&#34; )
	{}

	ArrayWrapper (int n)
		: _p_vals( new int[ n ] )
		, _metadata( n, &#34;ArrayWrapper&#34; )
	{}

	// move constructor
	ArrayWrapper (ArrayWrapper&amp;&amp; other)
		: _p_vals( other._p_vals  )
		, _metadata( move(other._metadata ))
	{
		other._p_vals = NULL;
	}

	// copy constructor
	ArrayWrapper (const ArrayWrapper&amp; other)
		: _p_vals( new int[ other._metadata.getSize() ] )
		, _metadata( other._metadata )
	{
		for ( int i = 0; i &amp;lt; _metadata.getSize(); ++i )
		{
			_p_vals[ i ] = other._p_vals[ i ];
		}
	}
	~ArrayWrapper ()
	{
		delete [] _p_vals;
	}
private:
	int *_p_vals;
	MetaData _metadata;
};

ArrayWrapper get()
{
	ArrayWrapper aw;
	return aw;
}

int main()
{
	ArrayWrapper aw(get());
	return 0;
}&lt;/pre&gt;
&lt;p&gt;这段代码中的ArrayWrapper的移动构造函数能工作吗？&lt;/p&gt;</description>
    </item>
    <item>
      <title>为什么指针可以做为迭代器使用呢</title>
      <link>https://ykyi.net/?p=1207/</link>
      <pubDate>Fri, 14 Feb 2014 06:47:36 +0000</pubDate>
      <guid>https://ykyi.net/?p=1207/</guid>
      <description>&lt;p&gt;写了十几年代码了，今天才知道*为什么*指针可以做为迭代器使用。&lt;/p&gt;
&lt;p&gt;这是因为：&lt;/p&gt;
&lt;p&gt;首先，标准库里有这样一个template，它用来得到特定迭代器的相关特性:&lt;/p&gt;
&lt;pre class=&#34;brush:cpp&#34;&gt;namespace std {
       template &amp;lt;class T&amp;gt;
       struct iterator_traits {
           typedef typename T::value_type            value_type;
           typedef typename T::difference_type       difference_type;
           typedef typename T::iterator_category     iterator_category;
           typedef typename T::pointer               pointer;
           typedef typename T::reference             reference;
       };
   } &lt;/pre&gt;
&lt;p&gt;而对于指针，又有这样一个模板特例化，&lt;/p&gt;
&lt;pre class=&#34;brush:cpp&#34;&gt;namespace std {
       template &amp;lt;class T&amp;gt;
       struct iterator_traits&amp;lt;T*&amp;gt; {
           typedef T                          value_type;
           typedef ptrdiff_t                  difference_type;
           typedef random_access_iterator_tag iterator_category;
           typedef T*                         pointer;
           typedef T&amp;                         reference;
       };
   }&lt;/pre&gt;
&lt;p&gt;这个模板特例化的意思是：对于每一个指向类型T的指针，都被定义为一个可随机访问的迭代器。&lt;/p&gt;
&lt;p&gt;更详细的，参见文章：介绍iterator_trait &lt;a href=&#34;http://www.codeproject.com/Articles/36530/An-Introduction-to-Iterator-Traits&#34; style=&#34;line-height: 1.6em;&#34;&gt;&lt;a href=&#34;http://www.codeproject.com/Articles/36530/An-Introduction-to-Iterator-Traits&#34;&gt;http://www.codeproject.com/Articles/36530/An-Introduction-to-Iterator-Traits&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>C&#43;&#43;准标准库boost转向github，并发布模块化boost(modular Boost)</title>
      <link>https://ykyi.net/?p=1203/</link>
      <pubDate>Thu, 13 Feb 2014 12:08:18 +0000</pubDate>
      <guid>https://ykyi.net/?p=1203/</guid>
      <description>&lt;p&gt;难道是中文社区首次报道吗？我用中文搜索引擎没有搜索到modular boost的文章。&lt;/p&gt;
&lt;p&gt;昨天想在STL的map容器上增加一个特性，即把std::map中所有的元素按照加入的先后时间用链表链接起来，以保存元素之间的时序关系。&lt;/p&gt;
&lt;p&gt;为了这个基于std::map和std::list的新的容器能够兼容STL的算法，于是想实现stl compatible iterator。一口气读了几十页资料，发现最酷最好的方法是用boost的迭代器模板实现。纠结了很久，最终决定在我的工程中引入boost。为了获得快速开发的好处，还是加入更多的开源库吧。毕竟，如果自己造一个轮子，阅读者仍然要花时间理解你发明的轮子，还不如用已经广泛使用的轮子。况且，计划要引入boost中asio的proactor I/O模型。所以，今天就开始引入boost吧。&lt;/p&gt;
&lt;p&gt;于是，发现boost早就发起了modular boost项目并把boost host在github.com上，如下地址：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/boostorg&#34;&gt;https://github.com/boostorg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在boost的官方网站上有模块化boost的FAQ:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://svn.boost.org/trac/boost/wiki/ModCvtFAQ&#34;&gt;https://svn.boost.org/trac/boost/wiki/ModCvtFAQ&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;还有它的简单使用教程：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://svn.boost.org/trac/boost/wiki/TryModBoost#InstallingModularBoost&#34;&gt;https://svn.boost.org/trac/boost/wiki/TryModBoost#InstallingModularBoost&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;教程上说，如果把整个module boost git clone到本地，需要花费45分钟，如果下行网速是3Mbps，而且需要占用1.5G磁盘！&lt;/p&gt;
&lt;p&gt;我晕~~&lt;/p&gt;
&lt;p&gt;另外FAQ上说：没办法只检出一个子库，暂时不能自动地解决依赖性问题。&lt;/p&gt;
&lt;p&gt;原文：&lt;/p&gt;
&lt;p style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Arial, &#39;Bitstream Vera Sans&#39;, Helvetica, sans-serif; font-size: 13px; line-height: normal;&#34;&gt;
  &lt;strong&gt;Is it possible to checkout only one library and its prerequisites?&lt;/strong&gt;
&lt;/p&gt;
&lt;blockquote style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Arial, &#39;Bitstream Vera Sans&#39;, Helvetica, sans-serif; font-size: 13px; font-style: normal; line-height: normal;&#34;&gt;
  &lt;p&gt;
    Not automatically. Automatic dependency resolution is planned for the future, but not as a part of the conversion to Git and Modular Boost.
  &lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>怎么知道gcc搜索头文件的路径</title>
      <link>https://ykyi.net/?p=1187/</link>
      <pubDate>Thu, 13 Feb 2014 08:02:43 +0000</pubDate>
      <guid>https://ykyi.net/?p=1187/</guid>
      <description>&lt;p&gt;&lt;font size=&#34;3&#34;&gt;每个C/C++程序员都知道，对于#include directive，一般，以双引号引用的头文件是程序号自定义的头文件。而用尖括号引用的头文件是系统的头文件或其它库文件。&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&#34;3&#34;&gt;更详细的，编译器先在当前目录找用双引号&amp;quot;&amp;ldquo;引用的头文件，如果找不到再到系统目录找这个头文件。而对于尖括号引用的头文件，编译器就只在系统文件中搜索了。&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&#34;3&#34;&gt;那么，到底是在哪些目录中搜索头文件呢？&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&#34;3&#34;&gt;可以用cpp查看，如下：&lt;/font&gt;&lt;/p&gt;
&lt;pre class=&#34;brush:other&#34;&gt;root@vicarious:/home/kamus/projs/horoscope/boost# cpp -v
Using built-in specs.
COLLECT_GCC=cpp
Target: x86_64-linux-gnu
Thread model: posix
gcc version 4.7.2 (Debian 4.7.2-5)
COLLECT_GCC_OPTIONS=&amp;#39;-E&amp;#39; &amp;#39;-v&amp;#39; &amp;#39;-mtune=generic&amp;#39; &amp;#39;-march=x86-64&amp;#39;
 /usr/lib/gcc/x86_64-linux-gnu/4.7/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu - -mtune=generic -march=x86-64
ignoring nonexistent directory &#34;/usr/local/include/x86_64-linux-gnu&#34;
ignoring nonexistent directory &#34;/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../x86_64-linux-gnu/include&#34;
#include &#34;...&#34; search starts here:
#include &amp;lt;...&amp;gt; search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.7/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.7/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;一般编写makefile时给gcc指定 -I选项，-I的参数代表的目录是搜索系统头文件时使用的目录。可以试试# cpp -I/tmp -v &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;/tmp目录会被添加为搜索系统头文件时的第一个目录。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;如果想要添加搜索双引号&amp;quot;&amp;ldquo;引用的头文件使用的目录呢，用 &lt;strong&gt;-iquote&lt;/strong&gt; 选项指定更多的目录。&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux的环境变量LD_DEBUG调试so的加载</title>
      <link>https://ykyi.net/?p=1185/</link>
      <pubDate>Wed, 12 Feb 2014 07:20:25 +0000</pubDate>
      <guid>https://ykyi.net/?p=1185/</guid>
      <description>&lt;p&gt;&lt;em style=&#34;line-height: 1.6em;&#34;&gt;一个稍微有经验的&lt;/em&gt;&lt;em style=&#34;line-height: 1.6em;&#34;&gt;Linux&lt;/em&gt;&lt;em style=&#34;line-height: 1.6em;&#34;&gt;程序员都知道使用&lt;/em&gt;&lt;em style=&#34;line-height: 1.6em;&#34;&gt;LD_LIBRARY_PATH&lt;/em&gt;&lt;span style=&#34;line-height: 1.6em;&#34;&gt; 来临时设置加载器搜索动态链接库so的路径顺序。但另一个不为人知的环境变量是LD_DEBUG。这个变量可以提供非常详细的加载动态链接库的信息。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;可以把LD_DEBUG设成以下值：&lt;/p&gt;
&lt;p&gt;export LD_DEBUG=files     # 显示库的依赖性和加载的顺序&lt;/p&gt;
&lt;p&gt;export LD_DEBUG=bindings  # 符号绑定&lt;/p&gt;
&lt;p&gt;export LD_DEBUG=libs   # 显示加载器查找库时使用的路径的顺序&lt;/p&gt;
&lt;p&gt;export LD_DEBUG=versions  # 版本依赖性&lt;/p&gt;
&lt;p&gt;export LD_DEBUG=help  # LD_DEBUG的帮助信息&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;试一下把LD_DEBUG设成以上值之一，再随便运行一个程序试试。&lt;/p&gt;
&lt;p&gt;一个试验：&lt;/p&gt;
&lt;pre class=&#34;brush:other&#34;&gt;root@vicarious:/home/kamus/projs/horoscope/bins# export LD_DEBUG=libs

root@vicarious:/home/kamus/projs/horoscope/bins# vim my.conf

     24360:   find library=libm.so.6 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libm.so.6

     24360:

     24360:   find library=libtinfo.so.5 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libtinfo.so.5

     24360:

     24360:   find library=libselinux.so.1 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libselinux.so.1

     24360:

     24360:   find library=libacl.so.1 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libacl.so.1

     24360:

     24360:   find library=libgpm.so.2 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/usr/lib/x86_64-linux-gnu/libgpm.so.2

     24360:

     24360:   find library=libc.so.6 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libc.so.6

     24360:

     24360:   find library=libdl.so.2 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libdl.so.2

     24360:

     24360:   find library=libattr.so.1 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libattr.so.1&lt;/pre&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>运行loadlib()提示attempt to call global ‘loadlib’ (a nil value)</title>
      <link>https://ykyi.net/?p=1177/</link>
      <pubDate>Wed, 22 Jan 2014 09:21:49 +0000</pubDate>
      <guid>https://ykyi.net/?p=1177/</guid>
      <description>&lt;p&gt;2009年的时候用过lua，当时在windows上写金山急救箱的恶意软件库引擎。&lt;/p&gt;
&lt;p&gt;时隔多年，又要玩一把lua. 重拾lua，在lua控制台用loadlib载入动态链接库时出错：&lt;/p&gt;
&lt;pre class=&#34;brush:other&#34;&gt;&amp;gt; loadlib(&#34;libhello.so&#34;, &#34;*&#34;)
stdin:1: attempt to call global &amp;#39;loadlib&amp;#39; (a nil value)
stack traceback:
    stdin:1: in main chunk
    [C]: in ?&lt;/pre&gt;
&lt;p&gt;Lua表示在全局域中没有loadlib。google后发现两种解决方案：&lt;/p&gt;
&lt;p&gt;第一种认为这种错误是因为没有把loadlib编译进lua中，需要改makefile.如此贴的楼主所述： &lt;a href=&#34;http://lua-users.org/lists/lua-l/2009-02/msg00463.html&#34;&gt;http://lua-users.org/lists/lua-l/2009-02/msg00463.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;第二种是在csdn上的贴子，要改lua的源文件中的一个define，实际上这种方法也是可以在makefile中define一个变量的。&lt;/p&gt;
&lt;p&gt;不过！！！&lt;/p&gt;
&lt;p&gt;问题其实更简单，不需要改什么makefile文件：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://lua-users.org/lists/lua-l/2009-02/msg00466.html&#34;&gt;http://lua-users.org/lists/lua-l/2009-02/msg00466.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;lua在5.0以后，loadlib已经不在全局域中了，loadlib在package名字空间中了。&lt;/p&gt;
&lt;p&gt;这样就好了：&lt;/p&gt;
&lt;p&gt;package.loadlib(&amp;ldquo;libhello.so&amp;rdquo;, &amp;ldquo;*&amp;rdquo;)&lt;/p&gt;
&lt;p&gt;实际上，loadlib是一个底层的函数。不像require,loadlib不在path里进行查找，也不自动添加文件名后缀。这个函数在某些平台上不被支持，因为ANSI并没有要求支持动态链接库。&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>什么是0MQ或ØMQ，或ZeroMQ</title>
      <link>https://ykyi.net/?p=1170/</link>
      <pubDate>Sat, 18 Jan 2014 10:39:00 +0000</pubDate>
      <guid>https://ykyi.net/?p=1170/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;line-height: 1.6em;&#34;&gt;ØMQ或者拼写成ZeroMQ,0MQ，是一个高性能异步消息队列库，旨在在分布式可扩展的并行程序中使用。它提供了一个消息队列，但不像面向消息的中间件，即使没有特定的消息经纪人(Message Broker)，0MQ也能正常工作。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;这个库在TCP的基础上开发，但能获得比TCP更高的性能，更不用说它提供了各种安全机制和分布式易扩展的特性。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;0MQ的API和传统的socket很像。OMQ中的socket描述了一个,多个终端之间的多对多的连接。0MQ还有一个消息模式的概念。基本的0MQ消息模式有：&lt;/p&gt;
&lt;p&gt;Request-reply:&lt;/p&gt;
&lt;p&gt;用来连接一组客户端和一组服务。这个模式是一个远程过程调用RPC，和多任务分发模式。&lt;/p&gt;
&lt;p&gt;Publish-subscribe:&lt;/p&gt;
&lt;p&gt;用来连接一组发行端和一组接收端。这是一个数据分发模式。&lt;/p&gt;
&lt;p&gt;Push-Pull(Pipeline)&lt;/p&gt;
&lt;p&gt;用扇入/扇出模式连接很多结点，通常要分好几个步骤。这是一个多任务并行分布和收集的模式。&lt;/p&gt;
&lt;p&gt;Exclusive Pair:&lt;/p&gt;
&lt;p&gt;用排它模式连组两个socket。这其实是一个为特殊需求准备的高级底层模式。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;每一种模式定义了一个对应的网络拓扑。Request-reply模式定义了所谓的”服务总线”，publish-subscribe定义了数据分发树，push-pull定义了并行管道。这样模式都被精心设计，使他们可以在互联网上被无限扩展。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;不想译了,。更多内容见wikipedia。&lt;a href=&#34;mailto:kamuszhou@qq.com&#34; style=&#34;font-size: 13px;&#34;&gt;&lt;a href=&#34;mailto:kamuszhou@qq.com&#34;&gt;kamuszhou@qq.com&lt;/a&gt;&lt;/a&gt;&lt;span style=&#34;font-size: 13px;&#34;&gt; 腾讯视频广告&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>Git 的M,T,D,A,U标志是什么意思</title>
      <link>https://ykyi.net/?p=1141/</link>
      <pubDate>Fri, 17 Jan 2014 08:56:20 +0000</pubDate>
      <guid>https://ykyi.net/?p=1141/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;line-height: 1.6em;&#34;&gt;在使用git checkout , git status，或git diff files时会出现奇怪的标志。如M,T,D,A,R,U等等。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;如：&lt;/p&gt;
&lt;p style=&#34;margin-left: 40px;&#34;&gt;
  # git checkout master
&lt;/p&gt;
&lt;p style=&#34;margin-left: 40px;&#34;&gt;
  M&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cpp-iniparser
&lt;/p&gt;
&lt;p&gt;文件cpp-iniparser前面有个M. git的这些奇怪标志是什么意思呢。&lt;/p&gt;
&lt;p&gt;A: 增加的文件.&lt;/p&gt;
&lt;p&gt;C: 文件的一个新拷贝.&lt;/p&gt;
&lt;p&gt;D: 删除的一个文件.&lt;/p&gt;
&lt;p&gt;M: 文件的内容或者mode被修改了.&lt;/p&gt;
&lt;p&gt;R: 文件名被修改了。&lt;/p&gt;
&lt;p&gt;T: 文件的类型被修改了。&lt;/p&gt;
&lt;p&gt;U: 文件没有被合并(你需要完成合并才能进行提交)&lt;/p&gt;
&lt;p&gt;X: 未知状态。(很可能是遇到git的bug了，你可以向git提交bug report)&lt;/p&gt;
&lt;p&gt;在git diff-files的手册man git diff-files中可以查到这些标志的说明。&lt;/p&gt;
&lt;p&gt;这些状态标志在git的源代码的diff.h文件中被定义。&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>使用Git的submodule功能管理第三方库</title>
      <link>https://ykyi.net/?p=1128/</link>
      <pubDate>Thu, 16 Jan 2014 06:40:00 +0000</pubDate>
      <guid>https://ykyi.net/?p=1128/</guid>
      <description>&lt;p align=&#34;left&#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family:arial,helvetica,sans-serif;&#34;&gt;用Git的Submodule功能来管理代码中使用的其它库，还是满方便的。主要用到三个命令:&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p align=&#34;left&#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family:arial,helvetica,sans-serif;&#34;&gt;Git submodule add, git submodule init, git submodule update.&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p align=&#34;left&#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family:arial,helvetica,sans-serif;&#34;&gt;git submodule init to initialize your local configuration file and git submodule update to fetch all the data from that project and check out the appropriate commit listed in your superproject.&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p align=&#34;left&#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family:arial,helvetica,sans-serif;&#34;&gt;还有两个查看相关信息的命令git submodule summary,和 git submodule status.&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p align=&#34;left&#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family:arial,helvetica,sans-serif;&#34;&gt;Git的submodule功能带来的好处和坏处都很多，网上有大量的贴子反对使用git submodule。&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p align=&#34;left&#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family:arial,helvetica,sans-serif;&#34;&gt;我觉有限制地，在以下场景用git submodule管理第三方库的代码还是很不错。&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p align=&#34;left&#34; style=&#34;margin-left:18pt;&#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family:arial,helvetica,sans-serif;&#34;&gt;1.&amp;nbsp;&amp;nbsp;&amp;nbsp; 你使用的第三方库更新非常慢，甚至不更新，它的接口很稳定。比如：管理vim的插件们。&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p align=&#34;left&#34; style=&#34;margin-left:18pt;&#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family:arial,helvetica,sans-serif;&#34;&gt;2.&amp;nbsp;&amp;nbsp;&amp;nbsp; 第三方库以比较固定的周期更新。于是，过一段时间再把上游的代码拉到submodule上来。&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p align=&#34;left&#34; style=&#34;margin-left:18pt;&#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family:arial,helvetica,sans-serif;&#34;&gt;3.&amp;nbsp;&amp;nbsp;&amp;nbsp; 第三方库虽然更新很快，但我过一段时间才拉取上游代码也无所谓。&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p align=&#34;left&#34; style=&#34;margin-left:18pt;&#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family:arial,helvetica,sans-serif;&#34;&gt;如果单开一个git clone管理第三方库，与自己的项目平行，当然也是可以的。但这样有个问题是，别人git clone了你的项目，还需要再git clone一次你的项目依赖的项目，并放在适当的相对路径上。而使用git submodule *时，你的项目和你依赖的库是层级关系，有条理得多。&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p align=&#34;left&#34; style=&#34;margin-left:18pt;&#34;&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p align=&#34;left&#34; style=&#34;margin-left:18pt;&#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family:arial,helvetica,sans-serif;&#34;&gt;还有一种方式是把第三方库的代码合并到自己的代码中。这样做的坏处是显而易见的，如果你要合并上游代码的FIX或功能加强，都非常的麻烦。大多数人是不会去做这个同步的，于是代码会被手动复制，越来越多的细微改动分散在各个不同的项目的相同/相近代码中。一片混乱&amp;hellip;.&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p align=&#34;left&#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;strong&gt;使用Git Submodule时忽略Submodule的改动：&lt;/strong&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p align=&#34;left&#34;&gt;
  如果submodule中有生成新文件。在父工程(superproject)中用git status，就总会提醒你git submodule子模块有还没被跟踪的文件。
&lt;/p&gt;
&lt;p align=&#34;left&#34;&gt;
  比如：一次make会生成很多.o，.dep文件。比如用git submodule管理vim插件会生成各种临时文件。你不想让git status提醒你，这多么烦人啊。
&lt;/p&gt;
&lt;p align=&#34;left&#34;&gt;
  如下，git status总提醒我cpp-iniparser子模块有未跟踪的文件：
&lt;/p&gt;
&lt;p align=&#34;left&#34; style=&#34;margin-left: 40px;&#34;&gt;
  root@vicarious:/home/kamus/projs/horoscope# git status&lt;br /&gt; # On branch dev&lt;br /&gt; # Changes not staged for commit:&lt;br /&gt; # &amp;nbsp; (use &#34;git add &lt;file&gt;&amp;#8230;&#34; to update what will be committed)&lt;br /&gt; # &amp;nbsp; (use &#34;git checkout &amp;#8212; &lt;file&gt;&amp;#8230;&#34; to discard changes in working directory)&lt;br /&gt; # &amp;nbsp; (commit or discard the untracked or modified content in submodules)&lt;br /&gt; #&lt;br /&gt; #&amp;nbsp;&amp;nbsp; &amp;nbsp;modified: &amp;nbsp; configuration.cpp&lt;br /&gt; #&amp;nbsp;&amp;nbsp; &amp;nbsp;modified: &amp;nbsp; configuration.h&lt;br /&gt; #&amp;nbsp;&amp;nbsp; &amp;nbsp;modified: &amp;nbsp; cpp-iniparser (untracked content)
&lt;/p&gt;</description>
    </item>
    <item>
      <title>HTTP中的HEAD方法是什么</title>
      <link>https://ykyi.net/?p=1122/</link>
      <pubDate>Wed, 08 Jan 2014 02:29:55 +0000</pubDate>
      <guid>https://ykyi.net/?p=1122/</guid>
      <description>&lt;p&gt;HTTP中的HEAD方法和GET方法是一样的，除了服务器在响应HEAD方法时不充许活加消息体(message body).服务器用来回复HEAD的响应信息中，在HTTP头部中的元信息需要跟回复GET时一样。这样，一个客户就可以通过HEAD来得到某资源的源信息，而不需要把整个资源都传输一次。&lt;/p&gt;
&lt;p&gt;HEAD方法通常被用来测试超链接的可达，和资源是否已经更新。&lt;/p&gt;
&lt;p&gt;HEAD方法的主要应用场景是检索资源的元信息meta infomation。用getResponseHeaders()函数可以得到HTTP的头部~&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>configure –prefix 和 make install DESTDIR= 还有make install prefix 什么区别</title>
      <link>https://ykyi.net/?p=1116/</link>
      <pubDate>Mon, 06 Jan 2014 02:19:04 +0000</pubDate>
      <guid>https://ykyi.net/?p=1116/</guid>
      <description>&lt;p&gt;./configure –prefix=*&lt;/p&gt;
&lt;p&gt;确定了程序会被包装到哪里，以及，程序将在什么位置搜寻运行需要用到的相关的文件。如果你在一台机器上编译，然后仍然在这台机器上运行，那使用configure –prefix就是你想要的了。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;make install DESTDIR=*&lt;/p&gt;
&lt;p&gt;把程序安装到一个临时用的目录，这个目录不是程序以后将要运行的目录。例如，这个功能被deb包的打包人员使用。打包人员使用此功能时，并不真正把程序安装到–prefix指定的目录下。因为他可能已经安装了不同的版本，他不想搞乱他的环境，或者他没有boot权限，没有办法把程序安装到/bin,/sbin之类目录。 –prefix=/usr，让程序运行时认为被安装在/usr，然后make install DESTDIR=debian/tmp则实际把程序安装到debian/tmp。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;make install prefix=/foo/bar/baz&lt;/p&gt;
&lt;p&gt;和 make install DESTDIR的区别在于，前者不会创建prefix后面指定的所有目录层级，而DESTDIR会。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;p&gt;./configure –prefix=usr/local &amp;amp;&amp;amp; make &amp;amp;&amp;amp; sudo make install prefix=/usr/local/stow/foo 会把程序安装在/usr/local/stow/bin目录下。&lt;/p&gt;
&lt;p&gt;而: make install DESTDIR=/usr/local/stow/foo，则把程序安装在/usr/local/stow/foo/usr/local/bin下面。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Geneva, sans-serif; font-size: 16px; line-height: 22px; background-color: rgb(244, 244, 244);&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>抓包程序的一些分享</title>
      <link>https://ykyi.net/?p=1102/</link>
      <pubDate>Thu, 26 Dec 2013 02:13:56 +0000</pubDate>
      <guid>https://ykyi.net/?p=1102/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;昨晚同白总和adden提到抓包的问题。因为写过相关的代码，遇到过抓包的各种各样的坑，此文分享一些相关的经验。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;strong&gt;1. Linux cooked capture&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;在用tcpdump或wireshark看数据包时，有时会看到数据链路层的的包头称为Linux cooked capture。这不是一个真实的包头，当用tcpdump指定从所有网络介质 -i any 抓包时，所有抓到的包的数据链路层被换成了Linux cooked capture。在wireshark官方网站对Linux cooked capture的解释中: 这是一个在linux上被libpcap抓包库使用的“假协议”(pseudo-protocal)，当从“any”设备在抓包，或者本地的数据链路层包头无效时被使用。更多，见&lt;a href=&#34;http://wiki.wireshark.org/SLL&#34;&gt;&lt;a href=&#34;http://wiki.wireshark.org/SLL&#34;&gt;http://wiki.wireshark.org/SLL&lt;/a&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;strong&gt;2. IP over IP tunnel&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;wikipedia的示例图显示IP tunnel上的包的结构是：&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;alignnone&#34; height=&#34;100&#34; src=&#34;http://upload.wikimedia.org/wikipedia/en/thumb/2/2d/IPTunnelDiagram_01-12-07.jpg/300px-IPTunnelDiagram_01-12-07.jpg&#34; width=&#34;300&#34; /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;但实战中用libpcap库从我们的线上机的IP隧道抓包时，pcap_loop或pcap_dispatch或pcap_next函数返回的数据包只有Inner IP header + IP payload，没有Outer IP headr，也没链路层的头部。多么幸运啊！&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;strong&gt;3. 混乱的RAW_SOCKET，PF_PACKET协议族&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;这不是工业标准定义的神秘领域，非常之混乱，谨慎进入。如果要写这方面的socket，可供参考。个人经验，用linux原生的socket抓包时，socket()的三的参数如下组合时的神奇效果.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;     &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;        _recv_fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;        从此socket中读所有的IP包，返回的IP包没有链路层包头,因为第二个参数是SOCK_DGRAM，链路层包头返回时被去掉。第三个参数指定的是IP包。奇怪的是，如果出站的IP包的目的地址不是本机，则出站的IP包不会被抓到。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;       &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;        _recv_fd = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_IP));&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;        和上一个socket的区别是，这个会返回链路层包头。和上一个socket一样，同样只能装到部分出站的包。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;      &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;            _recv_fd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;        这行代码只可以读入站的包，抓不到出站的包。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;            _recv_fd = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_ALL));&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>为什么dump生成core文件大小是0</title>
      <link>https://ykyi.net/?p=1099/</link>
      <pubDate>Wed, 25 Dec 2013 05:17:38 +0000</pubDate>
      <guid>https://ykyi.net/?p=1099/</guid>
      <description>&lt;p&gt;今天程序崩溃了，但是生成的core文件大小是0.&lt;/p&gt;
&lt;p&gt;用ulimit -c 查看生成core文件的大小限制是无限unlimited.&lt;/p&gt;
&lt;p&gt;也不是磁盘大小和写入权限的问题。&lt;/p&gt;
&lt;p&gt;但究竟是什么问题呢？&lt;/p&gt;
&lt;p&gt;捣了半天终于搞明白，原来是文件系统造成的。&lt;/p&gt;
&lt;p&gt;我是在vmware的虚拟机的debian linux上运行程序，文件系统用的是从host机windows 7挂载到/mnt/hgfs的windows的NTFS文件系统。&lt;/p&gt;
&lt;p&gt;后来我把程序转移动linux自己的文件系统，崩溃的时候就生成正常的core dump文件了。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Geneva, sans-serif; font-size: 16px; line-height: 22px; background-color: rgb(244, 244, 244);&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>CDT调试中的追踪点和断点有什么区别。</title>
      <link>https://ykyi.net/?p=1077/</link>
      <pubDate>Wed, 11 Dec 2013 02:31:13 +0000</pubDate>
      <guid>https://ykyi.net/?p=1077/</guid>
      <description>&lt;p style=&#34;margin: 0.4em 0px 10px; line-height: 24px; color: rgb(0, 0, 0); font-family: Arial, sans-serif; font-size: medium;&#34;&gt;
  追踪点（Tracepoint）被当成断点(breakpoint)的一种，但有两个不同点需要注意：
&lt;/p&gt;
&lt;p style=&#34;margin: 0.4em 0px 10px; line-height: 24px; color: rgb(0, 0, 0); font-family: Arial, sans-serif; font-size: medium;&#34;&gt;
  1. 当一个追踪点在一个调试会话中被创建时，它并不种入到二进制代码中，直到用户显式地开始追踪实验。这意味着，创建/修改/删除追踪点并不影响程序，直到追踪真正开始。
&lt;/p&gt;
&lt;p style=&#34;margin: 0.4em 0px 10px; line-height: 24px; color: rgb(0, 0, 0); font-family: Arial, sans-serif; font-size: medium;&#34;&gt;
  2. 简单的创建一个追踪点并不是非常有价值，因为它默认不会收集任何信息。重要的是，把操作(Actions)添加到Tracepoint，这样tracepoint被触发的时候，前面自定义的Action就大有用处了。
&lt;/p&gt;
&lt;p style=&#34;margin: 0.4em 0px 10px; line-height: 24px; color: rgb(0, 0, 0); font-family: Arial, sans-serif; font-size: medium;&#34;&gt;
  来自CDT官网的原文：
&lt;/p&gt;
&lt;p style=&#34;margin: 0.4em 0px 10px; line-height: 24px; color: rgb(0, 0, 0); font-family: Arial, sans-serif; font-size: medium;&#34;&gt;
  &lt;b&gt;Create Tracepoints&lt;/b&gt;
&lt;/p&gt;</description>
    </item>
    <item>
      <title>让eclipse自动生成的注释的时间显示英文，不用中文.</title>
      <link>https://ykyi.net/?p=1074/</link>
      <pubDate>Mon, 09 Dec 2013 08:21:55 +0000</pubDate>
      <guid>https://ykyi.net/?p=1074/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;这几天换成用eclipse在windows机器上编写代码，远程运行在linux上，并且在windows机器上远程调试。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;新建一个C++类的时候，eclipse/CDT自动生成注释，注释的时间用了中文，并且用的注释风格也不是我想要的。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&#34;3&#34;&gt;但我想全部用英文，这个如何解决了。在stackoverflow上找到了答案，并试验成功。&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&#34;3&#34;&gt;windows -&amp;gt; preferences -&amp;gt; c/c++ -&amp;gt; code style -&amp;gt; code template&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;在右边的注释模板中编辑File Comment，改成你想要的模式。比如我的：&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;/*&lt;strong&gt;*&lt;/strong&gt;*&lt;strong&gt;*&lt;/strong&gt;*&lt;strong&gt;*&lt;/strong&gt;*&lt;strong&gt;*&lt;/strong&gt;*&lt;strong&gt;*&lt;/strong&gt;*&lt;strong&gt;*&lt;/strong&gt;*&lt;strong&gt;*&lt;/strong&gt;***&lt;br&gt;
 * ${file_name}&lt;br&gt;
 * Author: ${user}&lt;br&gt;
 * Created on: ${date}&lt;br&gt;
 *&lt;strong&gt;*&lt;/strong&gt;*&lt;strong&gt;*&lt;/strong&gt;*&lt;strong&gt;*&lt;/strong&gt;*&lt;strong&gt;*&lt;/strong&gt;*&lt;strong&gt;*&lt;/strong&gt;*&lt;em&gt;&lt;strong&gt;&lt;span style=&#34;line-height: 1.6em;&#34;&gt;&lt;/strong&gt;&lt;/em&gt;*******/&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;再在eclipse的安装目录上找到eclipse.ini文件，加入：-Duser.language=en_US&lt;/p&gt;
&lt;p&gt;重启eclipse。现在${date}变量生产的日期就是全英文了。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Geneva, sans-serif; font-size: 16px; line-height: 22px;&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>CPRP和CPT是什么意思，有什么区别</title>
      <link>https://ykyi.net/?p=1065/</link>
      <pubDate>Fri, 06 Dec 2013 07:52:33 +0000</pubDate>
      <guid>https://ykyi.net/?p=1065/</guid>
      <description>&lt;p&gt;CPRP是Cost Per rating Point的缩写， CPT是cost per thousand的缩写。&lt;/p&gt;
&lt;p&gt;举例来说，某一个电视节目的一个商业广告时间槽位(commercial time slot)的价格是$1000，这个电视节目的收视率是10%（program rating），那么CPRP就是$1000除以10，即$100。&lt;/p&gt;
&lt;p&gt;而CPT则是广告到达某一个特定人群的花费。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Geneva, sans-serif; font-size: 16px; line-height: 22px;&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>如何从windows远程调试linux程序。</title>
      <link>https://ykyi.net/?p=1059/</link>
      <pubDate>Wed, 04 Dec 2013 03:29:06 +0000</pubDate>
      <guid>https://ykyi.net/?p=1059/</guid>
      <description>&lt;p class=&#34;p0&#34; data-mce-style=&#34;margin-top: 0pt; margin-bottom: 0pt; padding: 0px; border: 0px; font-size: 12px; font-family: Verdana, Geneva, sans-serif; vertical-align: baseline; line-height: 12pt; color: #000000; background-color: #f4f4f4;&#34; style=&#34;unicode-bidi: embed; margin: 0pt 0px; padding: 0px; border: 0px; font-family: Verdana, Geneva, sans-serif; vertical-align: baseline; line-height: 12pt; color: rgb(0, 0, 0); background-color: rgb(244, 244, 244);&#34;&gt;
  &lt;span data-mce-style=&#34;margin: 0px; padding: 0px; border: 0px; font-weight: inherit; font-style: inherit; font-size: 16px; vertical-align: baseline;&#34; style=&#34;margin: 0px; padding: 0px; border: 0px; font-weight: inherit; font-style: inherit; font-size: 16px; vertical-align: baseline;&#34;&gt;用gdb在远程linux机器上调试程序实在太不方便了。于是想到用eclipse的GUI调试。下面介绍&lt;span data-mce-style=&#34;margin: 0px; padding: 0px; border: 0px; font-weight: inherit; font-style: inherit; font-size: 16px; vertical-align: baseline;&#34; style=&#34;margin: 0px; padding: 0px; border: 0px; font-weight: inherit; font-style: inherit; vertical-align: baseline;&#34;&gt;如何从windows&lt;span data-mce-style=&#34;margin: 0px; padding: 0px; border: 0px; font-weight: inherit; font-style: inherit; font-size: 16px; vertical-align: baseline;&#34; style=&#34;margin: 0px; padding: 0px; border: 0px; font-weight: inherit; font-style: inherit; vertical-align: baseline;&#34;&gt;远程调试&lt;/span&gt;&lt;span data-mce-style=&#34;margin: 0px; padding: 0px; border: 0px; font-weight: inherit; font-style: inherit; font-size: 16px; vertical-align: baseline;&#34; style=&#34;margin: 0px; padding: 0px; border: 0px; font-weight: inherit; font-style: inherit; vertical-align: baseline;&#34;&gt;linux&lt;/span&gt;&lt;span data-mce-style=&#34;margin: 0px; padding: 0px; border: 0px; font-weight: inherit; font-style: inherit; font-size: 16px; vertical-align: baseline;&#34; style=&#34;margin: 0px; padding: 0px; border: 0px; font-weight: inherit; font-style: inherit; vertical-align: baseline;&#34;&gt;程序。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;</description>
    </item>
    <item>
      <title>设置变量GIT_CURL_VERBOSE可以帮助调试git出错</title>
      <link>https://ykyi.net/?p=1055/</link>
      <pubDate>Wed, 27 Nov 2013 04:43:22 +0000</pubDate>
      <guid>https://ykyi.net/?p=1055/</guid>
      <description>&lt;p&gt;今天操作git的时候又出错了:&lt;/p&gt;
&lt;p&gt;error: Failed connect to github.com:8080; No route to host while accessing &lt;a href=&#34;https://github.com/zausiu/gryphon/info/refs&#34;&gt;https://github.com/zausiu/gryphon/info/refs&lt;/a&gt;&lt;br&gt;
fatal: HTTP request failed&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;之前用公司的http代理上git, &lt;/p&gt;
&lt;p&gt;#git config -l&lt;/p&gt;
&lt;p&gt;http.proxy=http://web-proxy.oa.com:8080&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;设置变量GIT_CURL_VERBOSE可以看到详细的出错情况：&lt;/p&gt;
&lt;p&gt;#export GIT_CURL_VERBOSE=1&lt;/p&gt;
&lt;p&gt;# git pull&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Couldn&amp;rsquo;t find host github.com in the .netrc file; using defaults&lt;/li&gt;
&lt;li&gt;About to connect() to proxy web-proxy.oa.com port 8080 (#0)&lt;/li&gt;
&lt;li&gt;  Trying 10.14.36.100…&lt;/li&gt;
&lt;li&gt;0x23d67b0 is at send pipe head!&lt;/li&gt;
&lt;li&gt;STATE: CONNECT =&amp;gt; WAITCONNECT handle 0x23df5f0; (connection #0) &lt;/li&gt;
&lt;li&gt;No route to host&lt;/li&gt;
&lt;li&gt;Failed connect to github.com:8080; No route to host&lt;/li&gt;
&lt;li&gt;Closing connection #0&lt;/li&gt;
&lt;li&gt;Couldn&amp;rsquo;t find host github.com in the .netrc file; using defaults&lt;/li&gt;
&lt;li&gt;About to connect() to proxy web-proxy.oa.com port 8080 (#0)&lt;/li&gt;
&lt;li&gt;  Trying 10.14.36.100…&lt;/li&gt;
&lt;li&gt;0x23d67b0 is at send pipe head!&lt;/li&gt;
&lt;li&gt;STATE: CONNECT =&amp;gt; WAITCONNECT handle 0x23df5f0; (connection #0) &lt;/li&gt;
&lt;li&gt;No route to host&lt;/li&gt;
&lt;li&gt;Failed connect to github.com:8080; No route to host&lt;/li&gt;
&lt;li&gt;Closing connection #0&lt;br&gt;
error: Failed connect to github.com:8080; No route to host while accessing &lt;a href=&#34;https://github.com/zausiu/gryphon/info/refs&#34;&gt;https://github.com/zausiu/gryphon/info/refs&lt;/a&gt;&lt;br&gt;
fatal: HTTP request failed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Geneva, sans-serif; font-size: 16px; line-height: 22px;&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>packet captured和packet received by filter到底有什么区别</title>
      <link>https://ykyi.net/?p=1047/</link>
      <pubDate>Fri, 22 Nov 2013 05:22:58 +0000</pubDate>
      <guid>https://ykyi.net/?p=1047/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    我用的是linux.&amp;nbsp;结论是 packet received by filter是tcpdump从内核中拿到的且匹配命令上行指定的过滤条件的包， packet captured是经由pcap_loop, 或&amp;nbsp;&lt;span style=&#34;font-size: 13px;&#34;&gt;pcap_dispatch 或 pcap_next，把包交给回调处理过的包的数量。这两个数字的差值是tcpdump抓到的，还来不及处理的包。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: 13px;&#34;&gt;下面是讨论的一些细节:&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    /////////////
  &lt;/p&gt;
  &lt;p&gt;
    tcpdump的最后输出.&amp;nbsp;592个包captured,&amp;nbsp;&amp;nbsp;1184个包received&amp;nbsp;by&amp;nbsp;filter。。这个差值是不是表示有多少包tcpdump没来得及处理.
  &lt;/p&gt;
  &lt;p&gt;
    man&amp;nbsp;tcpdump上写得好复杂，received&amp;nbsp;by&amp;nbsp;filter的数字取决于OS&amp;#8230;&amp;nbsp;1.&amp;nbsp;包匹配不匹配命令行上指定的filter都算，如果匹配，有没有被tcpdump读出都算..&amp;nbsp;&amp;nbsp;&amp;nbsp;2.&amp;nbsp;只有匹配命令行上指定的filter的包才算，有没有被tcpdump读出都算.&amp;nbsp;&amp;nbsp;&amp;nbsp;3.&amp;nbsp;只有匹配filter才算，只有被tcpdump读出才算.
  &lt;/p&gt;
  &lt;p&gt;
    我的理解是：如果是第3种，那captured的数字和received&amp;nbsp;by&amp;nbsp;filter的数字就是一样的。&amp;nbsp;第2种的差值表示tcpdump来不及处理的包数量，理想状态上差值能为0.&amp;nbsp;&amp;nbsp;&amp;nbsp;第1种情况，基本上总是有差值。
  &lt;/p&gt;
  &lt;p&gt;
    我猜测我用的linux上应该是第2种情况.&amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    wangbin579()&amp;nbsp;10:18:54&amp;nbsp;&lt;br /&gt; 应该是匹配的才算received&amp;nbsp;by&amp;nbsp;filter，但奇怪的是，为啥你的系统，captured怎么少？&lt;br /&gt; wangbin579()&amp;nbsp;10:19:30&amp;nbsp;&lt;br /&gt; [root@hz0-12-157&amp;nbsp;~]#&amp;nbsp;tcpdump&amp;nbsp;-i&amp;nbsp;any&amp;nbsp;tcp&amp;nbsp;and&amp;nbsp;port&amp;nbsp;36524&amp;nbsp;or&amp;nbsp;3306&amp;nbsp;-w&amp;nbsp;all.pcap&lt;br /&gt; tcpdump:&amp;nbsp;listening&amp;nbsp;on&amp;nbsp;any,&amp;nbsp;link-type&amp;nbsp;LINUX_SLL&amp;nbsp;(Linux&amp;nbsp;cooked),&amp;nbsp;capture&amp;nbsp;size&amp;nbsp;65535&amp;nbsp;bytes&lt;br /&gt; 10757&amp;nbsp;packets&amp;nbsp;captured&lt;br /&gt; 11171&amp;nbsp;packets&amp;nbsp;received&amp;nbsp;by&amp;nbsp;filter&lt;br /&gt; 334&amp;nbsp;packets&amp;nbsp;dropped&amp;nbsp;by&amp;nbsp;kernel&lt;br /&gt; wangbin579()&amp;nbsp;10:20:07&amp;nbsp;&lt;br /&gt; 我们这边系统，基本可以认为packets&amp;nbsp;received&amp;nbsp;by&amp;nbsp;filter=packets&amp;nbsp;captured&amp;nbsp;+&amp;nbsp;packets&amp;nbsp;dropped&amp;nbsp;by&amp;nbsp;kernel
  &lt;/p&gt;
  &lt;p&gt;
    siu&amp;sup1;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;()&amp;nbsp;10:23:38&amp;nbsp;&lt;br /&gt; /home&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; height=&#34;25&#34; src=&#34;file:///C:\Users\KAMUSZ~1\AppData\Local\Temp\ksohtml\wps_clip_image-14656.png&#34; width=&#34;25&#34; /&gt;mus/tmp&amp;nbsp;#&amp;nbsp;time&amp;nbsp;time&amp;nbsp;tcpdump&amp;nbsp;-i&amp;nbsp;tunl0:1&amp;nbsp;&amp;nbsp;-w&amp;nbsp;tmp&lt;br /&gt; tcpdump:&amp;nbsp;listening&amp;nbsp;on&amp;nbsp;tunl0:1,&amp;nbsp;link-type&amp;nbsp;RAW&amp;nbsp;(Raw&amp;nbsp;IP),&amp;nbsp;capture&amp;nbsp;size&amp;nbsp;96&amp;nbsp;bytes&lt;br /&gt; 19508&amp;nbsp;packets&amp;nbsp;captured&lt;br /&gt; 39021&amp;nbsp;packets&amp;nbsp;received&amp;nbsp;by&amp;nbsp;filter&lt;br /&gt; 0&amp;nbsp;packets&amp;nbsp;dropped&amp;nbsp;by&amp;nbsp;kernel&lt;br /&gt; 0.01user&amp;nbsp;0.02system&amp;nbsp;0:17.04elapsed&amp;nbsp;0%CPU&amp;nbsp;(0avgtext+0avgdata&amp;nbsp;0maxresident)k&lt;br /&gt; 0inputs+0outputs&amp;nbsp;(0major+506minor)pagefaults&amp;nbsp;0swaps
  &lt;/p&gt;
  &lt;p&gt;
    real&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0m17.139s&lt;br /&gt; user&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0m0.012s&lt;br /&gt; sys&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0m0.028s&lt;br /&gt; wangbin579()&amp;nbsp;10:26:03&amp;nbsp;&lt;br /&gt; 如果是差是丢包，那么通过查看抓包文件，应该能看出很多不完整的session&lt;br /&gt; siu&amp;sup1;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;()&amp;nbsp;10:28:46&amp;nbsp;&lt;br /&gt; 我觉得差值是来不及写入磁盘的包.&lt;br /&gt; siu&amp;sup1;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;()&amp;nbsp;10:29:04&amp;nbsp;&lt;br /&gt; 再研究看看了。。谢谢啦/..&lt;br /&gt; wangbin579()&amp;nbsp;10:30:03&amp;nbsp;&lt;br /&gt; packets&amp;nbsp;captured是pcap_loop所设置的回调函数所调用的，一旦调用回调函数，就用统计&lt;br /&gt; wangbin579()&amp;nbsp;10:30:37&amp;nbsp;&lt;br /&gt; 有可能内核态部分和用户态部分，速度上不匹配，有延迟导致的？&lt;br /&gt; siu&amp;sup1;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;()&amp;nbsp;10:32:33&amp;nbsp;&lt;br /&gt; 我现在理解,&amp;nbsp;received&amp;nbsp;by&amp;nbsp;filter是pcap库从内核中拿到的又匹配命令行上filter的包的数量，&amp;nbsp;packets&amp;nbsp;captured是经由pcap_loop,&amp;nbsp;pcap_dispatch之类通过callback交付出去的包数量.&amp;nbsp;差值就是还没来得及处理的.&lt;br /&gt; wangbin579()&amp;nbsp;10:32:48&amp;nbsp;&lt;br /&gt; 17s，每秒也就2000多个，不算多，用户态程序应该来得及处理
  &lt;/p&gt;
  &lt;p&gt;
    wangbin579()&amp;nbsp;10:33:58&amp;nbsp;&lt;br /&gt; 我这边系统很破，处理速度也比这个快，也没有来不及处理&lt;br /&gt; wangbin579()&amp;nbsp;10:34:45&amp;nbsp;&lt;br /&gt; 看看我的：&lt;br /&gt; wangbin579()&amp;nbsp;10:34:47&amp;nbsp;&lt;br /&gt; [root@hz0-12-157&amp;nbsp;~]#&amp;nbsp;time&amp;nbsp;tcpdump&amp;nbsp;-i&amp;nbsp;any&amp;nbsp;tcp&amp;nbsp;and&amp;nbsp;port&amp;nbsp;36524&amp;nbsp;or&amp;nbsp;3306&amp;nbsp;-w&amp;nbsp;3306.pcap&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt; tcpdump:&amp;nbsp;listening&amp;nbsp;on&amp;nbsp;any,&amp;nbsp;link-type&amp;nbsp;LINUX_SLL&amp;nbsp;(Linux&amp;nbsp;cooked),&amp;nbsp;capture&amp;nbsp;size&amp;nbsp;65535&amp;nbsp;bytes&lt;br /&gt; 294663&amp;nbsp;packets&amp;nbsp;captured&lt;br /&gt; 295432&amp;nbsp;packets&amp;nbsp;received&amp;nbsp;by&amp;nbsp;filter&lt;br /&gt; 693&amp;nbsp;packets&amp;nbsp;dropped&amp;nbsp;by&amp;nbsp;kernel
  &lt;/p&gt;
  &lt;p&gt;
    real&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0m17.676s&lt;br /&gt; user&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0m0.897s&lt;br /&gt; sys&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0m3.502s&lt;br /&gt; wangbin579()&amp;nbsp;10:35:52&amp;nbsp;&lt;br /&gt; 量比你大7倍多，也没有出现来不及处理啊，当然我的是物理机，3G内存，&lt;br /&gt; siu&amp;sup1;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;()&amp;nbsp;10:36:59&amp;nbsp;&lt;br /&gt; 呃&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; height=&#34;25&#34; src=&#34;file:///C:\Users\KAMUSZ~1\AppData\Local\Temp\ksohtml\wps_clip_image-30198.png&#34; width=&#34;25&#34; /&gt;&amp;nbsp;那你觉得这个差值不是来不及处理的包么？。我觉得应该还是来不及处理的。我在想，可能是写到的磁盘文件系统是NFS之类的&amp;nbsp;&amp;#8230;.我继续排查一下。&lt;br /&gt; wangbin579()&amp;nbsp;10:37:43&amp;nbsp;&lt;br /&gt; 有可能，我的是写入本地磁盘。&lt;br /&gt; wangbin579()&amp;nbsp;10:37:58&amp;nbsp;&lt;br /&gt; 你这种情况，我还是第一次碰到&lt;br /&gt; siu&amp;sup1;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;()&amp;nbsp;10:39:05&amp;nbsp;&lt;br /&gt; 我先去运维那边了解下情况&amp;#8230;多谢啦&amp;nbsp;&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; height=&#34;25&#34; src=&#34;file:///C:\Users\KAMUSZ~1\AppData\Local\Temp\ksohtml\wps_clip_image-16870.png&#34; width=&#34;25&#34; /&gt;&lt;br /&gt; wangbin579()&amp;nbsp;10:39:18&amp;nbsp;&lt;br /&gt; 算涨见识了，还以为一般dropped&amp;nbsp;by&amp;nbsp;kernel为0就代表不丢包呢，居然还有你这种情况。&lt;br /&gt; 你可以看看抓包文件，session是不是很多不完整，如果不完整，你的推测是对的&lt;br /&gt; siu&amp;sup1;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;()&amp;nbsp;10:39:58&amp;nbsp;&lt;br /&gt; 嗯。呵呵~~&amp;nbsp;做IT，每天都会碰到挑战宇宙规律的现象。&lt;br /&gt; siu&amp;sup1;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;()&amp;nbsp;10:40:07&amp;nbsp;&lt;br /&gt; &lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; height=&#34;25&#34; src=&#34;file:///C:\Users\KAMUSZ~1\AppData\Local\Temp\ksohtml\wps_clip_image-6803.png&#34; width=&#34;25&#34; /&gt;&lt;br /&gt; мe(～&amp;nbsp;o&amp;nbsp;мe(632813052)&amp;nbsp;10:41:09&amp;nbsp;&lt;br /&gt; 呵呵&lt;br /&gt; wangbin579()&amp;nbsp;10:41:24&amp;nbsp;&lt;br /&gt; 其实，网络方面的问题，最复杂了。&lt;br /&gt; 我现在已经陷入到网络的汪洋大海之中了，各种各样的问题都会有，而且没有尽头。&lt;br /&gt; 早知道如此，3年前我就不搞这一块了&lt;br /&gt; siu&amp;sup1;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;()&amp;nbsp;10:42:30&amp;nbsp;&lt;br /&gt; 同感。写一点点代码，都非常难以调试。各种认为理所当然的假设，通通是bug的温床
  &lt;/p&gt;
  &lt;p&gt;
    @wangbin579&amp;nbsp;&amp;nbsp;麻烦你在tcpdump前加个time，。。把输出贴出来。我好像看出问题来了。
  &lt;/p&gt;
  &lt;p&gt;
    [root@hz0-12-157&amp;nbsp;~]#&amp;nbsp;time&amp;nbsp;tcpdump&amp;nbsp;-i&amp;nbsp;any&amp;nbsp;tcp&amp;nbsp;and&amp;nbsp;port&amp;nbsp;36524&amp;nbsp;or&amp;nbsp;3306&amp;nbsp;-w&amp;nbsp;3306.pcap&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt; tcpdump:&amp;nbsp;listening&amp;nbsp;on&amp;nbsp;any,&amp;nbsp;link-type&amp;nbsp;LINUX_SLL&amp;nbsp;(Linux&amp;nbsp;cooked),&amp;nbsp;capture&amp;nbsp;size&amp;nbsp;65535&amp;nbsp;bytes&lt;br /&gt; 294663&amp;nbsp;packets&amp;nbsp;captured&lt;br /&gt; 295432&amp;nbsp;packets&amp;nbsp;received&amp;nbsp;by&amp;nbsp;filter&lt;br /&gt; 693&amp;nbsp;packets&amp;nbsp;dropped&amp;nbsp;by&amp;nbsp;kernel
  &lt;/p&gt;
  &lt;p&gt;
    real&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0m17.676s&lt;br /&gt; user&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0m0.897s&lt;br /&gt; sys&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0m3.502s&lt;br /&gt; wangbin579()&amp;nbsp;10:56:03&amp;nbsp;&lt;br /&gt; 不是加了time了吗？&lt;br /&gt; wangbin579()&amp;nbsp;10:57:15&amp;nbsp;&lt;br /&gt; [root@hz0-12-157&amp;nbsp;~]#&amp;nbsp;time&amp;nbsp;time&amp;nbsp;tcpdump&amp;nbsp;-i&amp;nbsp;any&amp;nbsp;tcp&amp;nbsp;and&amp;nbsp;port&amp;nbsp;36524&amp;nbsp;or&amp;nbsp;3306&amp;nbsp;-w&amp;nbsp;3306.pcap&lt;br /&gt; tcpdump:&amp;nbsp;listening&amp;nbsp;on&amp;nbsp;any,&amp;nbsp;link-type&amp;nbsp;LINUX_SLL&amp;nbsp;(Linux&amp;nbsp;cooked),&amp;nbsp;capture&amp;nbsp;size&amp;nbsp;65535&amp;nbsp;bytes&lt;br /&gt; ^C202061&amp;nbsp;packets&amp;nbsp;captured&lt;br /&gt; 202523&amp;nbsp;packets&amp;nbsp;received&amp;nbsp;by&amp;nbsp;filter&lt;br /&gt; 369&amp;nbsp;packets&amp;nbsp;dropped&amp;nbsp;by&amp;nbsp;kernel&lt;br /&gt; 0.66user&amp;nbsp;2.50system&amp;nbsp;0:11.99elapsed&amp;nbsp;26%CPU&amp;nbsp;(0avgtext+0avgdata&amp;nbsp;24208maxresident)k&lt;br /&gt; 0inputs+105656outputs&amp;nbsp;(0major+660minor)pagefaults&amp;nbsp;0swaps
  &lt;/p&gt;
  &lt;p&gt;
    real&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0m11.999s&lt;br /&gt; user&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0m0.661s&lt;br /&gt; sys&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0m2.506s&lt;br /&gt; wangbin579()&amp;nbsp;10:57:26&amp;nbsp;&lt;br /&gt; 加两个，结果如上&lt;br /&gt; siu&amp;sup1;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;()&amp;nbsp;10:59:29&amp;nbsp;&lt;br /&gt; 问题找到的。我这边运行的tcpdump，根本就没有抢到cpu时间来处理.&lt;br /&gt; wangbin579()&amp;nbsp;11:00:05&amp;nbsp;&lt;br /&gt; &lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; height=&#34;25&#34; src=&#34;file:///C:\Users\KAMUSZ~1\AppData\Local\Temp\ksohtml\wps_clip_image-21252.png&#34; width=&#34;25&#34; /&gt;&lt;br /&gt; siu&amp;sup1;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;()&amp;nbsp;11:00:06&amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    Real&amp;nbsp;&amp;nbsp;0m3.914s
  &lt;/p&gt;
  &lt;p&gt;
    User&amp;nbsp;&amp;nbsp;0m0.008s
  &lt;/p&gt;
  &lt;p&gt;
    Sys&amp;nbsp;&amp;nbsp;&amp;nbsp;0m0.000s
  &lt;/p&gt;
  &lt;p&gt;
    跑了4秒钟，用户空间才抢到0.008秒，内核态几乎是0&amp;nbsp;&amp;#8230;.&lt;br /&gt; siu&amp;sup1;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;()&amp;nbsp;11:00:25&amp;nbsp;&lt;br /&gt; 那个差值确实是没有来得及处理的包的数量。&lt;br /&gt; wangbin579()&amp;nbsp;11:00:41&amp;nbsp;&lt;br /&gt; 奥，那你系统这么繁忙啊
  &lt;/p&gt;
  &lt;p&gt;
    siu&amp;sup1;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;&amp;ordm;()&amp;nbsp;11:02:22&amp;nbsp;&lt;br /&gt; 所以，解决了一个问题又会有新的颠覆宇宙规律的问题&amp;#8230;系统负载很高，但cpu使用率很低。。
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Geneva, sans-serif; font-size: 16px; line-height: 22px;&#34;&gt;copyright ykyi.net&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>昨天解决了tcpcopy的一个小却很重要的bug.</title>
      <link>https://ykyi.net/?p=1041/</link>
      <pubDate>Wed, 20 Nov 2013 02:48:59 +0000</pubDate>
      <guid>https://ykyi.net/?p=1041/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;tcpcopy的基础函数有个bug，流量比较大的时候，内核buffer满了。send系统调用发不完用户缓冲中的数据才会出现。然后加入了tcpcopy的QQ群，和作者稍稍讨论了一点时间。问了关于写论文和tc_session.c过于复杂的问题。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;(wangb) 10:00:55 &lt;br /&gt; &lt;a href=&#34;https://github.com//tcpcopy/pull/162&#34;&gt;https://github.com//tcpcopy/pull/162&lt;/a&gt;&lt;br /&gt; (wangb) 10:01:04 &lt;br /&gt; The bug arises when send system call returns with part of data transfered&lt;br /&gt; and part of data still need to be sent again.&lt;br /&gt; (wangb) 10:01:13 &lt;br /&gt; 常见于压力比较大的场合&lt;br /&gt; (wangb) 10:02:14 &lt;br /&gt; 当然如果系统参数设置好的话，这样的情况不常见。这也是为啥我这边无法重现的原因所在&lt;br /&gt; (wangb) 10:02:46 &lt;br /&gt; 当然昨天在开发gryphon，貌似遇到过一次&lt;br /&gt; (wangb) 10:03:06 &lt;br /&gt; gryphon给的压力，有时候真不是一般快和大&lt;br /&gt; siu1ooooooo(16236914) 10:03:14 &lt;br /&gt; 我在tcpcopy上作二次开发。碰到了个bug，最后追踪到了 tc_socket_send函数。&lt;br /&gt; siu1ooooooo(16236914) 10:03:52 &lt;br /&gt; 流量比较大的时候，内核buffer满了。send系统调用发不完用户缓冲中的数据才会出现。&lt;br /&gt; siu1ooooooo(16236914) 10:05:21 &lt;br /&gt; 希望能贡献更多代码的。。但是tc_session.c这个模拟tcp状态机的代码太难看懂了。&lt;br /&gt; (wangb) 10:05:49 &lt;br /&gt; 有些bug，程序员自身很难发现，往往需要依赖于用户的反馈，当然有上面的bug提出，就更好了&lt;br /&gt; tc_session.c这个模拟tcp状态机，其实不仅模拟tcp状态机，而为复杂的是模拟上层应用交互&lt;br /&gt; 光模拟tcp状态机，是远远不够的&lt;br /&gt; siu1ooooooo(16236914) 10:07:27 &lt;br /&gt; 有个想法， 把TCP的11个标准状态加入到tc_session中。可不可以做的。.&lt;br /&gt; (wangb) 10:09:13 &lt;br /&gt; 数据是死的，但测试服务器是活的。应该可以吧，但加入可能会更复杂。tc_session.c这个会进一步改进的，代码需简化和功能需独立，使其易懂&lt;br /&gt; siu1ooooooo(16236914) 10:09:31 &lt;br /&gt; 🙂&lt;br /&gt; (wangb) 10:10:33 &lt;br /&gt; 2010～2012.5月，初步探索阶段；2012.5～2014.5，为进一步探索阶段 2014.5～以后，进一步优化&lt;br /&gt; 因为tcpcopy刚开始，开发人员是无法知道复杂的互联网的各种应用的特性的，只有积累到一定程度，才能进一步优化。与其说是开发，不如说是探索&lt;br /&gt; siu1ooooooo(16236914) 10:12:10 &lt;br /&gt; 期待工程paper  &lt;br /&gt; siu1ooooooo(16236914) 10:12:43 &lt;br /&gt; tcpcopy稳定到了一个版本。先别加功能了。写paper吧  &lt;br /&gt; siu1ooooooo(16236914) 10:13:01 &lt;br /&gt; 投中EI应该问题不大。&lt;br /&gt; siu1ooooooo(16236914) 10:13:55 &lt;br /&gt; 中了paper，贡献者会迅速增多。&lt;br /&gt; wangb() 10:15:43 &lt;br /&gt; 其实写过sigcomm论文，但被拒，说应该投USENIX ATC&lt;br /&gt; wangb() 10:16:18 &lt;br /&gt; I don&amp;rsquo;t think that the research contribution of the paper is a good match for Sigcomm. Perhaps it would be a better match for &lt;br /&gt; a more practice-oriented conference like USENIX ATC. &lt;br /&gt; siu1ooooooo(16236914) 10:16:50 &lt;br /&gt; 后来呢&lt;br /&gt; wangb() 10:17:05 &lt;br /&gt; 确实，tcpcopy是基于实践的，从实践中摸索爬行的。后来我就先不写论文了&lt;br /&gt; siu1ooooooo(16236914) 10:17:22 &lt;br /&gt; 嗯。这是个工程实践性很强的探索啊&lt;br /&gt; wangb() 10:17:27 &lt;br /&gt; 要写论文，必须要有条件&lt;br /&gt; siu1ooooooo(16236914) 10:17:45 &lt;br /&gt; 喔。&lt;br /&gt; wangb() 10:18:06 &lt;br /&gt; 从交换机或者其它设备。镜像过来，这样测试系统和在线系统就没有关联，这样的论文是能够中USENIX ATC&lt;br /&gt; 的&lt;br /&gt; wangb() 10:19:13 &lt;br /&gt; tcpcopy最高端的应用，就是在交换机，利用分光镜或者其它镜像设备，利用高性能硬件，把用户的请求数据包复制给测试系统，可惜我没有这样的条件&lt;br /&gt; wangb() 10:19:38 &lt;br /&gt; 要是有这样的条件，我肯定要写论文了&lt;br /&gt; siu1ooooooo(16236914) 10:19:55 &lt;br /&gt; 呃。。没怎么看懂  &lt;br /&gt; siu1ooooooo(16236914) 10:21:49 &lt;br /&gt; 是说复制的流量要非常非常大才能中论文么&lt;br /&gt; siu1ooooooo(16236914) 10:21:59 &lt;br /&gt; 而非常大的流量需求硬件支持&lt;br /&gt; wangb() 10:22:02 &lt;br /&gt; twitter梦想的测试环境，其实完全可以用我们的tcpcopy来实现。交换机上面不是有来来往往的数据包吗？在那上面把请求数据包镜像到测试系统，测试系统搭一个跟在线类似的完整系统，这样测试系统跟在线系统承受类似的压力&lt;br /&gt; wangb() 10:22:17 &lt;br /&gt; 高端大气，才能中论文&lt;br /&gt; wangb() 10:22:48 &lt;br /&gt; 屌丝环境，写论文，还不被批啊&lt;br /&gt; siu1ooooooo(16236914) 10:23:14 &lt;br /&gt; 呃。是 。。。明白了。。想起以前学校的事情，懂了。&lt;br /&gt; wangb() 10:24:38 &lt;br /&gt; 总之，tcpcopy值得你去研究，期望有更多接班人把思想传承下去，代码可以推掉重来&lt;br /&gt; wangb() 10:25:10 &lt;br /&gt; 只要tcp协议还存在，这个思想，应该是最先进的，无法再先进了&lt;br /&gt; siu1ooooooo(16236914) 10:26:11 &lt;br /&gt; 需要好多的开发时间啊。..嗯。先上班了啊。多谢wangbin….&lt;br /&gt; wangb() 10:27:16 &lt;br /&gt; 慢慢来，这方面反正国外没有人做&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>为什么我的名字没有出现在github的contributor列表中.</title>
      <link>https://ykyi.net/?p=1033/</link>
      <pubDate>Wed, 20 Nov 2013 02:02:15 +0000</pubDate>
      <guid>https://ykyi.net/?p=1033/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;为什么我没有出现在github.com的contributor列表中.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;我提交了commit，但为什么我没有出现在贡献者列表中呢。有三个原因：&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;1. 检查你的commit中的邮箱信息，这个邮箱必须和你的github.com账号关联。怎么关联邮箱账号呢。先选择Account Setting, 在左边先Emails，于是就看到可以verify邮箱地址的页面了。关联邮箱地址后还有过一段时间，贡献者列表才会更新。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;2. 如果工程的贡献者名单列表超过了100个。就不会显示100个以后的贡献者了。官方HELP中说这是为了性能的考量。我觉得是码农偷懒，必竟这个需求太小了。绝大多数工程不会超过100个贡献者，于是码农不想解决这个小问题。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;3. 你的commit必须被提交到工程的默认分支上。如果提交到其它的分支上，你的名字就不会被显示。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size:16px;&#34;&gt;为什么我没有出现在github.com的contributor列表中.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size:16px;&#34;&gt;我提交了commit，但为什么我没有出现在贡献者列表中呢。有三个原因：&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size:16px;&#34;&gt;1.&amp;nbsp;检查你的commit中的邮箱信息，这个邮箱必须和你的github.com账号关联。怎么关联邮箱账号呢。先选择Account&amp;nbsp;Setting,&amp;nbsp;在左边先Emails，于是就看到可以verify邮箱地址的页面了。关联邮箱地址后还有过一段时间，贡献者列表才会更新。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size:16px;&#34;&gt;2.&amp;nbsp;如果工程的贡献者名单列表超过了100个。就不会显示100个以后的贡献者了。官方HELP中说这是为了性能的考量。我觉得是码农偷懒，必竟这个需求太小了。绝大多数工程不会超过100个贡献者，于是码农不想解决这个小问题。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size:16px;&#34;&gt;3.&amp;nbsp;你的commit必须被提交到工程的默认分支上。如果提交到其它的分支上，你的名字就不会被显示。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size:16px;&#34;&gt;&lt;span style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Geneva, sans-serif; line-height: 22px;&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>如何删掉github上的master分枝.</title>
      <link>https://ykyi.net/?p=1027/</link>
      <pubDate>Fri, 01 Nov 2013 04:53:26 +0000</pubDate>
      <guid>https://ykyi.net/?p=1027/</guid>
      <description>&lt;p style=&#34;text-align: justify; line-height: 20px; color: rgb(0, 0, 0); font-family: sans-serif; font-size: 16px;&#34;&gt;
  假设，代码已经被clone到了本地。第一步要做的就是创建一个新的分支，比如placeholder，然后用-D从本地删除master分支。
&lt;/p&gt;
&lt;div class=&#34;highlight-python&#34; style=&#34;color: rgb(0, 0, 0); font-family: sans-serif; font-size: 16px; line-height: normal;&#34;&gt;
  &lt;pre style=&#34;overflow-x: auto; overflow-y: hidden; padding: 5px; background-color: rgb(238, 255, 204); color: rgb(51, 51, 51); line-height: 15px; border-top-width: 1px; border-bottom-width: 1px; border-style: solid none; border-top-color: rgb(170, 204, 153); border-bottom-color: rgb(170, 204, 153);&#34;&gt;git branch placeholder
git checkout placeholder
git branch -D master&lt;/pre&gt;
&lt;/div&gt;
&lt;p style=&#34;text-align: justify; line-height: 20px; color: rgb(0, 0, 0); font-family: sans-serif; font-size: 16px;&#34;&gt;
  如果现在删除github上的master，会报错：
&lt;/p&gt;</description>
    </item>
    <item>
      <title>tcpcopy在视频广告组的二次开发</title>
      <link>https://ykyi.net/?p=1022/</link>
      <pubDate>Wed, 16 Oct 2013 09:01:05 +0000</pubDate>
      <guid>https://ykyi.net/?p=1022/</guid>
      <description>&lt;ol&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;流量筛选中的 “只导入某频道的流量”功能已经实现了。&lt;/p&gt;
&lt;p&gt;技术层面上，实际上是通过指定正则式的方法匹配HTTP请求中的GET方法中的URL来达到过滤的目的。&lt;/p&gt;
&lt;p&gt;所以，也可以用ty，ad_type, pf, coverid, oadid, v，plugin等出现在GET方法中的参数编写正则式来过滤流量。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;流量筛选中的“地域纬度筛选”暂时没有实现。&lt;/p&gt;
&lt;p&gt;因为地域纬度的信息不是以参数形式出现在GET方法的URL中，需要通过IP地址或者cookie的中QQ号信息来判断。&lt;/p&gt;
&lt;p&gt;还没最终决定是否实现这个功能。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;tcpcopy官方版本主要的应用场景是复制实时流量。所以部署的时候至少两台机器，一台线上机，另一台测试用机。为了方便压力测试，还引入了至少三台机器的高级模式。&lt;/p&gt;
&lt;p&gt;部署起来比较麻烦。&lt;/p&gt;
&lt;p&gt;如果“视频CPM广告的模拟投放，以及订单效果预估“只是从磁盘中读入以往的流量，针对这种场景，可以探索tcpcopy的单机离线模式，做到方便部署和使用。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;部分同学有一个误解.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;ldquo;将线上的实际访问流量，复制一份保存到本地服务器，用于后续使用&amp;rdquo;&lt;/p&gt;
&lt;p&gt;目前，tcpcopy的官方的版本没有把流量保存下来的功能，保存流量这个目前是用tcpdump的-w选项来做的。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;另外，技术上，tcpdump只能在IP层和TCP层指定过滤条件，不能用业务的逻辑过滤流量。第1点提到的流量筛选工作在tcpcopy读入实时流量时，或者从tcpdump存下的文件中读入流量时，在应用层指定过滤条件。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Geneva, sans-serif; font-size: 16px; line-height: 22px;&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux抓包技术简介</title>
      <link>https://ykyi.net/?p=1006/</link>
      <pubDate>Tue, 10 Sep 2013 05:05:03 +0000</pubDate>
      <guid>https://ykyi.net/?p=1006/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    Linux抓包技术简介
  &lt;/p&gt;
  &lt;p&gt;
    Author: zausiu@gmail.com
  &lt;/p&gt;
  &lt;p&gt;
    1.&amp;nbsp;简介
  &lt;/p&gt;
  &lt;p&gt;
    大多数应用常景下，我们在IP层上用AF_INET或AF_INET6作为socket的第一个参数，SOCK_STREAM或SOCK_DGRAM作为socket的第二个参数创建最为常见的IPv4或IPv6的TCP或UDP套接字。这样的套接字满足了绝大多数网络应用常景。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    本文简单介绍三种Linux平台下抓包，截获包的技术。它们提供一些更酷的功能。每种技术的水都很深，作者个人水平有限，按照自己的理解做一般的介绍。仅仅旨在起到科谱的作用。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    2.&amp;nbsp;RAW&amp;nbsp;SOCKET
  &lt;/p&gt;
  &lt;p&gt;
    参数SOCK_RAW可以作为socket函数的第二个参数传入，这样创建的套接字称为原始套接字。设置Socket的第一个参数可以让指定原始套接字开在数据链路层上或者网络层。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    下面的语句创建在数据链路层上的原始socket。
  &lt;/p&gt;
  &lt;p&gt;
    Socket(AF_PACKET,&amp;nbsp;SOCK_RAW,&amp;nbsp;htons(ETH_P_ALL));&amp;nbsp;&amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    在负载不大的情况下，读这个socket可以拿到本机收到的所有数据包。写入这个socket需要程序员负责填充各种包头的数据。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    Socket(AF_INET,&amp;nbsp;SOCK_RAW,&amp;nbsp;xxxxx协议号)；
  &lt;/p&gt;
  &lt;p&gt;
    在IP层上创建IPv4的RAW&amp;nbsp;socket，可以拿到各种经由IPv4的数据包，比如ICMP包，IGMP包等。Steven的&lt;Unix网络编程&gt;第三版第28.4节，第二段：&amp;ldquo;系统收到的UDP包和TCP包不会传给原始套接字&amp;rdquo;。但读tcpcopy的源代码时，确实用了原始套接字在网络层读UDP和TCP包。难道书上写的过时了。见代码，来自tcpcopy：
  &lt;/p&gt;
  &lt;p&gt;
    #if&amp;nbsp;(TCPCOPY_UDP)
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fd&amp;nbsp;=&amp;nbsp;socket(AF_INET,&amp;nbsp;SOCK_RAW,&amp;nbsp;IPPROTO_UDP);
  &lt;/p&gt;
  &lt;p&gt;
    #else
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fd&amp;nbsp;=&amp;nbsp;socket(AF_INET,&amp;nbsp;SOCK_RAW,&amp;nbsp;IPPROTO_TCP);
  &lt;/p&gt;
  &lt;p&gt;
    #endif
  &lt;/p&gt;
  &lt;p&gt;
    另外，在IP层上创建的原始套接字有一个选项：IP_HDRINCL，它被开启时，则内核帮助填充IP包头。Linux默认没有开启这个选项。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    3.&amp;nbsp;NF_Queue
  &lt;/p&gt;
  &lt;p&gt;
    NF_Queue是用户空间的一个库，需要内核模块NETFILTER_NETLINK_QUEUE的支持。官方网址：&lt;a href=&#34;http://www.netfilter.org/&#34;&gt;http://www.netfilter.org&lt;/a&gt;。通过这个库可以在数据包被发往用户空间处理前截获数据包，或者在数据包被发往网卡前截获数据库。截获后，可以修改数据包的内容，并决定是否丢充这个数据库。
  &lt;/p&gt;
  &lt;p&gt;
    NF_Queue可以用来编写防火墙等安全软件。
  &lt;/p&gt;
  &lt;p&gt;
    Tcpcopy使用NF_Queue丢弃测试中的程序回复给真实客户程序的数据包，使测试中程序回复的报文不影响真实客户程序。
  &lt;/p&gt;
  &lt;p&gt;
    另一个提供类似功能的库是IP_Queue，它已经被废弃。NF_Queue可以完全取代IP_Queue。我们用的tlinux，内核中built-in了NF_Queue模块。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    4.&amp;nbsp;libpcap
  &lt;/p&gt;
  &lt;p&gt;
    大名鼎鼎的Libpcap是一个古老的可以工作在所有Unix-like平台上的抓包库，比linux年纪更大。Tcpdump的广泛使用让libpcap成为事实上的行业标准。它可以很方便的编写抓取数据链路层上的数据包，并可以设置过滤条件在内核级别只复制关心的数据包，而数据链路层上的原始套接字会尽最大努力复制所有的包，所以libpcap的工作效率高。而且，pcap使用方便。下面是一个很简单的使用pcap抓到发往80端口的tcp包并打印源IP，目的IP，和目的端口号的程序。非常短，很容易看，起到介绍libpcap的作用。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;int&amp;nbsp;main(int&amp;nbsp;argc,&amp;nbsp;char&amp;nbsp;*argv[])
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;{
  &lt;/p&gt;
  &lt;p&gt;
    pcap_t&amp;nbsp;*handle; //&amp;nbsp;pcap用的句柄，和其它各种句柄一样。
  &lt;/p&gt;
  &lt;p&gt;
    char&amp;nbsp;*dev; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;网络接口名，如eth0,&amp;nbsp;eth1,&amp;nbsp;tunl0&amp;nbsp;之类
  &lt;/p&gt;
  &lt;p&gt;
    char&amp;nbsp;errbuf[PCAP_ERRBUF_SIZE]; //&amp;nbsp;存描述出错原因的缓冲
  &lt;/p&gt;
  &lt;p&gt;
    struct&amp;nbsp;bpf_program&amp;nbsp;fp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;pcap用来过滤数据包用
  &lt;/p&gt;
  &lt;p&gt;
    char&amp;nbsp;filter_exp[]&amp;nbsp;=&amp;nbsp;&#34;tcp&amp;nbsp;and&amp;nbsp;dst&amp;nbsp;port&amp;nbsp;80&#34;;&amp;nbsp;//&amp;nbsp;过滤字符串，和tcpdump的写法一样
  &lt;/p&gt;
  &lt;p&gt;
    struct&amp;nbsp;pcap_pkthdr&amp;nbsp;header;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;pcap自己用的包头
  &lt;/p&gt;
  &lt;p&gt;
    const&amp;nbsp;u_char&amp;nbsp;*packet; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;pcap包头后的数据，即抓到的数据
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    int&amp;nbsp;len_of_iphdr;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;ip头的长度
  &lt;/p&gt;
  &lt;p&gt;
    struct&amp;nbsp;in_addr&amp;nbsp;src_ip;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;源IP地址
  &lt;/p&gt;
  &lt;p&gt;
    struct&amp;nbsp;in_addr&amp;nbsp;dst_ip;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;目的IP
  &lt;/p&gt;
  &lt;p&gt;
    const&amp;nbsp;u_char&amp;nbsp;*ip_hdr_addr; //&amp;nbsp;IP头的首地址
  &lt;/p&gt;
  &lt;p&gt;
    const&amp;nbsp;u_char&amp;nbsp;*tcp_hdr_addr;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;tcp头的首地址
  &lt;/p&gt;
  &lt;p&gt;
    struct&amp;nbsp;tcphdr&amp;nbsp;*tcp_hdr;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;tcp头结构体
  &lt;/p&gt;
  &lt;p&gt;
    u_short&amp;nbsp;dst_port;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;目的端口
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    //&amp;nbsp;如果命令行指定网卡名
  &lt;/p&gt;
  &lt;p&gt;
    if&amp;nbsp;(argv[1])
  &lt;/p&gt;
  &lt;p&gt;
    dev&amp;nbsp;=&amp;nbsp;argv[1];&amp;nbsp;//就用指定的网卡
  &lt;/p&gt;
  &lt;p&gt;
    else
  &lt;/p&gt;
  &lt;p&gt;
    dev&amp;nbsp;=&amp;nbsp;&#34;eth0&#34;;&amp;nbsp;//否则用eth0
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    }
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;用pcap打开这个网卡
  &lt;/p&gt;
  &lt;p&gt;
    handle&amp;nbsp;=&amp;nbsp;pcap_open_live(dev,&amp;nbsp;BUFSIZ,&amp;nbsp;0,&amp;nbsp;1000,&amp;nbsp;errbuf);
  &lt;/p&gt;
  &lt;p&gt;
    if&amp;nbsp;(handle&amp;nbsp;==&amp;nbsp;NULL)&amp;nbsp;{&amp;nbsp;&amp;nbsp;//&amp;nbsp;打开网卡出错
  &lt;/p&gt;
  &lt;p&gt;
    fprintf(stderr,&amp;nbsp;&#34;Couldn&#39;t&amp;nbsp;open&amp;nbsp;device&amp;nbsp;%s:&amp;nbsp;%s\n&#34;,&amp;nbsp;dev,&amp;nbsp;errbuf);
  &lt;/p&gt;
  &lt;p&gt;
    return(2);
  &lt;/p&gt;
  &lt;p&gt;
    }
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;编译过滤文件
  &lt;/p&gt;
  &lt;p&gt;
    if&amp;nbsp;(pcap_compile(handle,&amp;nbsp;&amp;fp,&amp;nbsp;filter_exp,&amp;nbsp;0,&amp;nbsp;net)&amp;nbsp;==&amp;nbsp;-1)&amp;nbsp;{
  &lt;/p&gt;
  &lt;p&gt;
    fprintf(stderr,&amp;nbsp;&#34;Couldn&#39;t&amp;nbsp;parse&amp;nbsp;filter&amp;nbsp;%s:&amp;nbsp;%s\n&#34;,&amp;nbsp;filter_exp,&amp;nbsp;pcap_geterr(handle));
  &lt;/p&gt;
  &lt;p&gt;
    return(2);
  &lt;/p&gt;
  &lt;p&gt;
    }
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;设置过滤条件
  &lt;/p&gt;
  &lt;p&gt;
    if&amp;nbsp;(pcap_setfilter(handle,&amp;nbsp;&amp;fp)&amp;nbsp;==&amp;nbsp;-1)&amp;nbsp;{
  &lt;/p&gt;
  &lt;p&gt;
    fprintf(stderr,&amp;nbsp;&#34;Couldn&#39;t&amp;nbsp;install&amp;nbsp;filter&amp;nbsp;%s:&amp;nbsp;%s\n&#34;,&amp;nbsp;filter_exp,&amp;nbsp;pcap_geterr(handle));
  &lt;/p&gt;
  &lt;p&gt;
    return(2);
  &lt;/p&gt;
  &lt;p&gt;
    }
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;抓包
  &lt;/p&gt;
  &lt;p&gt;
    packet&amp;nbsp;=&amp;nbsp;pcap_next(handle,&amp;nbsp;&amp;header);
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    //&amp;nbsp;至此packet指向抓到的一个目标端口号是80的数据链路层的包
  &lt;/p&gt;
  &lt;p&gt;
    //&amp;nbsp;它的包结构是&amp;nbsp;14字节以太网包头&amp;nbsp;+&amp;nbsp;可变IPv4包头&amp;nbsp;+&amp;nbsp;TCP包头
  &lt;/p&gt;
  &lt;p&gt;
    ip_hdr_addr&amp;nbsp;=&amp;nbsp;(u_char*)(packet&amp;nbsp;+&amp;nbsp;sizeof(struct&amp;nbsp;ethernet_hdr));
  &lt;/p&gt;
  &lt;p&gt;
    src_ip.s_addr&amp;nbsp;=&amp;nbsp;((struct&amp;nbsp;iphdr*)ip_hdr_addr)-&gt;saddr;
  &lt;/p&gt;
  &lt;p&gt;
    dst_ip.s_addr&amp;nbsp;=&amp;nbsp;((struct&amp;nbsp;iphdr*)ip_hdr_addr)-&gt;daddr;
  &lt;/p&gt;
  &lt;p&gt;
    len_of_iphdr&amp;nbsp;=&amp;nbsp;((struct&amp;nbsp;iphdr*)ip_hdr_addr)-&gt;ihl&amp;nbsp;*&amp;nbsp;4;
  &lt;/p&gt;
  &lt;p&gt;
    tcp_hdr_addr&amp;nbsp;=&amp;nbsp;ip_hdr_addr&amp;nbsp;+&amp;nbsp;len_of_iphdr;
  &lt;/p&gt;
  &lt;p&gt;
    tcp_hdr&amp;nbsp;=&amp;nbsp;(struct&amp;nbsp;tcphdr*)tcp_hdr_addr;
  &lt;/p&gt;
  &lt;p&gt;
    dst_port&amp;nbsp;=&amp;nbsp;tcp_hdr-&gt;dest;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    //&amp;nbsp;经过上面的各种指针偏移，下面打印源IP和目标IP和目标端口.
  &lt;/p&gt;
  &lt;p&gt;
    printf(&#34;src&amp;nbsp;addr&amp;nbsp;%s\n&#34;,&amp;nbsp;inet_ntoa(src_ip));
  &lt;/p&gt;
  &lt;p&gt;
    printf(&#34;dst&amp;nbsp;addr&amp;nbsp;%s\n&#34;,&amp;nbsp;inet_ntoa(dst_ip));
  &lt;/p&gt;
  &lt;p&gt;
    printf(&#34;dst_port&amp;nbsp;%d\n&#34;,&amp;nbsp;ntohs(dst_port));
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    /*&amp;nbsp;And&amp;nbsp;close&amp;nbsp;the&amp;nbsp;session&amp;nbsp;*/
  &lt;/p&gt;
  &lt;p&gt;
    pcap_close(handle);
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    return(0);
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;}
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    5.&amp;nbsp;总结
  &lt;/p&gt;
  &lt;p&gt;
    本文只是一个非常简单的介绍。如需要进阶学习，Stevens的网络编译有更详细地关于Raw&amp;nbsp;Socket的内容，研究NF_Queue技术则需要读源代码和收集散在社区各个角落的资料了，而讲libpcap有两篇很好的文章：
  &lt;/p&gt;
  &lt;p&gt;
    &#34;&lt;a href=&#34;http://recursos.aldabaknocking.com/libpcapHakin9LuisMartinGarcia.pdf&#34;&gt;Programming&amp;nbsp;with&amp;nbsp;Libpcap&amp;nbsp;&amp;ndash;&amp;nbsp;Sniffing&amp;nbsp;the&amp;nbsp;network&amp;nbsp;from&amp;nbsp;our&amp;nbsp;own&amp;nbsp;application&amp;nbsp;&lt;/a&gt;&#34;用Libpcap编程，在我们的程序中嗅探网络。非常漂亮的pdf文档。
  &lt;/p&gt;
  &lt;p&gt;
    &lt;a href=&#34;http://recursos.aldabaknocking.com/libpcapHakin9LuisMartinGarcia.pdf&#34;&gt;http://recursos.aldabaknocking.com/libpcapHakin9LuisMartinGarcia.pdf&lt;/a&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;a href=&#34;http://yuba.stanford.edu/~casado/pcap/section1.html&#34;&gt;The&amp;nbsp;Sniffer&amp;rsquo;s&amp;nbsp;Guide&amp;nbsp;to&amp;nbsp;Raw&amp;nbsp;Traffic&lt;/a&gt;&amp;nbsp;嗅探器教程。斯坦福大学的Geek于大概2001年写的。
  &lt;/p&gt;
  &lt;p&gt;
    &lt;a href=&#34;http://yuba.stanford.edu/~casado/pcap/section1.html&#34;&gt;http://yuba.stanford.edu/~casado/pcap/section1.html&lt;/a&gt;
  &lt;/p&gt;
  &lt;p&gt;
    copyright ykyi.net
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>Linux是从什么时候开始支持线程的.</title>
      <link>https://ykyi.net/?p=1003/</link>
      <pubDate>Mon, 09 Sep 2013 04:57:26 +0000</pubDate>
      <guid>https://ykyi.net/?p=1003/</guid>
      <description>&lt;p&gt;几天前和同事吃饭，谈论到一个问题：linux从什么时候开始支持线程。他说linux中的线程出现的很晚，直到2.2.x才有。&lt;/p&gt;
&lt;p&gt;我觉得不对啊，怎么会那么晚。然后它用手机搜索了一下，linux对POSIX线程库的支持确实很晚，直到2.6.x才有。&lt;/p&gt;
&lt;p&gt;但我觉得POSIX线程库只不过是用户空间用来创建线程的接口，并不能证明那么晚linux才支持线程。&lt;/p&gt;
&lt;p&gt;后来用PC的时候搜索了一下，在The Linux Document Project的官方网站找到了答案：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.tldp.org/FAQ/Threads-FAQ/Support.html&#34;&gt;http://www.tldp.org/FAQ/Threads-FAQ/Support.html&lt;/a&gt;&lt;/p&gt;
&lt;p style=&#34;color: rgb(0, 0, 0); font-family: Simsun; font-size: medium; line-height: normal;&#34;&gt;
  &lt;font size=&#34;+3&#34;&gt;Does Linux support threads?&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;Yes. As of 1.3.56, Linux has supported kernel-space multithreading. There also have been user-space thread libraries around as early as 1.0.9. There is on-going effort to refine and make the kernel more reentrant. With the introduction of 2.1.x, the memory space is being revised so that the kernel can access the user memory more quickly.&lt;/p&gt;</description>
    </item>
    <item>
      <title>用线上机测试tcpcopy基本通过。支持旧模式，Advanced模式失败</title>
      <link>https://ykyi.net/?p=999/</link>
      <pubDate>Mon, 09 Sep 2013 01:54:06 +0000</pubDate>
      <guid>https://ykyi.net/?p=999/</guid>
      <description>&lt;p class=&#34;p0&#34;&gt;
  &lt;b&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;测试结果介绍：&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34;&gt;&amp;nbsp;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;color:blue&#34;&gt;tcpcopy&lt;/span&gt;&lt;span style=&#34;font-family:宋体;color:blue&#34;&gt;在编译期配置成使用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34; style=&#34;color:blue&#34;&gt;NFQueue&lt;/span&gt;&lt;span style=&#34;font-family:宋体;color:blue&#34;&gt;模式，用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34; style=&#34;color:blue&#34;&gt;Raw Socket&lt;/span&gt;&lt;span style=&#34;font-family:宋体;&lt;br /&gt;&lt;br /&gt;
color:blue&#34;&gt;抓包。线上机的流量被成功复制并导向测试机。经改动的&lt;span lang=&#34;EN-US&#34;&gt;tcpd&lt;/span&gt;初期工作正常。&lt;/span&gt;&lt;span lang=&#34;EN-US&#34; style=&#34;color:blue&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span style=&#34;font-family:宋体&#34;&gt;改动版的&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tcpd(&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;实际上是一个&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;echo&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;服务器&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;。测试机上的&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tcpd&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;把收到的报文被打印到日志文件。但日志文件到&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;6M&lt;/span&gt;&lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;+&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;大小的时候，就停止打印。目前还没有查到原因，可能是改动后的&lt;span lang=&#34;EN-US&#34;&gt;tcpd&lt;/span&gt;的&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;Bug&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;。此时，&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tcpdump&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;仍然抓到大量从线上机复制来的真实流量到达测试机。&lt;span lang=&#34;EN-US&#34;&gt;tcpcopy&lt;/span&gt;应该是工作正常的。&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;&amp;nbsp;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体;color:blue&#34;&gt;tcpcopy&lt;/span&gt;&lt;span style=&#34;font-family:宋体;color:blue&#34;&gt;被编译成使用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34; style=&#34;color:blue&#34;&gt;libpcap&lt;/span&gt;&lt;span style=&#34;font-family:宋体;color:blue&#34;&gt;抓包时&lt;/span&gt;&lt;span style=&#34;font-family:宋体;color:red&#34;&gt;不能&lt;/span&gt;&lt;span style=&#34;font-family:宋体;&lt;br /&gt;&lt;br /&gt;
color:blue&#34;&gt;在线上机上正常工作。&lt;/span&gt;&lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;tcpdump&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;没有抓到预期从线上机复制到测试机的报文。原因是：线上机&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;10.130.68.100&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;上的真实流量从网络接口&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tunl0:0&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;进入，从网络接口&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;eth1&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;发出。分析&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tcpd&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;的日志发现，&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tcpd&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;使用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;libpcap&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;只拿到&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tunl0&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;的&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;IP&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;，没有发现&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tunl0:0&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;的&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;IP&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;。需要了解&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;IP&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;隧道，和&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;libpcap&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;库的相关知识，有可能解决这个问题。&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34;&gt;&amp;nbsp;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span style=&#34;font-family:宋体;color:blue&#34;&gt;编译成使用&lt;span lang=&#34;EN-US&#34;&gt;Raw Socket&lt;/span&gt;抓包，和&lt;/span&gt;&lt;span lang=&#34;EN-US&#34; style=&#34;color:blue&#34;&gt;Advanced&lt;/span&gt;&lt;span style=&#34;font-family:宋体;color:blue&#34;&gt;模式时，&lt;span lang=&#34;EN-US&#34;&gt;tcpcopy&lt;/span&gt;启动失败，错误日志显示&lt;/span&gt;&lt;span lang=&#34;EN-US&#34; style=&#34;color:blue&#34;&gt;Advanced&lt;/span&gt;&lt;span style=&#34;font-family:宋体;&lt;br /&gt;&lt;br /&gt;
color:blue&#34;&gt;模式只能使用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34; style=&#34;color:blue&#34;&gt;libpcap&lt;/span&gt;&lt;span style=&#34;font-family:宋体;color:blue&#34;&gt;库抓包。&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;因此，只有在解决&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;libpcap&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;正确识别&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tunl0:0&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;网络接口后，才能在线上机上运行&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tcpcopy&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;。&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34;&gt;&amp;nbsp;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;b&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;预备知识：&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;Tcpcopy&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;可以编译成用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;libpcap&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;抓包或者使用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;Raw Socket&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;抓包。&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;Libpcap&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;库是&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tcpdump&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;使用的抓包库，&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;Raw Socket&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;是操作系统内建的功能。&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span style=&#34;font-family:宋体&#34;&gt;官方文档建议用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;libpcap&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;抓包，以获得更高性能和较低丢包率。&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;&amp;nbsp;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;Tcpcopy&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;在编译期指定工作模式。&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tcpcopy&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;目前有两种工作模式，一种使用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;IPQueue&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;技术或者&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;NFQueue&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;技术。&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;NFQueue&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;技术是用来替代&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;IPQueue&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;技术的。我们目前使用的&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tlinux&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;，内建了&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;NFQueue&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;内核模块，没有开启&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;IPQueue&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;模块。因为&lt;span lang=&#34;EN-US&#34;&gt;NFQueue&lt;/span&gt;是内建的即&lt;span lang=&#34;EN-US&#34;&gt;CONF_XXXXXX = y&lt;/span&gt;，而不是编译成模块，即&lt;span lang=&#34;EN-US&#34;&gt;CONF_XXXXX = m, &lt;/span&gt;所以我们在环境中不需要使用&lt;span lang=&#34;EN-US&#34;&gt;modprobe &lt;/span&gt;加载&lt;span lang=&#34;EN-US&#34;&gt;IPQueue&lt;/span&gt;或者&lt;span lang=&#34;EN-US&#34;&gt;NFQueue&lt;/span&gt;模块。忽略官方文档中提到的&lt;span lang=&#34;EN-US&#34;&gt;modprobe ip_queue&lt;/span&gt;。&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34;&gt;&amp;nbsp;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;b&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;测试步骤：&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;&amp;nbsp;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span style=&#34;font-family:宋体&#34;&gt;使用&lt;span lang=&#34;EN-US&#34;&gt;NFQueue&lt;/span&gt;模式：&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span style=&#34;font-family:宋体&#34;&gt;线上机：&lt;span lang=&#34;EN-US&#34;&gt;10.130.68.100&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span style=&#34;font-family:宋体&#34;&gt;编译&lt;span lang=&#34;EN-US&#34;&gt;tcpcopy&lt;/span&gt;时指定使用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;NFQueue&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;。&lt;span style=&#34;color:blue&#34;&gt;不要指定 &lt;/span&gt;&lt;/span&gt;&lt;span lang=&#34;EN-US&#34; style=&#34;color:blue&#34;&gt;&amp;#8211;enable-pcap&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;，则默认使用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;raw socket&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;抓包。用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;pcap&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;抓包时识别不到网络接口&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tunl0:0&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;，而&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tunl0:0&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;是真实流量的入口。&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;# ./configure &amp;#8211;enable-nfqueue &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;#./make&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span style=&#34;font-family:宋体&#34;&gt;生成的&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tcpcopy&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;在 &lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;src/tcpcopy &lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;目录下。&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span style=&#34;font-family:宋体&#34;&gt;运行&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tcpcopy&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;命令，把流量复制到测试机：&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;# ./tcpcopy -x 80-10.213.243.156 &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span style=&#34;font-family:宋体&#34;&gt;测试机：&lt;span lang=&#34;EN-US&#34;&gt;10.213.243.156&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span style=&#34;font-family:宋体&#34;&gt;编译&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tcpcopy&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;时同样指定&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;&amp;#8211;enable-nfqueue&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;，不要指定&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;&amp;#8211;enable-pcap&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;。然后运行&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;intercept&lt;/span&gt;&lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;# ./intercept&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;&amp;nbsp;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span style=&#34;font-family:宋体&#34;&gt;使用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;Advanced&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;模式：&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span style=&#34;font-family:宋体&#34;&gt;因为暂时未能解决用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;libpcap&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;识别到网络设备&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;tunel0:0&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;的问题，实际上&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;Advanced&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;模式暂时不能工作。根据以前的使用经验，用&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;Advanced&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;模式时需要注意两点：&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;1. &lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;在&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;./configure&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;时指定 &lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;&amp;#8211;enable-advaned &lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;和 &lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;&amp;#8211;enable-pcap&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;。&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;2. Advanced&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;模式需要两台测试机，需要设成一条路由把复制后的真实流量导向测试机。需要更改默认路由：删掉当前的默认路由，新的默认路由从正确的网卡指向测试机&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;的&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;IP&lt;/span&gt;&lt;span style=&#34;font-family:宋体&#34;&gt;。&lt;span lang=&#34;EN-US&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;# route del default&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;# route add default gw 10.213.243.156 dev eth1&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34;&gt;
  &lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;span style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Geneva, sans-serif; font-size: 16px; line-height: 22px;&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;span lang=&#34;EN-US&#34; style=&#34;font-family:宋体&#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;
&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tcpcopy初体验.</title>
      <link>https://ykyi.net/?p=984/</link>
      <pubDate>Mon, 26 Aug 2013 03:28:13 +0000</pubDate>
      <guid>https://ykyi.net/?p=984/</guid>
      <description>&lt;p&gt;Tcpcopy 初体验&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Tcpcopy是一个模拟真实流量的测试工具。它的工作基本思想是，从已经上线的服务器复制一份真实流量到测试服务器。Tcpcopy的代码开源，代码仓库放在&lt;a href=&#34;https://github.com/wangbin579/tcpcopy&#34;&gt;https://github.com/wangbin579/tcpcopy&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;经过初步学习，已成功在公司的测试机器上部署tcpcopy，并用简单的DEMO程序测试达到预期目的。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;**1.**&lt;strong&gt;安装&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;因为作者写的安装介绍只提到最基本的信息，而测试环境各不一样，在我用的测试机的实际安装过程中碰到一些问题。这时问题在这里列出，以供后来者参考，以节省时间。测试机：10.12.194.199 ； 10.12.194.212 ； 10.12.194.214 。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1.1&lt;/strong&gt; &lt;strong&gt;需要额外安装的库：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;需要在网站 &lt;a href=&#34;http://www.netfilter.org&#34;&gt;www.netfilter.org&lt;/a&gt; 下载 libmnl， libnfnetlink， libnetfilter_queue 三个工程并安装。 安装顺序为 libmnl， libnfnetlink, libnetfilter_queue，因为第三个依赖第二个，第二个依赖第一个。安装方法是GNU工具的传统三板斧方式： ./configure ; make; make install。这三个工程生成三个.so库放置到/usr/local/lib，而我们用的操作系统环境并没有把该目录列在默认查找库文件的目录列表中，因此要编辑 /etc/ld.so.conf 文件，把目录/usr/local/lib 加入，再运行 ldconfig 更新ld链接程序使用的cache。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1.2 IP_Queue****和NFQueue内核模块：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这两个内核模块给在用户空间编写处理内核空间中传递网络数据包提供接口。它们的区别是IP_Queue是旧的实现，仅支持IPv4，NFQueue是新的实现。Tcpcopy工程依赖这两个模块之一。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Tcpcopy官方文档中多次提到tcpcopy在内核版本小于3.5时默认使用IP_Queue，并在使用例子中有一步操作：&lt;/p&gt;
&lt;p&gt;# modprobe ip_queue&lt;/p&gt;
&lt;p&gt;这个操作是确保加载ip_queue模块到内核。&lt;/p&gt;
&lt;p&gt;我们的测试环境的内核版本号是2.6.32，按照官方文档介绍，内核版本小于3.5，于是使用#modprobe ip_queue命令，结果报错显示我们使用的内核没有启用动态模块加载。&lt;/p&gt;
&lt;p&gt;于是再用 # zcat /proc/config.gz 检查当前内核的配置，发现CONFIG_IP_NF_QUEUE is not set, 说明IP_Queue模块没有被buit-in，再查找NFQueue的配置项发现 CONFIG_NETFILTER_NETLINK_QUEUE=y。&lt;/p&gt;
&lt;p&gt;所以，在我们的环境中，应该忽略官方文档中# modprobe ip_queue，我们的内核已经内建了比IPQueue更新的&lt;strong&gt;NFQueue****。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1.3&lt;/strong&gt; &lt;strong&gt;编译安装tcpcopy&lt;/strong&gt;**：**&lt;/p&gt;
&lt;p&gt;官方文档中把已经正常运行业务的服务器称为在线服务器(online server)，把运行待测试用的服务器称为目标服务器(target server)。&lt;/p&gt;
&lt;p&gt;在在线服务器端运行配置命令时务必指定 –enable-nfqueue，这是因为我们用的内核中只有NFQueue，如果不指定这个选项，编译出的tcpcopy不会运行成功，会在日志文件中报错：please make sure ip queue is running.&lt;/p&gt;
&lt;p&gt;# ./configure –enable-nfqueue –enable-pcap&lt;/p&gt;</description>
    </item>
    <item>
      <title>virtualBox开机挂载windows分区，并把光盘镜源设为源</title>
      <link>https://ykyi.net/?p=981/</link>
      <pubDate>Wed, 21 Aug 2013 08:33:59 +0000</pubDate>
      <guid>https://ykyi.net/?p=981/</guid>
      <description>&lt;p&gt;virtualBox开机挂载windows分区，并把光盘镜源设为源。&lt;/p&gt;
&lt;p&gt;设置fstab文件。把windows的d,e,f盘分别开机挂载到了/misc/d &lt;span style=&#34;font-size: 13px;&#34;&gt;/misc/e /misc/f&lt;/span&gt; 。/misc是自建的目录，是miscellany的缩写。&lt;/p&gt;
&lt;p&gt;# cat /etc/fstab &lt;/p&gt;
&lt;p&gt;# /etc/fstab: static file system information.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;p&gt;# Use &amp;lsquo;blkid&amp;rsquo; to print the universally unique identifier for a&lt;br&gt;
# device; this may be used with UUID= as a more robust way to name devices&lt;br&gt;
# that works even if disks are added and removed. See fstab(5).&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;p&gt;# &lt;file system&gt; &lt;mount point&gt;   &lt;type&gt;  &lt;options&gt;       &lt;dump&gt;  &lt;pass&gt;&lt;br&gt;
# / was on /dev/sda1 during installation&lt;br&gt;
UUID=590c2b64-87b7-4f92-b32f-7133139be772 /               ext4    errors=remount-ro 0       1&lt;br&gt;
# swap was on /dev/sda5 during installation&lt;br&gt;
UUID=1e4e1188-d057-4210-99e7-6f2d1529db80 none            swap    sw              0       0&lt;br&gt;
/dev/sr0        /media/cdrom0   udf,iso9660 user,noauto     0       0&lt;br&gt;
D_DRIVE         /misc/d         vboxsf      rw,auto         0       0             0&lt;br&gt;
E_DRIVE         /misc/e         vboxsf      rw,auto         0       0             0&lt;br&gt;
F_DRIVE         /misc/f         vboxsf      rw,auto         0       0             0&lt;br&gt;
/misc/d/debian_ios/debian-7.1.0-amd64-DVD-1.iso /misc/a_iso udf,iso9660 user,loop,auto 0 0&lt;br&gt;
/misc/d/debian_ios/debian-7.1.0-amd64-DVD-2.iso /misc/b_iso udf,iso9660 user,loop,auto 0 0&lt;br&gt;
/misc/d/debian_ios/debian-7.1.0-amd64-DVD-3.iso /misc/c_iso udf,iso9660 user,loop,auto 0 0&lt;/p&gt;</description>
    </item>
    <item>
      <title>我的毕业论文.Linux桌面环境下内存去重技术的 研究与实现</title>
      <link>https://ykyi.net/?p=979/</link>
      <pubDate>Tue, 20 Aug 2013 07:00:10 +0000</pubDate>
      <guid>https://ykyi.net/?p=979/</guid>
      <description>&lt;p&gt;把我的毕业论文放上来，直接从word复制，所以图片会丢失。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;http://www.ykyi.net/upload/Research_and_Implementation_of_Memory_Deduplication_in_the_Linux_Desktop_Environment.pdf&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;span style=&#34;color:#FF0000;&#34;&gt;在这里可以下载原稿 www.ykyi.net/upload/Research_and_Implementation_of_Memory_Deduplication_in_the_Linux_Desktop_Environment.pdf&lt;/span&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;中山大学硕士学位论文&lt;/p&gt;
&lt;p&gt;Linux桌面环境下内存去重技术的. based on KSM&lt;/p&gt;
&lt;p&gt;研究与实现&lt;/p&gt;
&lt;p&gt;Research and Implementation of Memory Deduplication in&lt;/p&gt;
&lt;p&gt;The Linux Desktop Environment&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;table&gt;
  &lt;tr&gt;
    &lt;td style=&#34;width:188px;&#34;&gt;
      &lt;p&gt;
        学位申请人：
      &lt;/p&gt;
    &lt;/td&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;td style=&amp;quot;width:160px;&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;
    周霄
  &amp;lt;/p&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td style=&#34;width:188px;&#34;&gt;
      &lt;p&gt;
        导师姓名及职称：
      &lt;/p&gt;
    &lt;/td&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;td style=&amp;quot;width:160px;&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;
    王常吉副教授
  &amp;lt;/p&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;div&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;p&gt;
    论文原创性声明
  &lt;/p&gt;
  &lt;p&gt;
    本人郑重声明：所呈交的学位论文，是本人在导师的指导下，独立进行研究工作所取得的成果。除文中已经注明引用的内容外，本论文不包含任何其他个人或集体已经发表或撰写过的作品成果。对本文的研究做出重要贡献的个人和集体，均已在文中以明确方式标明。本人完全意识到本声明的法律结果由本人承担。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    学位论文作者签名：
  &lt;/p&gt;
  &lt;p&gt;
    日期：&amp;nbsp;年&amp;nbsp;&amp;nbsp;月&amp;nbsp;&amp;nbsp;日
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    学位论文使用授权声明
  &lt;/p&gt;
  &lt;p&gt;
    本人完全了解中山大学有关保留、使用学位论文的规定，即：学校有权保留学位论文并向国家主管部门或其指定机构送交论文的电子版和纸质版；有权将学位论文用于非赢利目的的少量复制并允许论文进入学校图书馆、院系资料室被查阅；有权将学位论文的内容编入有关数据库进行检索；可以采用复印、缩印或其他方法保存学位论文；可以为存在馆际合作关系的兄弟高校用户提供文献传递服务和交换服务。
  &lt;/p&gt;
  &lt;p&gt;
    保密论文保密期满后，适用本声明。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    学位论文作者签名：&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;导师签名：
  &lt;/p&gt;
  &lt;p&gt;
    日期：&amp;nbsp;&amp;nbsp;年&amp;nbsp;&amp;nbsp;月&amp;nbsp;&amp;nbsp;日&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;日期：&amp;nbsp;&amp;nbsp;年&amp;nbsp;&amp;nbsp;月&amp;nbsp;&amp;nbsp;日
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;p&gt;
    论文题目：&amp;nbsp;Linux桌面环境下内存去重技术的研究与实现
  &lt;/p&gt;
  &lt;p&gt;
    专业：软件工程&amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    硕士生：周霄
  &lt;/p&gt;
  &lt;p&gt;
    指导教师：王常吉&amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    摘&amp;nbsp;&amp;nbsp;要
  &lt;/p&gt;
  &lt;p&gt;
    内存管理是操作系统中至关重要的部分。优秀的操作系统高效地管理有限的内存资源。Linux内核的内核同页合并（KSM）模块是在虚拟化兴起后为节省虚拟机使用的内存而发展的一种节约内存的技术。KSM通过合并相同内容页面的方式显著地降低了多个基于内核虚拟机（KVM）技术的虚拟机同时运行时系统使用的内存。实际上，KSM也能合并一般应用程序中的相同内容页面。但一般应用程序为了使用KSM技术合并内存，需要在源代码级别显式地调用相应的系统调用来告知KSM需要扫描的内存区域。对于一般用户来说，需要修改应用程序的源代码显然是一个太高的门槛。
  &lt;/p&gt;
  &lt;p&gt;
    本论文在认真研究了KSM模块的实现的基础上，增强了KSM的功能。新设计实现的KSM+使得用户可以不必修改应用程序的源代码就能利用KSM+合并相同内容的内存页面。另外原来的KSM算法依赖程序指定的内存区域有大量的重复内存页面，而实际上，一般应用程序并没有大量的重复内存。在重复内存非常少的情况下，对这些程序应用KSM技术非但不能降低内存使用，而且因为运行KSM本身所需内存而增加了内存开销。本论文针对这一点在KSM的算法上做了改进，减少了运行KSM+算法本身所消耗的内存。然后论文用Linux桌面下的常用应用程序验证了KSM+的实际效果，并构造了一个实验比较了KSM和KSM+。最后，为了了解应用程序的重复内存页面的特点，还编写了专门统计重复页面的内核模块，发现应用程序的重复页面的一些规律，为持续改进KSM+提供了依据。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    关键词：KSM，重复内存合并&amp;nbsp;，内存管理
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    Title:&amp;nbsp;Research&amp;nbsp;and&amp;nbsp;Implementation&amp;nbsp;of&amp;nbsp;Memory&amp;nbsp;Deduplication&amp;nbsp;in&amp;nbsp;The&amp;nbsp;Linux&amp;nbsp;Desktop&amp;nbsp;Environment
  &lt;/p&gt;
  &lt;p&gt;
    Major:&amp;nbsp;Software&amp;nbsp;Engineering
  &lt;/p&gt;
  &lt;p&gt;
    Name:&amp;nbsp;Zhou&amp;nbsp;Xiao
  &lt;/p&gt;
  &lt;p&gt;
    Supervisor:&amp;nbsp;Wang&amp;nbsp;Changji
  &lt;/p&gt;
  &lt;p&gt;
    Abstract
  &lt;/p&gt;
  &lt;p&gt;
    Memory&amp;nbsp;management&amp;nbsp;is&amp;nbsp;one&amp;nbsp;of&amp;nbsp;the&amp;nbsp;most&amp;nbsp;important&amp;nbsp;parts&amp;nbsp;of&amp;nbsp;the&amp;nbsp;operating&amp;nbsp;system.&amp;nbsp;KSM&amp;nbsp;(Kernel&amp;nbsp;Samepage&amp;nbsp;Merging)&amp;nbsp;in&amp;nbsp;Linux&amp;nbsp;kernel&amp;nbsp;is&amp;nbsp;a&amp;nbsp;kind&amp;nbsp;of&amp;nbsp;memory&amp;nbsp;saving&amp;nbsp;technology&amp;nbsp;developed&amp;nbsp;after&amp;nbsp;the&amp;nbsp;emerging&amp;nbsp;of&amp;nbsp;virtual&amp;nbsp;machine.&amp;nbsp;KSM&amp;nbsp;can&amp;nbsp;dramatically&amp;nbsp;decrease&amp;nbsp;the&amp;nbsp;memory&amp;nbsp;usage&amp;nbsp;of&amp;nbsp;the&amp;nbsp;hypervisor&amp;nbsp;running&amp;nbsp;several&amp;nbsp;virtual&amp;nbsp;machines.&amp;nbsp;Actually,&amp;nbsp;KSM&amp;nbsp;can&amp;nbsp;also&amp;nbsp;be&amp;nbsp;applied&amp;nbsp;to&amp;nbsp;normal&amp;nbsp;applications.&amp;nbsp;But&amp;nbsp;in&amp;nbsp;order&amp;nbsp;to&amp;nbsp;use&amp;nbsp;the&amp;nbsp;KSM,&amp;nbsp;application&amp;nbsp;must&amp;nbsp;explicitly&amp;nbsp;evoke&amp;nbsp;a&amp;nbsp;system&amp;nbsp;call&amp;nbsp;in&amp;nbsp;source&amp;nbsp;code&amp;nbsp;level&amp;nbsp;to&amp;nbsp;tell&amp;nbsp;KSM&amp;nbsp;the&amp;nbsp;memory&amp;nbsp;area&amp;nbsp;where&amp;nbsp;the&amp;nbsp;KSM&amp;nbsp;will&amp;nbsp;scan.&amp;nbsp;To&amp;nbsp;normal&amp;nbsp;users,&amp;nbsp;modifying&amp;nbsp;the&amp;nbsp;source&amp;nbsp;code&amp;nbsp;is&amp;nbsp;impossible&amp;nbsp;at&amp;nbsp;most&amp;nbsp;of&amp;nbsp;the&amp;nbsp;time.
  &lt;/p&gt;
  &lt;p&gt;
    Base&amp;nbsp;on&amp;nbsp;the&amp;nbsp;full&amp;nbsp;grasp&amp;nbsp;of&amp;nbsp;the&amp;nbsp;implementation&amp;nbsp;of&amp;nbsp;KSM,&amp;nbsp;a&amp;nbsp;new&amp;nbsp;implementation&amp;nbsp;named&amp;nbsp;KSM+&amp;nbsp;is&amp;nbsp;created,&amp;nbsp;which&amp;nbsp;allows&amp;nbsp;users&amp;nbsp;to&amp;nbsp;merge&amp;nbsp;same-content&amp;nbsp;pages&amp;nbsp;on&amp;nbsp;the&amp;nbsp;specified&amp;nbsp;applications&amp;nbsp;without&amp;nbsp;modifying&amp;nbsp;corresponding&amp;nbsp;source&amp;nbsp;code.&amp;nbsp;Moreover,&amp;nbsp;the&amp;nbsp;original&amp;nbsp;KSM&amp;nbsp;algorithm&amp;nbsp;relies&amp;nbsp;heavily&amp;nbsp;on&amp;nbsp;the&amp;nbsp;specified&amp;nbsp;area&amp;nbsp;is&amp;nbsp;rich&amp;nbsp;in&amp;nbsp;same-content&amp;nbsp;pages,&amp;nbsp;while&amp;nbsp;normal&amp;nbsp;applications&amp;nbsp;have&amp;nbsp;much&amp;nbsp;less&amp;nbsp;same-content&amp;nbsp;pages&amp;nbsp;compared&amp;nbsp;to&amp;nbsp;virtual&amp;nbsp;machines.&amp;nbsp;So,&amp;nbsp;when&amp;nbsp;KSM&amp;nbsp;is&amp;nbsp;applied&amp;nbsp;to&amp;nbsp;those&amp;nbsp;applications,&amp;nbsp;it&amp;nbsp;is&amp;nbsp;possible&amp;nbsp;that&amp;nbsp;memory&amp;nbsp;usage&amp;nbsp;will&amp;nbsp;rise&amp;nbsp;rather&amp;nbsp;than&amp;nbsp;decrease.&amp;nbsp;To&amp;nbsp;combat&amp;nbsp;with&amp;nbsp;this&amp;nbsp;situation,&amp;nbsp;KSM+&amp;nbsp;employs&amp;nbsp;a&amp;nbsp;new&amp;nbsp;algorithm&amp;nbsp;to&amp;nbsp;decrease&amp;nbsp;the&amp;nbsp;memory&amp;nbsp;usage&amp;nbsp;for&amp;nbsp;running&amp;nbsp;itself.&amp;nbsp;Several&amp;nbsp;experiments&amp;nbsp;prove&amp;nbsp;that&amp;nbsp;the&amp;nbsp;KSM+&amp;nbsp;can&amp;nbsp;be&amp;nbsp;easily&amp;nbsp;applied&amp;nbsp;to&amp;nbsp;specified&amp;nbsp;applications&amp;nbsp;and&amp;nbsp;memory&amp;nbsp;usage&amp;nbsp;can&amp;nbsp;be&amp;nbsp;reduced.&amp;nbsp;And&amp;nbsp;a&amp;nbsp;case&amp;nbsp;is&amp;nbsp;designed&amp;nbsp;to&amp;nbsp;compare&amp;nbsp;the&amp;nbsp;effect&amp;nbsp;between&amp;nbsp;KSM&amp;nbsp;and&amp;nbsp;KSM+,&amp;nbsp;which&amp;nbsp;shows&amp;nbsp;KSM+&amp;nbsp;behaves&amp;nbsp;better&amp;nbsp;in&amp;nbsp;deduplication&amp;nbsp;when&amp;nbsp;the&amp;nbsp;same-content&amp;nbsp;pages&amp;rsquo;&amp;nbsp;density&amp;nbsp;is&amp;nbsp;very&amp;nbsp;low.&amp;nbsp;At&amp;nbsp;last,&amp;nbsp;in&amp;nbsp;order&amp;nbsp;to&amp;nbsp;inspect&amp;nbsp;the&amp;nbsp;characteristics&amp;nbsp;of&amp;nbsp;same-content&amp;nbsp;pages&amp;nbsp;from&amp;nbsp;normal&amp;nbsp;desktop&amp;nbsp;applications,&amp;nbsp;an&amp;nbsp;ad-hoc&amp;nbsp;kernel&amp;nbsp;module&amp;nbsp;is&amp;nbsp;developed&amp;nbsp;to&amp;nbsp;do&amp;nbsp;the&amp;nbsp;statistics&amp;nbsp;which&amp;nbsp;supplies&amp;nbsp;significant&amp;nbsp;data&amp;nbsp;for&amp;nbsp;the&amp;nbsp;further&amp;nbsp;development&amp;nbsp;of&amp;nbsp;KSM+.
  &lt;/p&gt;
  &lt;p&gt;
    Key&amp;nbsp;Words：&amp;nbsp;KSM,&amp;nbsp;Deduplication,&amp;nbsp;Memory&amp;nbsp;Management
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>epoll学习报告</title>
      <link>https://ykyi.net/?p=976/</link>
      <pubDate>Wed, 07 Aug 2013 12:01:31 +0000</pubDate>
      <guid>https://ykyi.net/?p=976/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    &amp;nbsp;epoll学习报告
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;kamuszhou&amp;nbsp;周霄&amp;nbsp;Jul/26/2013
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    这几天通读了内核中对epoll&amp;nbsp;I/O模型的实现代码，结合网络上很多介绍epoll的文章，对epoll的实现原理已经很熟悉，下面谈谈我的几点体会。下文引用的内核代码来自3.9.6版本的内核，见URL：&lt;a href=&#34;http://lxr.oss.org.cn/source/fs/eventpoll.c&#34;&gt;http://lxr.oss.org.cn/source/fs/eventpoll.c&lt;/a&gt;。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    一.&amp;nbsp;epoll的边沿触发(ET)的效率高于电平(LT)触发的效率
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;首先简单介绍一个背景：epoll实现中，把已经有事件发生的文件用一个双链表链接一起，这个双链表是在struct&amp;nbsp;eventpoll结构中的rdllist域。用户空间调用epoll_wait()，陷入内核后就会立即检查这个双链表，如果链表中非空，就通过文件的poll()函数询问文件有无事件发生。如果有事件发生且是用户关心的，就会向用户空间报告，否则就睡眠。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;epoll的实现代码中实际上只有两行代码与触发方式有关，如下图所示。
  &lt;/p&gt;
  &lt;p&gt;
    &lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; height=&#34;265&#34; src=&#34;file:///C:\Users\KAMUSZ~1\AppData\Local\Temp\ksohtml\wps_clip_image-17809.png&#34; width=&#34;554&#34; /&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;上图所示的代码运行的上下文情况是：用户加入到epoll中的某个文件，只要支持poll()，(可以是socket，FIFO，裸设备，whatever)有关心的事件到达(或可读，或可写，或报错)，内核空间已经把发生的事件复制到了用户空间，但还没有从内核态返回用户空间。在返回用户空间之前代码检查用被epoll监视的这个文件是否是ET触发，如果不是(那就是LT),就把监视的文件重新放回就绪队列，下次epoll_wait()调用的时候会立即重新检查这个文件有否有事件到达。如果这文件的确有事件发生，则epoll_wait()报告给调用者。如果没有，而且其它被监视的文件也没有事件发生，则调用epoll_wait()的task就让出处理器，开始睡觉(TASK_INTERRUPTIBLE)。这段逻辑在static&amp;nbsp;int&amp;nbsp;ep_poll(struct&amp;nbsp;eventpoll&amp;nbsp;*ep,&amp;nbsp;struct&amp;nbsp;epoll_event&amp;nbsp;__user&amp;nbsp;*events,&amp;nbsp;int&amp;nbsp;maxevents,&amp;nbsp;long&amp;nbsp;timeout)中，第1494行。
  &lt;/p&gt;
  &lt;p&gt;
    如果监听的文件开启的是边沿触发(默认)，则不会执行上图中的list_add_tail()逻辑。这就是边沿触发只会向用户报告一次，直到下一个关心事件发生才向用户空间报告的原因。
  &lt;/p&gt;
  &lt;p&gt;
    那么为什么ET触发效率高于LT触发呢？看一个例子，假如客户端监视一个TCP的Socket，服务端这时发来1M数据，客户端的主机网卡驱动缓存足够大，一次性接收到了所有1M数据。下面看两段客户端的接收伪代码(没有写read调用返回时socket被关闭的情况；另socket描述符fd被设为非阻塞)。
  &lt;/p&gt;
  &lt;p&gt;
    &lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; height=&#34;164&#34; src=&#34;file:///C:\Users\KAMUSZ~1\AppData\Local\Temp\ksohtml\wps_clip_image-26818.png&#34; width=&#34;487&#34; /&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;上图的代码使用了LT触发，这段代码依赖epoll_wait()通知还有数据可供读取。所以共调用了1024次epoll_wait()，1024次read()，共2048次系统调用才读完1M数据。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; height=&#34;242&#34; src=&#34;file:///C:\Users\KAMUSZ~1\AppData\Local\Temp\ksohtml\wps_clip_image-31492.png&#34; width=&#34;496&#34; /&gt;
  &lt;/p&gt;
  &lt;p&gt;
    上图使用ET触发，epoll_wait()只报告一次，然后代码循环调用1024次read()读完数据，直到第1025次read()返回-1，出错码为EAGAIN(EAGAIN等于EWOULDBLOCK)，于是代码知道已经接收完数据。一共只使用了1026次系统调用就读完了数据。
  &lt;/p&gt;
  &lt;p&gt;
    总结：即使使用电平触发也不要依赖epoll_wait()通知调用者到达事件，需要循环调用IO函数直到被通知EAGAIN，这样就把epoll_wait()的调用次数降到最低，仅管有可能在下次epoll_wait()时会有可能浪费一次文件的poll()调用，但这个很小的开销可以忽略。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    二.&amp;nbsp;为什么epoll支持嵌套调用
  &lt;/p&gt;
  &lt;p&gt;
    读epoll的实现代码发现，一个epoll的文件描述符epfd可以嵌套的加入另一个epoll。这样有什么用呢？
  &lt;/p&gt;
  &lt;p&gt;
    epoll的实现中&amp;ldquo;平等的&amp;rdquo;对待每个被监视的文件，它们维护在一棵红黑树之中，假如有十万个文件被监视，那么查找某个文件时就要在这十万个文件中查找。即使红黑树的查找效率是log(n)，文件非常大时也是比较消耗时间的。
  &lt;/p&gt;
  &lt;p&gt;
    那么假如有这样一种情况，如果这十万个文件中只有1000个是活跃的，或者说这1000个文件优先级最高。那么则有一种优化方案是，创建两个epoll，第一个epoll（epfd0）监控100000&amp;nbsp;&amp;#8211;&amp;nbsp;1000&amp;nbsp;个文件，第二个epoll&amp;nbsp;(epfd1)&amp;nbsp;监控1000个高优先级文件以及epfd0。这样的好处是，大多数情况下epoll实现只在1001个元素的红黑树中查找，自然效率提高了。
  &lt;/p&gt;
  &lt;p&gt;
    总结：epoll的嵌套调用给开发者提供了一个在高并发环境下的优化方案。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    三.&amp;nbsp;epoll的效率一定比select/poll高吗。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;答案是不一定。
  &lt;/p&gt;
  &lt;p&gt;
    Select的缺点大致有：
  &lt;/p&gt;
  &lt;p&gt;
    1.&amp;nbsp;内核中写死了最多只能监视1024个文件.
  &lt;/p&gt;
  &lt;p&gt;
    2.&amp;nbsp;每次调用select都要把关心的文件描述符和关心的文件件从一个用户空间的长长的数组拷贝到内核空间.
  &lt;/p&gt;
  &lt;p&gt;
    3.&amp;nbsp;select若使得caller进程进入睡眠后，某个文件有事件到达此进程被唤醒，那么所有被监视的文件全部会被调用poll()询问&amp;ldquo;你有没有事件到达&amp;rdquo;，这是一个线性的时间复杂度。
  &lt;/p&gt;
  &lt;p&gt;
    epoll针对select的三个缺点的改进：
  &lt;/p&gt;
  &lt;p&gt;
    1.&amp;nbsp;监视的文件数由取决于系统中有多少低端内存(x86_64架构中的所有内存都是低端内存)。3.9.6版本的内核实现中，对于每个登录用户，最多使用系统中低端内存的4%用来创建监视用的数据结构。见第1951行代码。max_user_watches&amp;nbsp;=&amp;nbsp;(((si.totalram&amp;nbsp;&amp;#8211;&amp;nbsp;si.totalhigh)&amp;nbsp;/&amp;nbsp;25)&amp;nbsp;&lt;&lt;&amp;nbsp;PAGE_SHIFT)&amp;nbsp;/&amp;nbsp;EP_ITEM_COST;
  &lt;/p&gt;
  &lt;p&gt;
    2.&amp;nbsp;用户只需要把关心的文件对应的数据结构在调用epoll_wait()前用epoll_ctl()一次性传入内存，以后调用epoll_wait()时不需要像select一样拷贝大量数据。
  &lt;/p&gt;
  &lt;p&gt;
    3.&amp;nbsp;当调用epoll_wait()的caller进程睡眠时，突然有事件到达，caller进程被唤醒，epoll_wait()返回用户空间，内核并不遍历没有监视的文件，而只报告在一个即短时间内发生的事件。下面更详细的描述这个场景，以监视tcp&amp;nbsp;socket举例，大致是：某进程调用epoll_wait()，此时没有任何它关心的事件发生，于是caller进程进入睡眠。处理器调度了其它进程。数据到达时，当前进程被硬件中断，网卡驱动收到数据包，数据包在中断处理函数中被拷入内核，中断处理函数设置中断下半部(Half&amp;nbsp;Bottom)。下半部被处理器调度，调用epoll实现代码注册的回调函数ep_poll_callback()。ep_poll_callback()函数唤醒之前的caller进程，caller进程重新获得CPU，从epoll实现的ep_poll()函数中恢复执行，在3.9.6内核中的第1564行：&amp;nbsp;if&amp;nbsp;(!schedule_hrtimeout_range(to,&amp;nbsp;slack,&amp;nbsp;HRTIMER_MODE_ABS))。然后，内核代码开始收集已经就绪的文件和发生的事件，发回用户空间。只有从第一次回调函数ep_poll_callback()被驱动的代码调用（caller进程还在睡眠时执行的ep_poll_callback()算第一次）到epoll实现代码走到第586行关闭中断关闭中断的代码&amp;nbsp;spin_lock_irqsave(&amp;ep-&gt;lock,&amp;nbsp;flags);之间发生的事件才会被收集。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;对于第3点，这是epoll的优点，但在某种情况下却会是epoll的缺点。网上很多比较poll,&amp;nbsp;select,&amp;nbsp;epoll性能的文章，没来得及仔细看，我个人认为结论是可靠的。结论引入了一个概念active-to-total&amp;nbsp;ratio，设所有被监控的文件数是n，活跃的文件数是m，active-to-total比则是m/n，如果这个比非常高，比如大于0.7，则poll或select的性能要高过epoll，反之则epoll胜出。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;对比前文对select的第3个缺点和epoll的改进点3的叙述可以解释这个原因。因为select在返回用户空间前又轮循了所有关心的文件，而这些文件又大部分是有事件发生的，所以select所做的工作并没有浪费，但epoll只收集了一小段时间中发生的事件，于是select较之epoll减少了用户空间和内核空间的频繁切换，从而让select的性能反超epoll。
  &lt;/p&gt;
  &lt;p&gt;
    那么如何改进呢？明白了以上的原因，那么就可以对epoll做出改进，理论上对于active-to-total比较高的应用环境下，可以在epoll的实现中加入与select做法相同逻辑，即退出前询问所有的监控文件，反正active-to-total比很高。或者更好的方案，用一个链表链接活跃的文件，在epoll返回用户空间前遍历这个链表，争取每一个epoll_wait()调用返回尽可能多的事件。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    附：epoll的主要数据结构简介.
  &lt;/p&gt;
  &lt;p&gt;
    epoll接口的主要数据结构有struct&amp;nbsp;eventpoll，struct&amp;nbsp;epitem，struct&amp;nbsp;eppoll_entry。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;在讲述这三个数据结构前先提一下struct&amp;nbsp;file。Unix设计初期希望它的设计遵从&amp;ldquo;一切皆文件&amp;rdquo;的理念。在Linux内核中，每个抽象的文件对应一个内核struct&amp;nbsp;file结构体。Struct&amp;nbsp;file结构体中有一个void&amp;nbsp;*private_data域。不同的文件类型会在private_data域中存放特定的信息。Struct&amp;nbsp;file中另一个域f_op是函数指针的列表，它记录了对应该文件的操作。所有epoll文件的f_op都指向static&amp;nbsp;const&amp;nbsp;struct&amp;nbsp;&lt;a href=&#34;http://lxr.oss.org.cn/ident?i=file_operations&#34;&gt;file_operations&lt;/a&gt;&amp;nbsp;&lt;a href=&#34;http://lxr.oss.org.cn/ident?i=eventpoll_fops&#34;&gt;eventpoll_fops&lt;/a&gt;，因此可以代码判断一个文件是不是epoll如下：
  &lt;/p&gt;
  &lt;p&gt;
    static&amp;nbsp;inline&amp;nbsp;int&amp;nbsp;is_file_epoll(struct&amp;nbsp;file&amp;nbsp;*f)
  &lt;/p&gt;
  &lt;p&gt;
    {
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;f-&gt;f_op&amp;nbsp;==&amp;nbsp;&amp;eventpoll_fops;
  &lt;/p&gt;
  &lt;p&gt;
    }
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;每次成功调用epoll_create时就会创建一个struct&amp;nbsp;file的结构体，和一个struct&amp;nbsp;eventpoll。Struct&amp;nbsp;file中的private_data指向struct&amp;nbsp;eventpoll。eventpoll维护了这个epoll的重要信息。其中比较重要的几个字段有：一个循环列表struct&amp;nbsp;list_head&amp;nbsp;&amp;nbsp;rdllist链接了该epll中已经可以读写或者有出错的文件描述符。一个红黑树的根结点struct&amp;nbsp;rb_root&amp;nbsp;&amp;nbsp;rbr，eventpoll维护了一棵红黑树，树中的结点是struct&amp;nbsp;epitem。
  &lt;/p&gt;
  &lt;p&gt;
    每个被加入到epoll中被关注的文件描述符都对应一个struct&amp;nbsp;epitem结构体。所有加入到同一个epoll中对应的所有epitem都挂在红黑树上。该红黑树的根结构保存在struct&amp;nbsp;eventpoll中。epitem中记录了对应的文件的文件描述符和文件指针。
  &lt;/p&gt;
  &lt;p&gt;
    struct&amp;nbsp;eppoll_entry是用来挂接到设备文件中的结构体。设备驱动在得知自己可读或可写或有错误时通过这个结构体通知有事件发生。每个eppoll_entry都指向一个epitem，一个epitem可能对应多个eppoll_entry。eppoll_entry中的域wait_queue_t&amp;nbsp;&amp;nbsp;wait就是被用来挂接到设备文件中的等待队列。设备文件通过wait可以拿到eppoll_entry，再通过eppoll_entry拿到epitem，再拿到eventpoll。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>makefile使cpp文件依赖头文件</title>
      <link>https://ykyi.net/?p=974/</link>
      <pubDate>Wed, 07 Aug 2013 12:00:10 +0000</pubDate>
      <guid>https://ykyi.net/?p=974/</guid>
      <description>&lt;p&gt;读代码时发现目前工程中的makefile文件中有一个问题或bug，.即cpp文件没有和该.cpp文件include的头文件建立依赖性。这个危害是，当头文件被修改后，受影响的.cpp文件对应的.o文件不会被重新创建。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;而目前的代码中大量使用C++模板，模板的实现全部写在.h文件中.&lt;/p&gt;
&lt;p&gt;我做了个实验，修改了单件模板的实现文件 SingletonHolder.h。虽然这个修改影响了大量include了SingletonHolder.h的.cpp文件，但它们对应的.o全被没有被重新编译。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;解决方法是用g++编译器提供的 -MM 选项。这个选项会让g++在把.cpp依赖的头文件(除系统头文件)全部列出来。具体的使用方法可以查阅手册。思路是，把cpp文件和头文件的依赖性写入到.d文件，在主makefile文件中include所有的.d文件。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;以tcpd工程为列，修改后的makefile如下(亦见附件)，该makefile可以检查到.cpp依赖的头文件被修改，使得重新生成目标文件。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;include ./makefile.def&lt;/p&gt;
&lt;p&gt;SRCS = $(wildcard *.cpp)&lt;/p&gt;
&lt;p&gt;OBJS = $(patsubst %.cpp,%.o,$(SRCS))&lt;/p&gt;
&lt;p&gt;# 每个.cpp都对应一个.d文件，.d文件由g++ -MM生成，列出了.cpp依赖的头文件.&lt;/p&gt;
&lt;p&gt;DEPENDENCIES = $(subst .cpp,.d,$(SRCS))&lt;/p&gt;
&lt;p&gt;TARGET = tcpd&lt;/p&gt;
&lt;p&gt;OK = [\e[1m\e&lt;a href=&#34;file:///%5Ce%5B1m%5Ce%5b32m&#34;&gt;32m&lt;/a&gt; OK [\e&lt;a href=&#34;file:///%5Ce%5Bm&#34;&gt;m&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;FAILURE = [\e[1m\e&lt;a href=&#34;file:///%5Ce%5B1m%5Ce%5b31m&#34;&gt;31m&lt;/a&gt; FAILURE [\e&lt;a href=&#34;file:///%5Ce%5Bm&#34;&gt;m&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;all:$(TARGET)&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;# 使包含.d文件，.d文件指定了.o文件依赖哪些头文件。&lt;/p&gt;
&lt;p&gt;# 如果不是make clean 就include所有的.d文件。&lt;/p&gt;
&lt;p&gt;ifneq &amp;ldquo;$(MAKECMDGOALS)&amp;rdquo; &amp;ldquo;clean&amp;rdquo;&lt;/p&gt;
&lt;p&gt;  -include $(DEPENDENCIES)&lt;/p&gt;
&lt;p&gt;endif&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;# 此函数生成.d文件，参考g++的 -MM -MF -MT选项&lt;/p&gt;
&lt;p&gt;#$(call make-depend,source-file,object-file,depend-file)&lt;/p&gt;
&lt;p&gt;define make-depend&lt;/p&gt;
&lt;p&gt;  g++ -MM -MF $3 -MT $2 $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) $1&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux桌面环境下内存去重技术的研究与实现(第二章)</title>
      <link>https://ykyi.net/?p=971/</link>
      <pubDate>Tue, 04 Jun 2013 03:03:51 +0000</pubDate>
      <guid>https://ykyi.net/?p=971/</guid>
      <description>&lt;h1 id=&#34;linux桌面环境下内存去重技术的研究与实现&#34;&gt;Linux桌面环境下内存去重技术的研究与实现&lt;/h1&gt;
&lt;h1 id=&#34;在这里可以下载原稿wwwykyinetuploadresearch_and_implementation_of_memory_deduplication_in_the_linux_desktop_environmentpdf&#34;&gt;&lt;strong style=&#34;font-size: 13px;&#34;&gt;&lt;a href=&#34;http://www.ykyi.net/upload/Research_and_Implementation_of_Memory_Deduplication_in_the_Linux_Desktop_Environment.pdf&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;span style=&#34;color: rgb(255, 0, 0);&#34;&gt;在这里可以下载原稿 www.ykyi.net/upload/Research_and_Implementation_of_Memory_Deduplication_in_the_Linux_Desktop_Environment.pdf&lt;/span&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/h1&gt;
&lt;h1 id=&#34;第二章-相关理论与技术&#34;&gt;第二章 相关理论与技术&lt;/h1&gt;
&lt;h2 id=&#34;21-内存管理&#34;&gt;2.1 内存管理&lt;/h2&gt;
&lt;p&gt;内存管理是操作系统内核中极为重要的部分，它涉及物理地址、虚拟地址、分段、分页等诸多概念。&lt;/p&gt;
&lt;h3 id=&#34;211-内存地址&#34;&gt;2.1.1 内存地址&lt;/h3&gt;
&lt;p&gt;程序使用地址来访问内存单元。对于x86架构的中央处理器，使用逻辑地址，虚拟地址，物理地址三种不同的地址&lt;sup&gt;[15]&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;逻辑地址包括段和偏移地址两部分，它们共同用来指定机器指令或者操作数在内存中的位置。逻辑地址对应下文提到的分段式内存管理。&lt;/p&gt;
&lt;p&gt;虚拟地址也被称作线性地址，它表示一个寻址空间。在Linux操作系统中，使用一个无符号长整型存储虚拟地址。如果是针对32位x86处理器的内核，这是一个32位的无符号长整型，可以寻址至多2&lt;sup&gt;32&lt;/sup&gt;，即4GB空间。而Linux在x86_64处理器上，一个无符号长整型有64位，但实际上只使用了48位，即可寻址到2&lt;sup&gt;48&lt;/sup&gt; ，即256TB的内存空间。引入虚拟地址使得用户空间的进程都独自拥有一个地址空间，方便操作系统在硬件的协助下隔离进程访问内存的操作，从而实现更高的安全性和便捷性。在32位处理器架构下，4G虚拟地址空间划分成两部分，高端的1G空间被称之为内核空间，低端的3G空间称之为用户空间。内核的代码和数据存在内核空间，用户空间的进程通过系统调用陷入内核空间执行内核空间的代码。对于64位处理器，虚拟地址同样分为内核空间和用户空间，只是针对64位处理器的内核拥有大得多的寻址范围，对内核空间和用户空间的地址划分有多种实现。&lt;/p&gt;
&lt;p&gt;物理地址被中央处理器用来寻址内存芯片上的实际的物理单元。它对应了送往处理器的针脚上的高低电平信号。&lt;/p&gt;
&lt;p&gt;       Linux中的内存管理单元 (Memory Management Unit, MMU)在硬件电路的帮助下把逻辑地址译成线性地址；而另一个硬件电路则帮助把线性地址翻译成物理地址。&lt;/p&gt;
&lt;h3 id=&#34;212-段页式内存管理&#34;&gt;2.1.2 段页式内存管理&lt;/h3&gt;
&lt;p&gt;内存分段是由80×86处理器引入的概念，它鼓励程序员在设计程序时把程序使用的内存按照逻辑上的意义相关性分成若干个部分，比如有些段存放全局数据，有些段存放程序代码&lt;sup&gt;[16]&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;内存管理单元的分页单元协助把虚拟地址译为物理地址，为了提高翻译的效率，虚拟地址被按照固定长度切分成一个个小单元，它们则被称之为页面。页面可以看成是MMU管理内存的最小单位。&lt;/p&gt;
&lt;p&gt;      分段和分页都用来划分内存，在某种程度上，它们的功能有一定重合。实际上，Linux内核的内存管理机制倾向于使用分页技术。Linux进程运行在用户空间时使用的标志代码段的代码段选择子(segmentation selector)和数据段选择子是相等的；进程运行在内核空间时使用的代码段选择子和数据段选择子也是相等的。而且这四个段选择子的段基址都设置为0。这意味着在Linux操作系统中，无论寻址数据和还是寻址指令，无论在用户空间还是内核空间，逻辑地址的段基址部分为0，偏移地址部分刚好等于虚拟地址。&lt;/p&gt;
&lt;p&gt;在Linux所支持的大多数硬件平台上，默认的页面大小是4K。但Linux同时也支持大于4K的页面的内存管理。运行在用户空间的代码可以使用glibc库中的getpagesize()函数得到当前使用的页面大小。本论文只针对在x86_64架构上页面大小是4K的Linux内核。实际上从内核2.6.38开始，内核中开始支持透明巨页(Transparent Huge Page)&lt;sup&gt;[17]&lt;/sup&gt;，内核中有些页面的大小实际上是2M，但这不影响按照4K的页面大小展开讨论。&lt;/p&gt;
&lt;p&gt;Linux使用分级页表的方式把虚拟地址映射到页面。在32位处理器上使用二级页表，在x86_64架构的处理器上则使用四级页表。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;
  图2-1 四级页表
&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;       如图2-1所示，以针对x86_64架构处理器的Linux内核为例，64位虚拟地址的高16位不被使用，低48位被平均分为5段，offset段占12位，其它四个段各占9位。这个划分在源代码文件arch/x86/include/asm/pgtable_64_types.h中定义。cr3寄存器存储了页全局目录的物理地址。在把虚拟地址翻译到物理地址的过程中，MMU先从cr3寄存器中取出全局目录的物理地址，再加上GLOBALDIR段算出的偏移量，从而在页全局目录中得到页上级目录的物理地址。与此类似，从页上级目录中得到页中间目录的地址，然后得到页表的地址，再得到页面的地址，最后的OFFSET字段则定位到页面中的一个字节。至此，虚拟地址被翻译到了物理地址。&lt;/p&gt;
&lt;p&gt;页全局目录，页上级目录，页中间目录，以及页表中的每一项都由相同的数据结构表示。它记载了一些重要的信息，与本论文相关的信息有：该项指向的下一级表或者页面是否存在的标志，如果访问时不存在则产生缺页中断，由do_page_fault函数负责把页面调入内存&lt;sup&gt;[18]&lt;/sup&gt;；下一级表或页面的物理地址；下一级表或页面是否可读可写的标志，利用该标志位可以写保护一个页面。&lt;/p&gt;
&lt;p&gt;Linux内核用一个struct page结构体描述一个页面的信息。这个结构体定义在include/linux/mm_types.h文件中&lt;sup&gt;[19]&lt;/sup&gt;。图2-2列出这个结构体中与本论文直接相关的字段。&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;
  图2-2 struct page的部分字段
&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;其中的flags字段存储了页面的状态信息，例如：表示页面刚被写了数据的脏位；该页面是否被锁定在内存中不充许置换到交换分区的标志。_count字段和_mapcount字段都是引用计数，它们用来共同维护page页面的生命期。_mapcount表示一个页面拥有多少页表项指向它，_count被称为page的使用计数，所有的_mapcount计数只相当于_count计数中的一次计数。如果内核代码中某执行序列在访问某个页面时需要确保该页面存在，则在访问前给_count计数加一，访问结束后_count计数减一。当_count计数减到负数时表示没有任何内核需要使用该页面，则表示该页面没被使用。内核代码不应该直接访问_count计数，而应该使用page_count函数。该函数用一个struct page的指针做为参数，当该页空闲时函数返回0，否则返回一个正数表示参数指向的页面正被使用。当页面被页高速缓冲使用时，mapping域指向一个address_space对象，该对象与Linux文件系统中的文件是一对一映射的关系，描述了一个文件分配到的物理页面及相关数据结构。如果页面并不被页高速缓冲使用时，mapping则有其它的意义，比如mapping字段的最低位记载这是否是一个匿名页面。virtual字段是映射到该页面的内核空间的虚拟地址，如果该页面是属于高端内存区域则virtual字段为NULL。对于x86_64架构上的Linux内核，已经没有高端内存，因此该字段不会为NULL。&lt;/p&gt;
&lt;h3 id=&#34;213-内核中的巨页&#34;&gt;2.1.3 内核中的巨页&lt;/h3&gt;
&lt;p&gt;现代处理器的内存管理单元几乎都能处理除4KB大小外的多种页面尺寸。然而，Linux内核在几乎所以平台上的实现都选用最小的页面大小，即4KB，比4KB更大的页面，都被称之为巨页(huge page)。在某些工作环境下，巨页可以给操作系统带来性能上的提高。巨页能提高操作系统的性能主要是因为两点。第一，使用巨页可以减少发生页面出错处理的频率，因为在每次页面出错处理时内核调入比使用小页面更多的内存。第二，使用巨页减少翻译虚拟地址的时间。在x86_64加构的处理器上，从虚拟地址翻译到物理地理需要依次访问四级页表，非常耗时。而使用巨页可以减少页表的级数。实际上更大的性能提高源自使用巨页后提高了旁路转换缓冲区(Translation Lookaside Buffer，TLB)的命中效率&lt;sup&gt;[20]&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;在内核2.6.38版本之前，唯一使用巨页的方式是通过非常复杂的hugetlbfs文件系统。应用程序开发者和系统管理员都需要注意一些特别事项才能够开启巨页功能。因此只有极少数真正需要巨页带来性能提高的用户，如专用数据库系统，才使用巨页。&lt;/p&gt;
&lt;p&gt;情况从内核版本2.6.38以后发生了变化，一个被称之为透明巨页的功能被合并进了内核主干代码。之前内核在VMA（Virtual Memory Area，虚拟内存区域）中的所有页面大小都是一样大的，而加入透明巨页后，VMA中的页面的大小可能不只一种。透明巨页的实现代码改写了页面出错处理函数，当一个出错发生时，内核尽力分配一个巨页，如果成功的话，其它相应的在巨页地址范围内的小页面就会被释放，巨页被插入到VMA中。如果不能分配到一个巨页，则仍然按照以前的方式分配一个小页面。当巨页需要被置换到交换分区时，透明巨页机制简单地把巨页切割成小页面，其它逻辑和处理小页面时一样。实际上不仅在置换到交换分区时需要切割巨页，很多其它的操作，如mprotect()和mlock()页面时也需要。本论文将详述的KSM在合并页面时同样需要把巨页切割成小页面。&lt;/p&gt;
&lt;p&gt;透明巨页这种轻便地利用巨页的方式使得很多内核代码并没有感知到巨页的存在，对于应用程序则更没有感知到巨页，因此被称之为透明巨页。&lt;/p&gt;
&lt;h3 id=&#34;214-内存描述符&#34;&gt;2.1.4 内存描述符&lt;/h3&gt;
&lt;p&gt;Linux内核使用一个叫内存描述符(Memory Descriptor)的结构体描述每一个进程的地址空间&lt;sup&gt;[21]&lt;/sup&gt;。这个结构体包括了所有和进程地址空间相关的信息。内存描述符和struct page一样在文件include/linux/mm_types.h中定义。图2-3列出这个结构体中与本论文直接相关的字段。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;
  图2-3 struct mm_struct的部分字段
&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p&gt;其中，mmap字段是用来实现一个链表。这个链表链接了属于这个内存描述符的所有vm_area_struct结构体。vm_area_struct结构体描述了一个内存区域。由于属于一个内存描述符的内存区域可能非常多，为了加快内存区域的查找以及添加删除等操作的速度，内核用mm_rb表示一棵链接了所有内存区域的红黑树。红黑树是一种二叉树，它被广泛地应用在Linux内核代码中。mmap和mm_rb是用两种不同的数据结构表示同一批数据。mm_users和mm_count是内存描述符的引用计数，它的实现原理和struct page的引用计数的原理一样。每一个进程如果拥有一个内存描述符，则会增加mm_users的计数，所有mm_users的计数只相当于mm_count的一个计数。比如n个Linux线程共享同一个内存描述符，那么对应的内存描述符的mm_users计数则为n，而mm_count则可能只是1。如果有内核执行序列想要访问一个内存描述符，则该执行序列先增加mm_count的计数，使用结束后减少mm_count的计数。一但mm_count减为0，表示该内存描述符没有任何引用，则它会被内核销毁。mmap_sem是一个读写锁，凡是需要操作内存描述符中的内存区域时，则需要先得到相应的读锁或者写锁，使用结束后释放该锁。mm_list字段是一个循环双链表。它链接了系统中所有的内存描述符。flags字段定义了内存描述符的标志，这些标志标记了内存描述符的一些状态和属性，内核代码需要使用原子操作访问该字段。&lt;/p&gt;
&lt;h3 id=&#34;215-虚拟内存区域&#34;&gt;2.1.5 虚拟内存区域&lt;/h3&gt;
&lt;p&gt;同样被定义在inlude/linux/mm_types.h中的结构体vm_area_struct用来描述一个内存区域。在Linux内核中，内存区域经常被称之为虚拟内存区域(Virtual Memory Areas,VMA)。VMA描述的内存区域是一个地址空间中的地址连续的部分。而且该部分拥有一些特定的属性，比如访问权限和相关联的操作等。不同的VMA可以用来描述不同的内存区域。比如，映射到内存的文件，用户空间的栈，特别是本论文重点关注的匿名内存区域(Anonymous VMA)。下面讨论本论文关心的vm_area_struct的一些重要字段，这些字段如图2-4所示。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux桌面环境下内存去重技术的研究与实现(第一章)</title>
      <link>https://ykyi.net/?p=967/</link>
      <pubDate>Sat, 01 Jun 2013 09:00:14 +0000</pubDate>
      <guid>https://ykyi.net/?p=967/</guid>
      <description>&lt;h1 id=&#34;linux桌面环境下内存去重技术的研究与实现&#34;&gt;Linux桌面环境下内存去重技术的研究与实现&lt;/h1&gt;
&lt;h1 id=&#34;在这里可以下载原稿httpsasgoodasgoldresearch_and_implementation_of_memory_deduplication_in_the_linux_desktop_environmentpdf&#34;&gt;&lt;strong style=&#34;font-size: 13px;&#34;&gt;&lt;a href=&#34;https://as.goodas.gold/Research_and_Implementation_of_Memory_Deduplication_in_the_Linux_Desktop_Environment.pdf&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;span style=&#34;color: rgb(255, 0, 0);&#34;&gt;在这里可以下载原稿 https://as.goodas.gold/Research_and_Implementation_of_Memory_Deduplication_in_the_Linux_Desktop_Environment.pdf&lt;/span&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/h1&gt;
&lt;h1 id=&#34;第一章-绪论&#34;&gt;第一章 绪论&lt;/h1&gt;
&lt;h2 id=&#34;11-课题背景&#34;&gt;1.1 课题背景&lt;/h2&gt;
&lt;p&gt;内存是操作系统中最为重要的资源之一。为了最有效地利用好有限的内存资源，现代操作系统使用了很多技术以节省内存的使用。在Linux程序的内存布局中，代码段具有只读属性，永远是共享的。具体地说，即使一个程序被实例化了多个进程，但是在物理内存中对于该程序的代码只有一份拷贝，同一个程序的不同进程之间共享这份拷贝。而且，所有共享库（Windows下被称之为动态链接库）的代码段在物理内存中也只有一份拷贝&lt;sup&gt;[1]&lt;/sup&gt;，所有加载了该共享库的进程虽然把共享库加载到了不同的虚拟地址中，但实际上都映射到相同的物理地址上以实现对共享库代码区的共享。除了共享只读的代码区外，可写的页面也可能在进程之间被共享，Linux在创建进程时的fork操作使用写时拷贝技术在父子进程之间共享内存。当父进程调用fork()函数后，所有的可写页面转成写时拷贝页面。只要父子进程都不写入某页面，则该页面一直被共享。&lt;/p&gt;
&lt;p&gt;近年来，Linux操作系统中出现了一种新的节省内存的技术，它的出现源于云计算的发展。云计算能够通过互联网按需分发计算机的软硬件资源，被称之为IT产业的又一次革命&lt;sup&gt;[2]&lt;/sup&gt;。虚拟机技术是云计算的基础，Xen和KVM(Kernel Virtual Machine，内核虚拟机)是开源社区最流行的两种虚拟化技术&lt;sup&gt;[3]&lt;/sup&gt;。通过运用虚拟化技术，越来越多的Linux主机上同时运行着多个虚拟机，而虚拟机使用了相同的操作系统，操作系统中运行着相同的大型程序，如数据库服务器，邮件服务器，Web服务器等。在运行多个虚拟机的环境下，人们发现虚拟机之间存在着大量的相同内存页面，但Linux主机没有办法共享这些内存页面。为了解决虚拟机之间大量重复内存的问题，Linux社区诞生了KSM(Kernel Samepage Merging，内核相同页面合并)技术。KSM技术通过扫描内存区域，找到相同的内存页面，并把它们合并。该技术使得运行虚拟机的主机使用的内存明显下降，从而让同样的Linux主机在使用KSM技术后能运行更多的虚拟机。&lt;/p&gt;
&lt;p&gt;KSM技术虽然是为基于KVM技术的虚拟机设计，但也能运用到普通的桌面应用程序。随着软硬件技术的不断进步，Linux桌面应用程序占用的内存也越来越多。普通的Linux桌面应用程序中存在多少重复页面，重复页面的分布有些什么特点，把KSM技术运用在桌面应用程序上存在什么问题，这些是本论文将要探讨的内容。针对桌面应用程序的重复内存，本文在KSM的基础上开发了KSM+，能方便有效地合并桌面应用程序的重复内存。&lt;/p&gt;
&lt;h2 id=&#34;12-国内外研究现状&#34;&gt;1.2 国内外研究现状&lt;/h2&gt;
&lt;p&gt;对于传统的节约内存技术，如共享只读代码区，fork的写时拷贝技术。这些技术非常成熟，现代操作系统中已经普通采用。&lt;/p&gt;
&lt;p&gt;另外，文献&lt;sup&gt;[4]&lt;/sup&gt;研究了一种比较特殊的节省内存技术。它针对的是科学计算中的特殊程序，通过用注释驱动的工具把源代码转译到更高效的代码，于是编译出节省内存的程序。&lt;/p&gt;
&lt;p&gt;近年来研究较多的是基于合并相同内存页面的内存去重技术：通过查找系统中的相同内存页面，把这些页面合并从而节省系统内存。但国内外的研究基本集中在运行虚拟机的场景中。如VMware公司较早进行了虚拟机内存去重技术的研究工作，文献&lt;sup&gt;[5]&lt;/sup&gt;研究了VMware公司的Hypervisor(虚拟机管理器)使用的基于合并相同内容内存页面的去重技术，以减少虚拟机之间的内存冗余。文献&lt;sup&gt;[6]&lt;/sup&gt;详细论述了此类技术对于基于Xen的虚拟机的实现。Linux社区的类似技术称之为KSM。文献&lt;sup&gt;[7]&lt;/sup&gt;以实证研究的方式通过大量实验研究了KSM用于合并虚拟机之间冗余内存的性能。文献&lt;sup&gt;[8]&lt;/sup&gt;研究的是在数据中心中如何提高在虚拟机之间合并相同内存的效率。它实现了通过把虚拟机在各物理机中动态迁移到最适合的位置从而提高合并效率。文献&lt;sup&gt;[9]&lt;/sup&gt;使用KSM技术解决了主机和虚拟机都需要维护自己的缓存的问题，提高了缓存的效率。KSM技术并不是总能高效地去除虚拟机之间的冗余内存，也存在一些问题。内存地址的ASLR(Address Space Layout Randomization，空间布局随机化技术)是为了提高程序安全性的一种技术。该技术提高了程序的安全性，却影响了页面对齐，从而影响了KSM的合并效率&lt;sup&gt;[10]&lt;/sup&gt;。另外，KSM的运用也暴露了安全问题。运行在某台虚拟机上的程序可以通过构造特定的页面尝试让主机的KSM合并它，再计算写该页面所用的时间。因为写被KSM合并的页面的时候会发生写时拷贝，所以这个时间会比正常情况下延迟。通过利用这个时间差，运行在一台虚拟机上的程序可能会发现其它虚拟机上运行的程序&lt;sup&gt;[11]&lt;/sup&gt;，甚至让虚拟机之间秘密通信&lt;sup&gt;[12]&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;KSM技术应用在非虚拟机的场景下的研究则比较少。欧洲核子研究组织(CERN)的核子实验模拟程序产生海量的数据，并且并行工作的科学程序同时载入这些数据，使得内存中有大量的相同内容页面。CERN通过使用钩子技术修改C运行库的malloc()从而运行KSM，解决了内存中的大量重复页面的问题，节省了8%-48%的内存&lt;sup&gt;[13]&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;本论文将在一般桌面应用环境下研究并增强新的内存节省技术KSM，使之更适合运用在桌面应用环境下，更有效地减少应用程序的内存使用量。&lt;/p&gt;
&lt;h2 id=&#34;13-研究意义&#34;&gt;1.3 研究意义&lt;/h2&gt;
&lt;p&gt;内存资源总是操作系统中稀缺的资源，研究节省内存的技术具有普遍的意义。另外，随着基于Linux内核的操作系统如Android在消费电子终端上的迅速普及&lt;sup&gt;[14]&lt;/sup&gt;，以及可预见到基于Linux的Chrome OS在PC桌面市场也将占有一定市场，而目前的应用程序普遍占用越来越多的内存，研究Linux平台下新的节省内存的技术KSM，对于开发Android平台等基于Linux内核的平台下的商用优化管理软件具有重要的技术指导作用。&lt;/p&gt;
&lt;h2 id=&#34;14-论文的主要工作&#34;&gt;1.4 论文的主要工作&lt;/h2&gt;
&lt;p&gt;      本论文重点研究了Linux内核的KSM模块的设计与实现，并在原来的基础上做了针对桌面应用环境的增强与改进，同时认真研究了Linux内核代码的组织方式，配置与编译方式，内核开发及调试的技术，以及Linux的内存管理单元的实现。增强后的KSM命名为KSM+,它比原来的KSM更方便地自动采集到应用程序的相同内容页面并合并这些页面，以达到节省应用程序消耗的内存的目的。论文用多个实验展示了KSM+的功能，并与修改前的KSM做了比较。此外，本论文还编写了内核模块用于统计Linux桌面应用程序的重复内存页面的特点，同时可以用来应证KSM+运行的效果。&lt;/p&gt;
&lt;h2 id=&#34;15-论文的整体结构布局&#34;&gt;1.5 论文的整体结构布局&lt;/h2&gt;
&lt;p&gt;    本论文的第二章介绍了x86体系的段页式内存管理方式，以及Linux的内存管理的实现，还介绍了编写Linux内核代码的一些基本理论。&lt;/p&gt;
&lt;p&gt;第三章介绍了如何使用KSM以及KSM的设计和实现原理。&lt;/p&gt;
&lt;p&gt;第四章讲述KSM+的设计与实现。KSM+是在KSM的基础上的增强与改进。&lt;/p&gt;
&lt;p&gt;第五章用多个实验展示了KSM+合并程序的重复内存页面的效果，并设计了一个实验比较了KSM和KSM+的差别。最后编写了用于统计应用程序重复内存页面的内核模块，并用统计数据应证了KSM+的实验结果。这些统计数据反映了Linux桌面应用程序中重复内存页面的一些基本特点，对进一步改进KSM+的算法提供了依据。&lt;/p&gt;
&lt;h2 id=&#34;16-本章小结&#34;&gt;1.6 本章小结&lt;/h2&gt;
&lt;p&gt;      本章首先介绍了Linux操作系统中传统的节省内存技术，然后引入了因为虚拟化兴起而发展的新的内存节省技术，它通过合并内容相同的内存页面从而减少系统的内存使用，也被称之为内存去重技术，接着叙述了国内外在该技术方面的相关研究。目前对该技术的研究多针对虚拟机环境，而本论文则是在Linux桌面环境中研究内存去重技术。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux桌面环境下内存去重技术的研究与实现(中英文摘要)</title>
      <link>https://ykyi.net/?p=957/</link>
      <pubDate>Mon, 27 May 2013 14:28:12 +0000</pubDate>
      <guid>https://ykyi.net/?p=957/</guid>
      <description>&lt;h1 id=&#34;linux桌面环境下内存去重技术的研究与实现&#34;&gt;Linux桌面环境下内存去重技术的研究与实现&lt;/h1&gt;
&lt;h1 id=&#34;在这里可以下载原稿wwwykyinetuploadresearch_and_implementation_of_memory_deduplication_in_the_linux_desktop_environmentpdf&#34;&gt;&lt;strong style=&#34;font-size: 13px;&#34;&gt;&lt;a href=&#34;http://www.ykyi.net/upload/Research_and_Implementation_of_Memory_Deduplication_in_the_Linux_Desktop_Environment.pdf&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;span style=&#34;color: rgb(255, 0, 0);&#34;&gt;在这里可以下载原稿 www.ykyi.net/upload/Research_and_Implementation_of_Memory_Deduplication_in_the_Linux_Desktop_Environment.pdf&lt;/span&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;论文题目： Linux桌面环境下内存去重技术的研究与实现&lt;/p&gt;
&lt;p&gt;专业：软件工程&lt;/p&gt;
&lt;p&gt;硕士生：周霄&lt;/p&gt;
&lt;p&gt;指导教师：王常吉&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;
  &lt;strong&gt;摘&amp;nbsp; 要&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;内存管理是操作系统中至关重要的部分。优秀的操作系统高效地管理有限的内存资源。Linux内核的内核同页合并（KSM）模块是在虚拟化兴起后为节省虚拟机使用的内存而发展的一种节约内存的技术。KSM通过合并相同内容页面的方式显著地降低了多个基于内核虚拟机（KVM）技术的虚拟机同时运行时系统使用的内存。实际上，KSM也能合并一般应用程序中的相同内容页面。但一般应用程序为了使用KSM技术合并内存，需要在源代码级别显式地调用相应的系统调用来告知KSM需要扫描的内存区域。对于一般用户来说，需要修改应用程序的源代码显然是一个太高的门槛。&lt;/p&gt;
&lt;p&gt;本论文在认真研究了KSM模块的实现的基础上，增强了KSM的功能。新设计实现的KSM+使得用户可以不必修改应用程序的源代码就能利用KSM+合并相同内容的内存页面。另外原来的KSM算法依赖程序指定的内存区域有大量的重复内存页面，而实际上，一般应用程序并没有大量的重复内存。在重复内存非常少的情况下，对这些程序应用KSM技术非但不能降低内存使用，而且因为运行KSM本身所需内存而增加了内存开销。本论文针对这一点在KSM的算法上做了改进，减少了运行KSM+算法本身所消耗的内存。然后论文用Linux桌面下的常用应用程序验证了KSM+的实际效果，并构造了一个实验比较了KSM和KSM+。最后，为了了解应用程序的重复内存页面的特点，还编写了专门统计重复页面的内核模块，发现应用程序的重复页面的一些规律，为持续改进KSM+提供了依据。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;**关键词：**KSM，重复内存合并 ，内存管理&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Title: Research and Implementation of Memory Deduplication in The Linux Desktop Environment&lt;/p&gt;
&lt;p&gt;Major: Software Engineering&lt;/p&gt;
&lt;p&gt;Name: Zhou Xiao&lt;/p&gt;
&lt;p&gt;Supervisor: Wang Changji&lt;/p&gt;
&lt;p align=&#34;center&#34;&gt;
  &lt;strong&gt;Abstract&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;Memory management is one of the most important parts of the operating system. KSM (Kernel Samepage Merging) in Linux kernel is a kind of memory saving technology developed after the emerging of virtual machine. KSM can dramatically decrease the memory usage of the hypervisor running several virtual machines. Actually, KSM can also be applied to normal applications. But in order to use the KSM, application must explicitly evoke a system call in source code level to tell KSM the memory area where the KSM will scan. To normal users, modifying the source code is impossible at most of the time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SAN和NAS有什么区别和相同</title>
      <link>https://ykyi.net/?p=953/</link>
      <pubDate>Mon, 29 Apr 2013 07:55:45 +0000</pubDate>
      <guid>https://ykyi.net/?p=953/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;line-height: 1.6em;&#34;&gt;SAN(Storage Area Network存储区域网络)和NAS(Network Attached Storage不知中文点译)都是提供网络存储的解决方案。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;其中NAS是*一个*存储设备，以文件为操作单位。&lt;/p&gt;
&lt;p&gt;SAN用一个局域网把很多设备连接起来，以磁盘的块(block)为操作单位。&lt;/p&gt;</description>
    </item>
    <item>
      <title>我的BUG大全。</title>
      <link>https://ykyi.net/?p=947/</link>
      <pubDate>Sat, 23 Mar 2013 03:32:22 +0000</pubDate>
      <guid>https://ykyi.net/?p=947/</guid>
      <description>&lt;p&gt;在这里记下我的程序BUG&lt;/p&gt;
&lt;h1 id=&#34;buff溢出后把栈破坏了这个线程也没崩溃一直死循环在一小段不可知的代码里&#34;&gt;buff溢出后，把栈破坏了，这个线程也没崩溃，一直死循环在一小段不可知的代码里。&lt;/h1&gt;
&lt;p&gt;#调用getaddrinfo很多次以后，getaddrinfo报错：No address associated with NAME。非常地奇怪呀&lt;del&gt;后来把同样的程序部署到比较旧的linux上，报错: Too many open files。才明白，原来fd被用光了。回头再检查相关代码，果然如此~补上close(fd)后，getaddrinfo的问题也解决了。启发是：1. 有些报错信息其实离真正的错误原因很远。2. 一个系统调用一开始正常，跑了很多次后失败，应该怀疑是不是有资源泄露。&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;#把uint_t类型赋值给std::string时，会崩溃在std::string里面。&lt;/p&gt;
&lt;p&gt;#当一个预期统一的规则出现特例的时候容易出现BUG. 关联订单，关联片区，入货地址都指受YYYY-MM-DD HH:MM:SS的时间戳，但同机分析接受的时间戳却是YYYYMMDD某一天的时间戳。有一个组合需求是同时导出上述4个小需求时，由于传入的时间戳参数不一致导致了BUG.&lt;/p&gt;
&lt;h1 id=&#34;vectorpush_back可能会重新分配vector的内存导致指向之前元素的引用和指针失效一个stdfunction持有一个stdref指向vector中的一个元素当这个funcction被调用的时候vector中的这个元素已经失效了&#34;&gt;vector::push_back可能会重新分配vector的内存，导致指向之前元素的引用和指针失效.一个std::function持有一个std::ref指向vector中的一个元素，当这个funcction被调用的时候，vector中的这个元素已经失效了。&lt;/h1&gt;
&lt;p&gt;&lt;span style=&#34;font-size: 13.3333330154419px; line-height: 13.8666658401489px;&#34;&gt;# 用boost::optional记录一个信息。这个信息没及时在clear函数里做清理。于是，观察到的情况时，这个信息总是被打印。但一开始，我们却怀疑是另外的函数不稳定而重新生成了该信息。&lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&#34;在写一个匹配函数时待匹配操作数是一个字符串我没有考虑字符串是空串的情况&#34;&gt;在写一个匹配函数时，待匹配操作数是一个字符串，我没有考虑字符串是空串的情况。&lt;/h1&gt;
&lt;h1 id=&#34;在比较旧的gcc-412上把shared_ptr赋给weak_ptr时崩溃溃在atomic_exchange_and_add一开始怀疑是旧版gcc对boost的智能指针支持的不够好后来发现是因为weak_ptr此时已经失效了原因是用handler的参数持用shared_ptr的引用做生命期管理时传错了参数使得这个对象已经被销毁了&#34;&gt;在比较旧的gcc 4.1.2上把shared_ptr赋给 weak_ptr时，崩溃。溃在atomic_exchange_and_add。一开始怀疑是旧版gcc对boost的智能指针支持的不够好，后来发现是因为weak_ptr此时已经失效了。原因是用handler的参数持用shared_ptr的引用做生命期管理时，传错了参数，使得这个对象已经被销毁了。&lt;/h1&gt;
&lt;h1 id=&#34;现象一个依赖某布尔变量的逻辑大多数时候正常少部分时间异常期望这个布尔变量是false有时候陌名其妙变成了true&#34;&gt;现象：一个依赖某布尔变量的逻辑大多数时候正常，少部分时间异常。期望这个布尔变量是false，有时候陌名其妙变成了true。&lt;/h1&gt;
&lt;p&gt;原因是此布尔变量未被初始化，大多数时候它的值是false，但有时却不是。&lt;/p&gt;
&lt;p&gt;#. 现象rmap_item泄露.&lt;/p&gt;
&lt;p&gt;Fix it: 单链表插入新结点时指针操作出错。应该是new-&amp;gt;rmap_list = _item，被我写成 new-&amp;gt;rmap_list = (_item)-&amp;gt;rmap_list.&lt;/p&gt;
&lt;p&gt;#. 我意图注释掉某行代码，却鬼使神差注释错了一行代码。&lt;/p&gt;
&lt;p&gt;#. 变量名 pkt 和ptr 很像，在用memcpy函数时用错了变量导致bug. 一块内存被莫名其妙的修改了，很有可能是因为像刚才这样写这块函数的参数填错了。&lt;/p&gt;
&lt;p&gt;#. _sessions.erase(ite++);删除了_sessions维护的一个对象.对象的析构被调用，会有一连串对象的析构因此而被调用。这些对象中的指针很可能就失效了。但是，在代码的其它地方还能拿到这个指针。野指针啊！！！今天这个例子中是session维护的ip_pkt对象都被析构了，ip_pkt中的指针也都失效了。于是，一使用野指针，崩溃了。&lt;/p&gt;
&lt;p&gt;#. 删除数据时，总是要注意其它代码中指向这些被删除数据的引用或指针。&lt;/p&gt;
&lt;p&gt;#. 解引用container.end()返回的迭代器会崩溃。&lt;/p&gt;
&lt;p&gt;#. 这是个腾讯视频广告投放组的bug. 一个线程负责开，关FD。另一个线程读写FD。两个线程的竞争条件造成了BUG.&lt;/p&gt;
&lt;p&gt;#. 写代码时偷懒复制代码，然后忘记做相应更改，视觉上很难在第一时间察觉，却在后期花费了几倍时间调试程序。&lt;/p&gt;
&lt;p&gt;#. 写判断语句时，判断表达示如 container.empty()之前是否要取反，经常搞错。&lt;/p&gt;
&lt;p&gt;#. htonl 写成 htons&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: 13px;&#34;&gt;#. std::distance 计算两个迭代器之间距离时死循环，是因为迭代器没有初始化。而我之前想，作初始化工作的函数已经调用了，实际上并没有被调用。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: 13px;&#34;&gt;#. 没注意函数的返回值. 有时函数返回0时表示成功，即true的含义。所以看到一些和预期刚好相反的现象时，应该考虑是不是出现了这样的错误。&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>泪流满面，WARNING: modpost: Found 1 section mismatch(es).</title>
      <link>https://ykyi.net/?p=942/</link>
      <pubDate>Thu, 28 Feb 2013 02:02:31 +0000</pubDate>
      <guid>https://ykyi.net/?p=942/</guid>
      <description>&lt;p&gt;看来编译时出现警告要非常重视，一定要对警告的意义非常清楚，这极可能是出现BUG的原因。&lt;/p&gt;
&lt;p&gt;昨天调了一整个晚上，各种离奇的出错~~&lt;/p&gt;
&lt;p&gt;其实编译内核模块时，已经提示我警告了，但我一直没注意：&lt;/p&gt;
&lt;p&gt;  Building modules, stage 2.&lt;br&gt;
  MODPOST 1 modules&lt;br&gt;
WARNING: modpost: Found 1 section mismatch(es).&lt;br&gt;
To see full details build your kernel with:&lt;br&gt;
&amp;lsquo;make CONFIG_DEBUG_SECTION_MISMATCH=y&amp;rsquo;&lt;br&gt;
  CC      /home/zausiu/linux-3.0.66/mm/sksm/sksm.mod.o&lt;br&gt;
  LD [M]  /home/zausiu/linux-3.0.66/mm/sksm/sksm.ko&lt;/p&gt;
&lt;p&gt;警告告诉我使用 &lt;span style=&#34;font-size: 13px;&#34;&gt;&amp;lsquo;make CONFIG_DEBUG_SECTION_MISMATCH=y&amp;rsquo;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: 13px;&#34;&gt;我以为要编译整棵kenel sourcecode tree时打开DEBUG_SECTION_MISMATCH编译选项，在我的虚机里编译一次要几个小时啊，果断拒绝了。其实在内核代码树外单独编译内核模块时也只用DEBUG_SECTION_MISMATCH=y这个选项。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: 13px;&#34;&gt;# make DEBUG_SECTION_MISMATCH=y&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: 13px;&#34;&gt;…&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;  Building modules, stage 2.&lt;br&gt;
  MODPOST 1 modules&lt;br&gt;
WARNING: /home/zausiu/linux-3.0.66/mm/sksm/sksm.o(.init.text+0x193): Section mismatch in reference from the function init_module() to the function .exit.text:sksm_slab_free()&lt;br&gt;
The function __init init_module() references&lt;br&gt;
a function __exit sksm_slab_free().&lt;br&gt;
This is often seen when error handling in the init function&lt;br&gt;
uses functionality in the exit path.&lt;br&gt;
The fix is often to remove the __exit annotation of&lt;br&gt;
sksm_slab_free() so it may be used outside an exit section.&lt;/p&gt;</description>
    </item>
    <item>
      <title>dpkg的一些用法</title>
      <link>https://ykyi.net/?p=940/</link>
      <pubDate>Mon, 25 Feb 2013 02:28:11 +0000</pubDate>
      <guid>https://ykyi.net/?p=940/</guid>
      <description>&lt;div class=&#34;showHead&#34; style=&#34;padding: 0px; margin: 5px 12px 0px; height: 60px; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: rgb(204, 204, 204); color: rgb(85, 85, 85); font-family: 宋体, &#39;Arial Narrow&#39;, arial, serif; line-height: normal;&#34;&gt;
  &lt;div class=&#34;showTitleBOx&#34; style=&#34;padding: 20px 0px 0px; margin: 0px; overflow: hidden; text-align: center;&#34;&gt;
    &lt;div class=&#34;showTitle&#34; style=&#34;padding: 0px; margin: 0px; font-weight: bold; font-size: 20px; line-height: 20px; font-family: 宋体;&#34;&gt;
      Debian的dpkg的一些用法
    &lt;/div&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;p&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/p&amp;gt;&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;showContent&#34; style=&#34;padding: 0px; margin: 20px 15px 8px; line-height: 2; font-size: 14px; border-bottom-width: 1px; border-bottom-style: dashed; border-bottom-color: rgb(217, 217, 217); word-wrap: break-word; word-break: normal; color: rgb(85, 85, 85); font-family: 宋体, &#39;Arial Narrow&#39;, arial, serif;&#34;&gt;
  &lt;b style=&#34;padding: 0px; margin: 0px;&#34;&gt;1. 查看当前系统中的软件信息(dpkg -l)&lt;/b&gt;&lt;br style=&#34;padding: 0px; margin: 0px;&#34; /&gt;&lt;br /&gt; &lt;br /&gt; &#34;dpkg -l&#34;命令用于查看当前系统中所有deb的软件包信息；通过&#34;dpkg -l&#34;命令与less和grep命令配合使用，可以实现更复杂的软件包信息查询功能。&lt;br style=&#34;padding: 0px; margin: 0px;&#34; /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br style=&#34;padding: 0px; margin: 0px;&#34; /&gt;&lt;br /&gt; &lt;br /&gt; &lt;span style=&#34;padding: 0px; margin: 0px; color: rgb(102, 102, 204);&#34;&gt;debian:~/Desktop# dpkg -l&lt;br style=&#34;padding: 0px; margin: 0px;&#34; /&gt;&lt;br /&gt; &lt;br /&gt; 期望状态=未知(u)/安装(i)/删除(r )/清除(p)/保持(h)&lt;br style=&#34;padding: 0px; margin: 0px;&#34; /&gt;&lt;br /&gt; &lt;br /&gt; | 当前状态=未(n)/已安装(i)/仅存配置(c )/仅解压缩(U)/配置失败(F)/不完全安装(H)&lt;br style=&#34;padding: 0px; margin: 0px;&#34; /&gt;&lt;br /&gt; &lt;br /&gt; |/ 错误？=(无)/保持(?)/须重装(R )/两者兼有(#) (状态，错误：大写=故障)&lt;br style=&#34;padding: 0px; margin: 0px;&#34; /&gt;&lt;br /&gt; &lt;br /&gt; ||/ 名称 版本 简介&lt;/span&gt;&lt;br style=&#34;padding: 0px; margin: 0px;&#34; /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br style=&#34;padding: 0px; margin: 0px;&#34; /&gt;&lt;br /&gt; &lt;br /&gt; &lt;br style=&#34;padding: 0px; margin: 0px;&#34; /&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>一位高手写的山东莱芜方言高频词汇</title>
      <link>https://ykyi.net/?p=935/</link>
      <pubDate>Wed, 20 Feb 2013 04:33:43 +0000</pubDate>
      <guid>https://ykyi.net/?p=935/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    &lt;strong&gt;山东莱芜方言高频词汇&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    作者： 高龙超&amp;nbsp;gaolch001@163.com
  &lt;/p&gt;
  &lt;p&gt;
    一、人称代词：
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    惩（音&amp;ldquo;恩&amp;rdquo;，ŋən）：你，你们
  &lt;/p&gt;
  &lt;p&gt;
    俺（ŋan）：我，我们
  &lt;/p&gt;
  &lt;p&gt;
    他（音近&amp;ldquo;特&amp;rdquo;，tə）：他
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    二、时间名词：
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    1、日子
  &lt;/p&gt;
  &lt;p&gt;
    夜来：昨天
  &lt;/p&gt;
  &lt;p&gt;
    今（音&amp;ldquo;机&amp;rdquo;，tɕi）们：今天
  &lt;/p&gt;
  &lt;p&gt;
    明日：明天
  &lt;/p&gt;
  &lt;p&gt;
    后日：后天
  &lt;/p&gt;
  &lt;p&gt;
    大后日：大后天
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    2、早晚
  &lt;/p&gt;
  &lt;p&gt;
    早晨：早上
  &lt;/p&gt;
  &lt;p&gt;
    头晌午：上午
  &lt;/p&gt;
  &lt;p&gt;
    晌午：中午
  &lt;/p&gt;
  &lt;p&gt;
    光午：为&amp;ldquo;过晌午&amp;rdquo;的连读，意为下午
  &lt;/p&gt;
  &lt;p&gt;
    后晌：晌（音&amp;ldquo;赏&amp;rdquo;，sŋ）亦常读作航（hɔŋ）
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    3、时钟
  &lt;/p&gt;
  &lt;p&gt;
    钟头：小时
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    不大霎（音&amp;ldquo;杀&amp;rdquo;，sa）：一会儿，不多时候，不长时间
  &lt;/p&gt;
  &lt;p&gt;
    大盼（pan）子：一大会儿，不超过半日
  &lt;/p&gt;
  &lt;p&gt;
    大会子：过了好久，一般指数月
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    三、动词：
  &lt;/p&gt;
  &lt;p&gt;
    1、与&amp;ldquo;家&amp;rdquo;有关
  &lt;/p&gt;
  &lt;p&gt;
    &amp;ldquo;家&amp;rdquo;作副词，表示动作的方向，该方向一般指自己的家。
  &lt;/p&gt;
  &lt;p&gt;
    家来：表示往&amp;ldquo;家&amp;rdquo;的方向而来，一般用来邀请其他人进入自己家
  &lt;/p&gt;
  &lt;p&gt;
    家去：表示往&amp;ldquo;家&amp;rdquo;的方向而去，&amp;ldquo;去&amp;rdquo;一般读作&amp;ldquo;气&amp;rdquo;，tɕʻi
  &lt;/p&gt;
  &lt;p&gt;
    家走：表示往&amp;ldquo;家&amp;rdquo;的方向而走，与&amp;ldquo;家去&amp;rdquo;相近，但&amp;ldquo;家走&amp;rdquo;更用来强调动作。
  &lt;/p&gt;
  &lt;p&gt;
    2、给（音&amp;ldquo;及&amp;rdquo;，tɕi）
  &lt;/p&gt;
  &lt;p&gt;
    表示&amp;ldquo;很&amp;rdquo;的程度副词：
  &lt;/p&gt;
  &lt;p&gt;
    （1）&amp;ldquo;精&amp;rdquo;，形容&amp;ldquo;小&amp;rdquo;及相近的词：
  &lt;/p&gt;
  &lt;p&gt;
    精短&amp;nbsp;精细&amp;nbsp;精窄&amp;nbsp;精矮（音近&amp;ldquo;眼&amp;rdquo;，iai）精浅&amp;nbsp;精薄&amp;nbsp;精瘦
  &lt;/p&gt;
  &lt;p&gt;
    该组多用ABB式叠词，比如&amp;ldquo;精短&amp;rdquo;可以说&amp;ldquo;精短短&amp;rdquo;
  &lt;/p&gt;
  &lt;p&gt;
    （2）&amp;ldquo;大&amp;rdquo;，形容&amp;ldquo;大&amp;rdquo;及相近的词：
  &lt;/p&gt;
  &lt;p&gt;
    大长&amp;nbsp;大粗&amp;nbsp;大厚（该组多用ABB式叠词）
  &lt;/p&gt;
  &lt;p&gt;
    （3）&amp;ldquo;乔&amp;rdquo;含有让人难以忍受的意思。
  &lt;/p&gt;
  &lt;p&gt;
    乔冷、乔热、乔苦、乔脏、乔酸、乔硬、乔辣、乔臭、乔难受、乔不得劲、乔肚子疼。
  &lt;/p&gt;
  &lt;p&gt;
    （4）&amp;ldquo;详&amp;rdquo;，&amp;nbsp;多有赞叹之意
  &lt;/p&gt;
  &lt;p&gt;
    详肥、详瘦、详干净、详富、详好。
  &lt;/p&gt;
  &lt;p&gt;
    （5）&amp;ldquo;怪&amp;rdquo;，它的语用域很广，只要普通话中能和副词&amp;ldquo;很&amp;rdquo;结合的词都能和&amp;ldquo;怪&amp;rdquo;结合。
  &lt;/p&gt;
  &lt;p&gt;
    怪沉、怪香、怪高、怪痛快、怪好
  &lt;/p&gt;
  &lt;p&gt;
    （6）&amp;ldquo;忒&amp;rdquo;，近似于普通话的&amp;ldquo;太&amp;rdquo;，一般表示程度有点过。
  &lt;/p&gt;
  &lt;p&gt;
    忒大、忒小、忒酸、忒甜、忒干净、忒窝囊
  &lt;/p&gt;
  &lt;p&gt;
    （7）&amp;ldquo;挺&amp;rdquo;，一般只能修饰&amp;ldquo;湿&amp;rdquo;和&amp;ldquo;浓&amp;rdquo;（泥泞）。
  &lt;/p&gt;
  &lt;p&gt;
    （8）其他固定搭配副词
  &lt;/p&gt;
  &lt;p&gt;
    焦酸&amp;nbsp;焦黄&amp;nbsp;焦干&amp;nbsp;焦劲&amp;nbsp;齁咸&amp;nbsp;稀甜&amp;nbsp;稀烂&amp;nbsp;稀软&amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    锃明&amp;nbsp;锃白&amp;nbsp;锃绿&amp;nbsp;乌黑&amp;nbsp;红黑&amp;nbsp;齁辣
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    四、发音特点
  &lt;/p&gt;
  &lt;p&gt;
    1、声母：
  &lt;/p&gt;
  &lt;p&gt;
    （1）普通话的zh，ch，sh，r基本上读成平舌音z，c，s，？，普通话的z，c，s基本上读成咬舌音？，&amp;theta;，？。
  &lt;/p&gt;
  &lt;p&gt;
    普通话的w声母大都读成唇齿音v。
  &lt;/p&gt;
  &lt;p&gt;
    （2）后面接u,&amp;nbsp;ə时，部分r声母读成l
  &lt;/p&gt;
  &lt;p&gt;
    容&amp;nbsp;（音&amp;ldquo;龙&amp;rdquo;）luŋ&amp;nbsp;，褥（音&amp;ldquo;陆&amp;rdquo;）lu&amp;nbsp;，&amp;nbsp;乳（音&amp;ldquo;鲁&amp;rdquo;）lu&amp;nbsp;&amp;nbsp;，软（音&amp;ldquo;卵&amp;rdquo;）luan
  &lt;/p&gt;
  &lt;p&gt;
    （3）普通话的零声母基本全部改为ŋ声母
  &lt;/p&gt;
  &lt;p&gt;
    俺ŋan，&amp;nbsp;爱&amp;nbsp;ŋai，&amp;nbsp;摁&amp;nbsp;ŋen&amp;nbsp;，袄&amp;nbsp;ŋɔ
  &lt;/p&gt;
  &lt;p&gt;
    2、韵母：
  &lt;/p&gt;
  &lt;p&gt;
    （1）以下字均为ei&amp;nbsp;（近-ik）作为韵母：
  &lt;/p&gt;
  &lt;p&gt;
    得&amp;nbsp;dei&amp;nbsp;&amp;nbsp;德&amp;nbsp;dei&amp;nbsp;&amp;nbsp;客&amp;nbsp;kei&amp;nbsp;&amp;nbsp;责&amp;nbsp;zei&amp;nbsp;&amp;nbsp;白&amp;nbsp;bei&amp;nbsp;&amp;nbsp;百&amp;nbsp;bei&amp;nbsp;&amp;nbsp;色&amp;nbsp;sei&amp;nbsp;麦&amp;nbsp;mei&amp;nbsp;摘&amp;nbsp;zei&amp;nbsp;册&amp;nbsp;cei&amp;nbsp;策&amp;nbsp;cei&amp;nbsp;&amp;nbsp;墨&amp;nbsp;mei&amp;nbsp;脉&amp;nbsp;mei&amp;nbsp;&amp;nbsp;宅&amp;nbsp;zei&amp;nbsp;迫&amp;nbsp;pei&amp;nbsp;&amp;nbsp;柏&amp;nbsp;bei&amp;nbsp;拍&amp;nbsp;pei&amp;nbsp;窄&amp;nbsp;zei&amp;nbsp;刻kei&amp;nbsp;&amp;nbsp;塞&amp;nbsp;&amp;theta;ei
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    （2）以下字均以-uə结尾：
  &lt;/p&gt;
  &lt;p&gt;
    药（音&amp;ldquo;约&amp;rdquo;）iuə&amp;nbsp;薄buə&amp;nbsp;脚tɕuə&amp;nbsp;博buə&amp;nbsp;钥（音&amp;ldquo;月&amp;rdquo;）iuə&amp;nbsp;着zuə&amp;nbsp;勺suə
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    （3）前后鼻音与普通话不同的字：
  &lt;/p&gt;
  &lt;p&gt;
    怎&amp;nbsp;dzəng
  &lt;/p&gt;
  &lt;p&gt;
    暖&amp;nbsp;nang
  &lt;/p&gt;
  &lt;p&gt;
    懂&amp;nbsp;dun
  &lt;/p&gt;
  &lt;p&gt;
    甭&amp;nbsp;bən
  &lt;/p&gt;
  &lt;p&gt;
    吗&amp;nbsp;mang
  &lt;/p&gt;
  &lt;p&gt;
    嘛&amp;nbsp;man
  &lt;/p&gt;
  &lt;p&gt;
    吧&amp;nbsp;bə
  &lt;/p&gt;
  &lt;p&gt;
    (4)了
  &lt;/p&gt;
  &lt;p&gt;
    句中用lɔ（唠）,句尾用liə（咧）。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    五、其他习惯：
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    1、一般不用&amp;ldquo;死&amp;rdquo;字，普通话中有&amp;ldquo;死&amp;rdquo;这的，一般有&amp;ldquo;煞&amp;rdquo;（音&amp;ldquo;舌&amp;rdquo;，sa）。如：
  &lt;/p&gt;
  &lt;p&gt;
    气煞我咧：气死我了
  &lt;/p&gt;
  &lt;p&gt;
    喜煞我咧：笑死我了
  &lt;/p&gt;
  &lt;p&gt;
    冻煞咧：冻死了
  &lt;/p&gt;
  &lt;p&gt;
    关煞门：关死门（即：关上门）
  &lt;/p&gt;
  &lt;p&gt;
    2、普通话的&amp;ldquo;亮&amp;rdquo;一般改用&amp;ldquo;明&amp;rdquo;
  &lt;/p&gt;
  &lt;p&gt;
    明天了：天亮了
  &lt;/p&gt;
  &lt;p&gt;
    月明：月亮
  &lt;/p&gt;
  &lt;p&gt;
    锃明：锃亮
  &lt;/p&gt;
  &lt;p&gt;
    明快：明亮
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>GCC内联汇编写的memcmp函数 for x86-64</title>
      <link>https://ykyi.net/?p=933/</link>
      <pubDate>Sun, 17 Feb 2013 12:32:07 +0000</pubDate>
      <guid>https://ykyi.net/?p=933/</guid>
      <description>&lt;p&gt;今天写内核代码时要写一个比较两个页框(Page Frame)的函数，想到用内联汇编来写这个功能。下面是代码：&lt;/p&gt;
&lt;p&gt;long cmp_x64(void *s1, void *s2, size_t n)&lt;br&gt;
{&lt;br&gt;
    size_t num = n / 8;&lt;br&gt;
    register long res;&lt;/p&gt;
&lt;p&gt;    __asm__ __volatile__&lt;br&gt;
    (&lt;br&gt;
     &amp;ldquo;testq %3,%3\n\t&amp;rdquo;               ; 测试num是不是0&lt;br&gt;
     &amp;ldquo;repe  cmpsq\n\t&amp;rdquo;                ; 不停地比较直到cx寄存器为0或比较到差别&lt;br&gt;
     &amp;ldquo;je        1f\n\t&amp;rdquo;              ; 两块内存相等，跳出，返回0.&lt;br&gt;
     &amp;ldquo;sbbq      %0,%0\n\t&amp;rdquo;    ; sbb是x86的减法指令，会额外地减去CF(借位)的值，这样%0就会是0或者-1&lt;br&gt;
     &amp;ldquo;orq       $1,%0\n&amp;rdquo;         ; 把立即数1或到%0上，这样%0就会是1或者-1.&lt;br&gt;
     &amp;ldquo;1:&amp;rdquo;&lt;br&gt;
         : &amp;ldquo;=&amp;amp;a&amp;rdquo;(res)          ;  传入变量res放入寄存器ax，且这个变量是输出值(=)，不要与其它输入输出共用寄存器(&amp;amp;)&lt;br&gt;
     : &amp;ldquo;0&amp;rdquo;(res), &amp;ldquo;S&amp;rdquo;(s1), &amp;ldquo;D&amp;rdquo;(s2), &amp;ldquo;c&amp;rdquo;(num)  ; 输入列表&lt;br&gt;
     : &amp;ldquo;cc&amp;rdquo;);           // clobber list 告诉gcc在这段内联汇编中哪些寄存器被显式/隐式修改.&lt;span style=&#34;color: rgb(0, 0, 0); font-family: &#39;Times New Roman&#39;; font-size: medium; line-height: normal;&#34;&gt;If our instruction can alter the condition code register, we have to add &amp;ldquo;cc&amp;rdquo; to the list of clobbered registers.&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux内核中的宏可变参数(GCC的宏可变参数)</title>
      <link>https://ykyi.net/?p=931/</link>
      <pubDate>Sun, 17 Feb 2013 05:10:42 +0000</pubDate>
      <guid>https://ykyi.net/?p=931/</guid>
      <description>&lt;pre style=&#34;color: rgb(0, 0, 0); line-height: normal; word-wrap: break-word; white-space: pre-wrap;&#34;&gt;Linux内核中的宏可变参数(GCC的宏可变参数)。
写内核模块的时候为了调试方便，经常需要wrap一下printk函数。下面的宏定义非常有实用价值。
注意两个井号~~
记到博客里~~

#define seclvl_printk(verb, type, fmt, arg...)			\
	do {							\
		if (verbosity &amp;gt;= verb) {			\
			static unsigned long _prior;		\
			unsigned long _now = jiffies;		\
			if ((_now - _prior) &amp;gt; HZ) {		\
				printk(type &#34;%s: %s: &#34; fmt,	\
					MY_NAME, __FUNCTION__ ,	\
					## arg);		\
				_prior = _now;			\
			}					\
		}						\
	} while (0)&lt;/pre&gt;</description>
    </item>
    <item>
      <title>今天用Debian时总遇到locale的错误.</title>
      <link>https://ykyi.net/?p=925/</link>
      <pubDate>Thu, 14 Feb 2013 13:59:56 +0000</pubDate>
      <guid>https://ykyi.net/?p=925/</guid>
      <description>&lt;p&gt;我的debian一般把LC_ALL设成en_US.UTF-8。这次dpkg-reconfigure locales时没有选美国英语，而是用了香港英语。于是就出错了。&lt;/p&gt;
&lt;p&gt;解决方法的关键在于  /etc/environment 文件,  dpkg-reconfigure locales 命令用来配置local，以及locale命令列出当前期待的locale，还有 local-gen 命令可以生成local.&lt;/p&gt;
&lt;p&gt;debian报得错误类似于：&lt;/p&gt;
&lt;p&gt;perl: warning: Setting locale failed.&lt;br&gt;
perl: warning: Please check that your locale settings:&lt;br&gt;
    LANGUAGE = &amp;ldquo;en_US:en&amp;rdquo;,&lt;br&gt;
    LC_ALL = (unset),&lt;br&gt;
    LANG = &amp;ldquo;en_US&amp;rdquo;&lt;br&gt;
    are supported and installed on your system.&lt;/p&gt;
&lt;p&gt;////////////&lt;/p&gt;
&lt;p&gt;另外今天还解决了编译内核后，用新内核启动时报错：&lt;/p&gt;
&lt;p&gt;kernel panic – not syncing VFS: unable to mount root fs on unknown block (0, 0)&lt;/p&gt;
&lt;p&gt;// 通常这是因为对应文件系统被编译成模块，那么就应该生成initrd加载对应的文件驱动模块。在debian下，用update-initramfs 命令生成对应的initrd. 如： update-initramfs -c -k 3.0.63&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>git的排错神器pickaxe和git blame</title>
      <link>https://ykyi.net/?p=920/</link>
      <pubDate>Tue, 29 Jan 2013 08:30:03 +0000</pubDate>
      <guid>https://ykyi.net/?p=920/</guid>
      <description>&lt;p&gt;git log -Sstring 这里的-S选项被称作pickaxe，这是一个非常好的排错工具。&lt;/p&gt;
&lt;p&gt;比如： git log -Sinclude –pretty=oneline –abbrev-commit init/version.c&lt;/p&gt;
&lt;p&gt;会把减少了，或者增加了include的commit全部找出来。&lt;/p&gt;
&lt;p&gt;要注意的是，如果有一个提交增加和减少include的次数一样，这个commit不会被列出来。&lt;/p&gt;
&lt;p&gt;/////////////&lt;/p&gt;
&lt;p&gt;另外一个排错工作是 git blame:&lt;/p&gt;
&lt;p&gt;git blame可以用来帮助查找引入bug的commit。git blame告诉你谁，什么时候，是哪个commit更改了某个文件。&lt;/p&gt;
&lt;p&gt;如: git blame -L 32, init/version.c&lt;/p&gt;</description>
    </item>
    <item>
      <title>使用gdb和虚拟机调试内核</title>
      <link>https://ykyi.net/?p=917/</link>
      <pubDate>Mon, 28 Jan 2013 03:31:28 +0000</pubDate>
      <guid>https://ykyi.net/?p=917/</guid>
      <description>&lt;p&gt;调试内核很麻烦，即使是有了虚拟机的帮助。在这里记下一些关键的东西，以备忘 。&lt;/p&gt;
&lt;p&gt;＃  编译内核后， 用新内核启动系统失败，报错 “unable to mount fs ….” 之类.&lt;/p&gt;
&lt;p&gt;需要用 update-initramfs 生成initram。&lt;/p&gt;
&lt;p&gt;＃ 对于grub2，我增加了一个自定义的grub开机启动项用来调试内核，如下：&lt;/p&gt;
&lt;p&gt;#!/bin/sh&lt;br&gt;
exec tail -n +3 $0&lt;br&gt;
# This file provides an easy way to add custom menu entries.  Simply type the&lt;br&gt;
# menu entries you want to add after this comment.  Be careful not to change&lt;br&gt;
# the &amp;rsquo;exec tail&amp;rsquo; line above.&lt;br&gt;
echo &amp;ldquo;Add Debugging entry&amp;rdquo;&lt;br&gt;
cat &amp;laquo; EOF&lt;br&gt;
menuentry &amp;ldquo;Debian debug 3.7.4&amp;rdquo;{&lt;br&gt;
set root=(hd0,1)&lt;br&gt;
linux /boot/vmlinuz-3.7.4 root=/dev/vda1 ro quiet kgdboc=ttyS0,115200 kgdbwait&lt;br&gt;
initrd /boot/initrd.img-3.7.4&lt;br&gt;
}&lt;br&gt;
EOF&lt;/p&gt;</description>
    </item>
    <item>
      <title>尼玛，原来用财富通转账比用支付宝便宜。</title>
      <link>https://ykyi.net/?p=914/</link>
      <pubDate>Wed, 23 Jan 2013 06:04:43 +0000</pubDate>
      <guid>https://ykyi.net/?p=914/</guid>
      <description>&lt;p&gt;今天我哥们要我给打他些钱。&lt;/p&gt;
&lt;p&gt;于是我就想到用支付宝试试，但哥也还有财富通的账号呀~~于是比较了两个支付平台的收费标准。&lt;/p&gt;
&lt;div&gt;
  这是财富通的：
&lt;/div&gt;
&lt;div&gt;
  到账时间&amp;nbsp;&amp;nbsp;&amp;nbsp; 服务费率真&amp;nbsp;&amp;nbsp; 手续费下限&amp;nbsp;&amp;nbsp;&amp;nbsp; 手续费上限&lt;br /&gt; 次日到账&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.1%&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1元/笔&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10元/笔&lt;br /&gt; 2小时到账&amp;nbsp; 0.25%&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1元/笔&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 50元/笔
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  这是支付宝的：
&lt;/div&gt;
&lt;div&gt;
  &lt;table&gt;
    &lt;caption&gt;收费标准：&lt;/caption&gt; &lt;tr&gt;
      &lt;th&gt;
        用户类型
      &lt;/th&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;th&amp;gt;
    到账时间
  &amp;lt;/th&amp;gt;
  
  &amp;lt;th&amp;gt;
    服务费率
  &amp;lt;/th&amp;gt;
  
  &amp;lt;th&amp;gt;
    服务费下限
  &amp;lt;/th&amp;gt;
  
  &amp;lt;th&amp;gt;
    服务费上限
  &amp;lt;/th&amp;gt;
&amp;lt;/tr&amp;gt;

&amp;lt;tr&amp;gt;
  &amp;lt;td rowspan=&amp;quot;2&amp;quot;&amp;gt;
    金账户会员&amp;lt;br /&amp;gt; &amp;lt;em style=&amp;quot;margin-left:12px;&amp;quot;&amp;gt;(7折)&amp;lt;/em&amp;gt;
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    次日到账
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    0.175%
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    0.9元/笔
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    35元/笔
  &amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;

&amp;lt;tr&amp;gt;
  &amp;lt;td&amp;gt;
    2小时内到账
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    0.35%
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    1元/笔
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    35元/笔
  &amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;

&amp;lt;tr&amp;gt;
  &amp;lt;td rowspan=&amp;quot;2&amp;quot;&amp;gt;
    普通会员
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    次日到账
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    0.25%
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    0.9元/笔
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    50元/笔
  &amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;

&amp;lt;tr&amp;gt;
  &amp;lt;td&amp;gt;
    2小时内到账
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    0.5%
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    1元/笔
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td&amp;gt;
    &amp;lt;p&amp;gt;
      50元/笔
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/table&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;</description>
    </item>
    <item>
      <title>Okular是linux下最好用的pdf阅读工具</title>
      <link>https://ykyi.net/?p=911/</link>
      <pubDate>Fri, 04 Jan 2013 12:55:46 +0000</pubDate>
      <guid>https://ykyi.net/?p=911/</guid>
      <description>&lt;p style=&#34;margin: 0px 0px 13px; padding: 0px; border: 0px; outline: 0px; font-size: 15px; font-family: Georgia, Times, &#39;Liberation Serif&#39;, serif; vertical-align: baseline; line-height: 22px; &#34;&gt;
  &lt;span style=&#34;font-size: 15px; &#34;&gt;我记得对于大多数Gnome桌面环境，Evince是默认的pdf阅读软件。&lt;/span&gt;&lt;span style=&#34;font-size: 15px; &#34;&gt;今天不知道怎么回事，发现evince没有了。当时我不记得evince这个名字了，就apt-cache search pdf 随便装上了xpdf-viewer。太他妈难用了啊～～就卸载了，然后google: &lt;/span&gt;&lt;span style=&#34;font-size: 15px; &#34;&gt;The Best PDF Viewer on Linux。找到了Okular，也是免费软件，装上一用。不错哈哈哈.贴一张网络上的图片：&lt;/span&gt;
&lt;/p&gt;
&lt;p style=&#34;margin: 0px 0px 13px; padding: 0px; border: 0px; outline: 0px; font-size: 15px; font-family: Georgia, Times, &#39;Liberation Serif&#39;, serif; vertical-align: baseline; line-height: 22px; &#34;&gt;
  &lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;alignnone&#34; height=&#34;360&#34; src=&#34;http://cache.lifehacker.com/assets/images/17/2012/01/82d614bf4c4d89c757cb0050d3255bd9.jpg&#34; width=&#34;640&#34; /&gt;
&lt;/p&gt;
&lt;p style=&#34;margin: 0px 0px 13px; padding: 0px; border: 0px; outline: 0px; font-size: 15px; font-family: Georgia, Times, &#39;Liberation Serif&#39;, serif; vertical-align: baseline; line-height: 22px; &#34;&gt;
  另外今天才知道, Adobe也有出linux下的pdf阅读软件。
&lt;/p&gt;</description>
    </item>
    <item>
      <title>显示Gnome3任务栏</title>
      <link>https://ykyi.net/?p=896/</link>
      <pubDate>Thu, 03 Jan 2013 09:22:54 +0000</pubDate>
      <guid>https://ykyi.net/?p=896/</guid>
      <description>&lt;p&gt;Gnome3桌面较之Gnome2有了非常大的区别～&lt;/p&gt;
&lt;p&gt;第一眼看上去有惊艳的感觉～多用了一点时间，发现没有任务栏真是相当的不方便啊。我觉得最方便的还是Win7的方式。&lt;/p&gt;
&lt;p&gt;那怎么把Gnome3消失的任务栏找回来呢？通过安装一个安装包搞定。&lt;/p&gt;
&lt;p&gt;我用的是Debian 6.06 Wheazy&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;zausiu@accolade:~$ cat /etc/debian_version&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;6.0.6&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;对于Debian家族的ubuntu应该也是适用的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;# apt-get install tint2&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;$ tint2 &amp;amp;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;于是久违的gnome任务又回来了～&lt;/p&gt;
&lt;figure style=&#34;width: 1680px&#34; class=&#34;wp-caption alignnone&#34;&gt;&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; alt=&#34;Gnome的任务栏又回来了&#34; src=&#34;http://www.micahcarrick.com/images/migrating-to-gnome-3/tint2-panel-large.png&#34; width=&#34;800&#34; height=&#34;444&#34; /&gt;&lt;figcaption class=&#34;wp-caption-text&#34;&gt;Gnome的任务栏又回来了&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>Let the Universal Access Preferences Taskbar Icon Disappear让统一访问首选项在任务栏上消失</title>
      <link>https://ykyi.net/?p=892/</link>
      <pubDate>Wed, 02 Jan 2013 05:45:27 +0000</pubDate>
      <guid>https://ykyi.net/?p=892/</guid>
      <description>&lt;p&gt;我用的是Debian Wheezy Stable系统。今天不知道怎么搞得，把任务栏上面弄出个 配置Universal Access Preferences的图标。右链点击也没有让我选择退出的选项。&lt;/p&gt;
&lt;p&gt;搜索了一下，知道用 gnome-keyboard-properties 把这个该死的图标去掉。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;alt+F2  输入 gnome-keyboard-properties&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;选中Accessibility ，取消 Accessibility features can be toggled with keyboard shortcuts.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这几天调linux内核源代码，好困难好困难。&lt;/p&gt;</description>
    </item>
    <item>
      <title>2012年终总结 预言2013</title>
      <link>https://ykyi.net/?p=885/</link>
      <pubDate>Sat, 15 Dec 2012 06:51:48 +0000</pubDate>
      <guid>https://ykyi.net/?p=885/</guid>
      <description>&lt;p&gt;身为一只技术蝼蚁，我的2012是离奇又相当刺激的一年。这一年年初，我遇见了让我难忘的人，虽然结局非常悲惨；年中剑桥高级商务英语考试惨败与经历了时间最长的一次失眠症；下半年经历了找工作的惊心动魂又收获了惊喜；年尾写毕业论文比便秘还要艰难。&lt;/p&gt;
&lt;p&gt;在互联网的战场上就更加刺激好玩~看看互联网的各派势怎么玩的&lt;/p&gt;
&lt;p&gt;360：&lt;br&gt;
战 争之王周流氓继续发挥，打了三大战役。小三大战，在终端市场狙击以期货方式做互联网手机的小米军团；3B大战，继续挖掘 客户端—浏览器—网址导流加搜索 的三级火箭的商业模式，推出自营搜索引擎，挑战百度的垄断地位，直击百度的要害‘竞价排名’，揭露百度搜索引擎上医疗推广的暴利，从搜索市场上圈到了 10%的市场份额；还有方舟子和周总的大战，哈哈，这次算是棋缝对手啊。&lt;/p&gt;
&lt;p&gt;sina:&lt;br&gt;
新浪的微博在商业化的探索上继续苦苦挣扎。传统新浪网造血供给微博，微博继续烧钱，面对腾讯微博的防守和微信的进攻，资本市场惭惭对新浪微博失去信心。新浪已然失去掘起为 Baidu, Alibaba, Tencent 三大巨头同量级的大军阀的机会。&lt;/p&gt;
&lt;p&gt;金山：&lt;br&gt;
金 山软件旗下的游戏和办公软件仍然波澜不惊。金山快盘拆分出来成立金山云计算公司，不知业绩怎样，个人觉得快盘还是满好用的，不过我已经改成用腾讯微云了。 各大产商纷纷进入云存储领域，快盘若想有所作为也不那么容易。在傅胜的带领上，金山安全抢到了足够多的爆光率。金山安全年中推出猎豹浏览器，主打UI酷炫 的特点，至此金山安全的的商业模式与360几乎一样。金山安全旗下软件的推广明显变得流氓起来。但，祝我的老东家走好。&lt;/p&gt;
&lt;p&gt;百度：&lt;br&gt;
百度面临360搜索的极大威胁，李彦宏呼吁百度员工的‘狼性’。如周鸿祎所说，百度缺的不是狼性，缺的是人性。百度的欺诈医疗推广伤天害理，道德伦丧啊。今年8月时，哥就被百度的欺诈医疗推广骗到了广州海军医院。仅就3B大战而言，哥支持360.&lt;/p&gt;
&lt;p&gt;阿里：&lt;br&gt;
马云成功回购雅虎持有的股票。阿里巴巴还是马云的阿里巴巴。淘宝商城改名天猫。电商大战如火如茶。。。。。&lt;/p&gt;
&lt;p&gt;腾讯：&lt;br&gt;
腾讯股票继续大涨。腾讯录用了哥是一大利好啊！资本市场因此非常兴奋吧。微信成功挤占了新浪微博用户的时间，并稳固了腾讯在IM市场的垄断地位。纯移动设计的微信在开放平台，o2o上给予投资者极大的想象空间。&lt;/p&gt;
&lt;p&gt;马雅人不靠谱。&lt;span style=&#34;font-size:24px&#34;&gt;2013 年大预测：&lt;/span&gt;&lt;br&gt;
作为一个技术蝼蚁，水平有限，手痒手贱，预测一下2013年哈….&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;360搜索市场份额突破15%。3B大战升级。。。&lt;/li&gt;
&lt;li&gt;小米神话破灭。。。。&lt;/li&gt;
&lt;li&gt;360运营的Line即时通讯软件慢慢做大。因语音聊天功能触及运营商的高压红线，运营商和互联网公司的矛盾继续扩大。微信顺势也上线即时语音聊天，现在仅仅是语音对讲。&lt;/li&gt;
&lt;li&gt;以前一直闷声发大财的9158因涉嫌情色被整改。&lt;/li&gt;
&lt;li&gt;楼市回暖，全国平均涨幅10%&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>用Briss批量切除pdf文件的白边</title>
      <link>https://ykyi.net/?p=854/</link>
      <pubDate>Sun, 08 Jul 2012 04:36:34 +0000</pubDate>
      <guid>https://ykyi.net/?p=854/</guid>
      <description>&lt;p&gt;这段时间准备论文，要看好多电子资料。比如中国知网下载的N多论文还有N多RFC的pdf。已经忍无可忍成天对住台电脑看资料，于是入手了一部kindle4。这下问题又来了，pdf(&lt;span style=&#34;font-family: arial, sans-serif; font-size: small; line-height: 16px; &#34;&gt;Portable Document Format&lt;/span&gt;)是专门为打印设计的，在页面的四个方向都预留了白边。对于kindle4本来就不大的屏幕来说，pdf显示在kindle4的屏幕上，字小的同乌蝇一样，比用电脑看还要费眼。于是想到去掉白边，在网络上搜索了一下，发现了好几种软件，最后哥选了briss，真的非常的酷喔~~可以把白边删除得干干净净。&lt;/p&gt;
&lt;p&gt;不过问题又来了，我有好多pdf文件呀！但是briss的操作界面只支持一次处理一个文件。看Briss的帮助文件的时候发现Briss支持用控制台操作~~如下：&lt;/p&gt;
&lt;p&gt;================&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3 id=&#34;command-line-usage使用命令行&#34;&gt;Command line usage(使用命令行)&lt;/h3&gt;
&lt;p&gt;If you prefer command line and trust the basic automatic detection algorithm use it this way (can be batched!):&lt;/p&gt;
&lt;p&gt;如果你喜欢用命令行并信任白边自动推测算法，可以用以下命令操作（支持批处理）。&lt;/p&gt;
&lt;pre&gt;java -jar briss-0.0.13.jar -s [SOURCEFILE] [-d [DESTINATIONFILE]]&lt;/pre&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;java -jar briss-0.0.13.jar -s dogeatdog.pdf -d dogcrop.pdf
java -jar briss-0.0.13.jar -s dogeatdog.pdf &lt;/pre&gt;
&lt;p&gt;================&lt;/p&gt;
&lt;p&gt;到此，就非常好办了。我的电脑装了UNIX工具链在windows平台下的移植版:cygwin，于是我只用写一行unix命令就把我的一个目录夹下面所有的pdf文件都切边了。命令如下：&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div&gt;
  zausiu@enigma /cygdrive/e/kindle4/ipv6_en &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // 当前目录 e://kindle4/ipv6_en 下面存放了所有待切白边的pdf文件.
&lt;/div&gt;
&lt;div&gt;
  $ ls *.pdf | xargs -I&#39;{}&#39; -n1 java -jar d:/Program\ Files\ \(x86\)/briss-0.0.13/briss-0.0.13.jar -s &#39;{}&#39; &amp;nbsp; &amp;nbsp;// 用来把该目录下面所有.pdf文件去白边的命令。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  我的pdf文件很多，随便贴出一点命令的输出。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &lt;div&gt;
    Since no destination was provided destination will be set to &amp;nbsp;: E:\kindle4\ipv6_en\draft-itojun-ipv6-transition-abuse-01_cropped.pdf
  &lt;/div&gt;
  &lt;div&gt;
    Clustering PDF: draft-itojun-ipv6-transition-abuse-01.pdf
  &lt;/div&gt;
  &lt;div&gt;
    Created 2 clusters.
  &lt;/div&gt;
  &lt;div&gt;
    Starting to render clusters&amp;#8230;..finished!
  &lt;/div&gt;
  &lt;div&gt;
    Calculating crop rectangles.
  &lt;/div&gt;
  &lt;div&gt;
    Starting to crop files.
  &lt;/div&gt;
  &lt;div&gt;
    Cropping succesful. Cropped to:E:\kindle4\ipv6_en\draft-itojun-ipv6-transition-a=buse-01_cropped.pdf
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    Since no destination was provided destination will be set to &amp;nbsp;: E:\kindle4\ipv6_en\layer2_attacks_and_mitigation_t_cropped.pdf
  &lt;/div&gt;
  &lt;div&gt;
    Clustering PDF: layer2_attacks_and_mitigation_t.pdf
  &lt;/div&gt;
  &lt;div&gt;
    Created 2 clusters.
  &lt;/div&gt;
  &lt;div&gt;
    Starting to render clusters&amp;#8230;&amp;#8230;&amp;#8230;.finished!
  &lt;/div&gt;
  &lt;div&gt;
    Calculating crop rectangles.
  &lt;/div&gt;
  &lt;div&gt;
    Starting to crop files.
  &lt;/div&gt;
  &lt;div&gt;
    Cropping succesful. Cropped to:E:\kindle4\ipv6_en\layer2_attacks_and_mitigation_t_cropped.pdf
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    大概的意思是，我的命令没有提供切白边后新pdf文件的文件名，于是自动取了一个名字。然后程序分析pdf文件，开始切边，最后切边成功。
  &lt;/div&gt;
  &lt;div&gt;
    由于我写的命令是用了Unix Shell的语法，所以如果你的机器没有装cygwin是运行不了这个命令的。可以把它用windows批处理的语法改写，但是哥不会windows批处理的语法哈~~~
  &lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux内核Makefiles教程(二)</title>
      <link>https://ykyi.net/?p=847/</link>
      <pubDate>Sat, 07 Jul 2012 13:52:55 +0000</pubDate>
      <guid>https://ykyi.net/?p=847/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://ykyi.net/2012/07/linux%E5%86%85%E6%A0%B8makefiles%E6%95%99%E7%A8%8B%E4%B8%80/&#34;&gt;接第一篇 &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;**3.3.**&lt;strong&gt;可加载模块目标&lt;/strong&gt; &lt;strong&gt;obj-m (Loadable module goals – obj-m)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;obj-m指定将被构建为可加载内核模块的对象文件(object file)。&lt;/p&gt;
&lt;p&gt;一个模块可以从一个源文件构建或者从多个源文件构建。如果模块仅仅从一个源文件构建，kbuild makefile仅仅把对象文件加到obj-m。如下：&lt;/p&gt;
&lt;p&gt;       #drivers/isdn/i4l/Makefile&lt;/p&gt;
&lt;p&gt;        obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o&lt;/p&gt;
&lt;p&gt;_在这个例子中，__$(CONFIG_ISDN_PPP_BSDCOMP)_&lt;em&gt;被求值为__m.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If a kernel module is built from several source files, you specify that you want to build a module in the same way as above.&lt;/p&gt;
&lt;p&gt;如果一个内核模块需要从多个源文件构建，你也是按照刚才提到的那一行指定。不过，除此之外，还要额外地指定，你的内核模块需要哪些对象文件。所以还需要设置&amp;lt;模块名&amp;gt;-objs变量。如下：&lt;/p&gt;
&lt;p&gt;       #drivers/isdn/i4l/Makefile&lt;/p&gt;
&lt;p&gt;        obj-$(CONFIG_ISDN) += isdn.o&lt;/p&gt;
&lt;p&gt;        isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o&lt;/p&gt;
&lt;p&gt;在这个例子中，模块名是 isdn 。Kbuild将编译isdn-objs列出的所有对象文件，然后运行$(LD) –r把这些对象文件链接成一个文件isdn.o。&lt;/p&gt;
&lt;p&gt;Kbuild用-objs后缀或者-y后缀识别构成复合对象文件(composite objects)的对象文件。这样，Makefile就可以使用CONFIG_* 符号来确定一个对象文件是不是一个复合对象文件的一部分。如下：&lt;/p&gt;
&lt;p&gt;       #fs/ext2/Makefile&lt;/p&gt;
&lt;p&gt;        obj-$(CONFIG_EXT2_FS)        += ext2.o&lt;/p&gt;
&lt;p&gt;        ext2-y                       := balloc.o bitmap.o&lt;/p&gt;
&lt;p&gt;        ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux内核Makefiles教程(一)</title>
      <link>https://ykyi.net/?p=840/</link>
      <pubDate>Fri, 06 Jul 2012 08:17:50 +0000</pubDate>
      <guid>https://ykyi.net/?p=840/</guid>
      <description>&lt;p&gt; &lt;/p&gt;
&lt;h1 id=&#34;linux内核makefiles&#34;&gt;Linux内核Makefiles&lt;/h1&gt;
&lt;p&gt;本教程描述了了Linux内核的Makefile是如何工作的。&lt;/p&gt;
&lt;h2 id=&#34;1概述&#34;&gt;1. 概述&lt;/h2&gt;
&lt;p&gt;Linux内核的Makefile包括五个部分。&lt;/p&gt;
&lt;table&gt;
  &lt;tr&gt;
    &lt;td style=&#34;width:203px;&#34;&gt;
      &lt;p&gt;
        Makefile
      &lt;/p&gt;
    &lt;/td&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;td style=&amp;quot;width:373px;&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;
    最上层Makefile
  &amp;lt;/p&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td style=&#34;width:203px;&#34;&gt;
      &lt;p&gt;
        .config
      &lt;/p&gt;
    &lt;/td&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;td style=&amp;quot;width:373px;&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;
    内核配置文件。
  &amp;lt;/p&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td style=&#34;width:203px;&#34;&gt;
      &lt;p&gt;
        arch/$(ARCH)/Makefile
      &lt;/p&gt;
    &lt;/td&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;td style=&amp;quot;width:373px;&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;
    CPU架构相关Makefile
  &amp;lt;/p&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td style=&#34;width:203px;&#34;&gt;
      &lt;p&gt;
        scripts/Makefile.*
      &lt;/p&gt;
    &lt;/td&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;td style=&amp;quot;width:373px;&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;
    对于所有Kbuild&amp;amp;nbsp;Makefile的公共方法。.
  &amp;lt;/p&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td style=&#34;width:203px;&#34;&gt;
      &lt;p&gt;
        kbuild&amp;nbsp;Makefiles
      &lt;/p&gt;
    &lt;/td&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;td style=&amp;quot;width:373px;&amp;quot;&amp;gt;
  &amp;lt;p&amp;gt;
    有将近500个kbuild&amp;amp;nbsp;Makefiles。
  &amp;lt;/p&amp;gt;
&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;最上层Makefile读取.config文件。.config文件是由内核配置过程生成的。&lt;/p&gt;
&lt;p&gt;最上级的Makefile负责生成linux的内核映象文件vmlinux和其它所有的模块。最上级Makefile递归地进入内核代码树的各级子目录分别执行子目录下的Makefile。究竟要进入哪些子目录是由内核配置阶段决定的，即配置在.cncfig文件中。最上级Makefile提定了一个路径为arch/$(ARCH)/Makefile的子目录Makefile。这个Makefile中定义了与处理器架构紧密相关的信息。&lt;/p&gt;
&lt;p&gt;每一个子目录下面都有一个kbuild Makefile，这里都定义了一些makefile命令和变量可以被更下级的Makefile继承。Kbuild Makefile使用来自.config配置的信息生成各种文件列表用来构建内建的或者模块化的目标文件。Scripts/Makefile.*包括了很多被其它Makefile使用定义和规则。&lt;/p&gt;
&lt;h2 id=&#34;2谁使用内核makefile&#34;&gt;2. 谁使用内核Makefile&lt;/h2&gt;
&lt;p&gt;内核Makefile的使用者可以大致分为四种。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;用户(Userse)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这类使用者仅仅敲入一些命令，如“make menuconfig”或者“make”。他们很少会阅读甚修改内核Makefile和源代码文件。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一般开发者（Normal Developers）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一般开发者一般编写一些设备驱动程序，文件系统，网络协议。他们需要维护他们编写的代码涉及的子系统的kbuild Makefiles。为了工作地更有效率，他们甚至还需要对整个内核的Makefile有全局的把握，包括对kbuild的公共接口的详尽了解。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;处理器架构开发者(Arch Developers)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这部分开发者关心与某个处理器架构紧密相关的代码部分，比如PC上最广泛使用的x86，以及IA64，还有ARM,Sparc,PowerPC,Alpha,s390,MIPS。Linux支持几百种处理器架构。从内核2.6.24开始，i386和x86_64合并为x86。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KBuild的开发者(KBuild Developers)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;KBuild的开发者就是维护内核构建系统的开发者，他们需要知道内核Makefile的各个方面。&lt;/p&gt;
&lt;p&gt;——&lt;/p&gt;
&lt;p&gt;本篇教程主要面向第二类开发者和第三类开发者。即一般开发者和处理器体系架构开发者。&lt;/p&gt;
&lt;h2 id=&#34;3kbuild文件&#34;&gt;3. kbuild文件&lt;/h2&gt;
&lt;p&gt;大多数内核Makefile文件是kbuild Makefile文件，它们使用不同于一般make文件的kbuild语法。下面会介绍kbuild makefile的语法。Kbuild文件一般被命名为Mafile，但是也可以使用Kbuild名字。如果已经存在一个Makefile文件了，那么就只好用Kbuild名字了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>中山大学软件工程专业Java语言课作业</title>
      <link>https://ykyi.net/?p=836/</link>
      <pubDate>Wed, 04 Jul 2012 02:52:24 +0000</pubDate>
      <guid>https://ykyi.net/?p=836/</guid>
      <description>&lt;p&gt;这是11年中山大学软件工程硕士研究生java必修课的大作业，授课老师是&lt;strong&gt;温武少&lt;/strong&gt;~ 讨厌写java代码。代码写得不好~不过，需要的童鞋可以拿过去改改。 &lt;a href=&#34;https://ykyi.net/mesmerize/Java_banksys_sc.zip&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;下载源代码！！！&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;下面是作业要求：&lt;/p&gt;
&lt;p&gt;面向对象程序设计课程项目&lt;/p&gt;
&lt;h2 id=&#34;基于java银行管理系统设计case-234&#34;&gt;&lt;strong&gt;基于JAVA银行管理系统设计(Case 2,3,4)&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;注意：如果发现全部或者部分copy程序，双方都将会被部分或者全部扣分。本课程是必修课，70分是通过线。&lt;/p&gt;
&lt;p&gt;    系统将依据3-tier架构设计银行管理系统。要求所有的项目用JAVA语言编程。设计的系统将是简化的银行管理系统。 &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;项目二：银行管理系统Business Logic 设计 （中程检查：10月31日（40%）;上交11月7日 （60%）， 当堂运行+ftp上交）&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;    所有的用户输入都是由命令行输入。项目必须提供设计文档、测试和运行报告。在线提交程序源程序。 &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p style=&#34;margin-left:21.3000pt;&#34;&gt;
  1．&amp;nbsp;银行用户分类:&amp;nbsp;普通个人用户，个人贵宾用户(VIP)，企业用户
&lt;/p&gt;
&lt;p&gt;   对所有的用户必须支持以下功能：开户、存款、取款、查询、转账、改密码、销户等七项工作。所有对账户的操作都要产生日志。 所有的数据都要永久化（存到硬盘）。系统重新启动时要能恢复数据。&lt;/p&gt;
&lt;p&gt;（1）开户：调研银行管理系统需要存储的账户信息。&lt;/p&gt;
&lt;p&gt;     开户时需要身份证号码，决定开的账户类型，存款的初始金额。银行生成用户的帐号，用户输入初始密码。系统给出开户的时间日志。&lt;/p&gt;
&lt;p&gt;（2）存款：&lt;/p&gt;
&lt;p&gt;   存款时需要给银行提供自己的账号，密码以及要存款的金额；银行系统反馈用户帐户的余额以及存款的日志。&lt;/p&gt;
&lt;p&gt;（3）取款：&lt;/p&gt;
&lt;p&gt;   取款时需要给银行提供自己的账号、密码以及要取的金额；系统判断是否有足够余额以供取款。取款后给出用户帐户的余额，产生取款日志。&lt;/p&gt;
&lt;p&gt;（4）查询：&lt;/p&gt;
&lt;p&gt;    查询时用户需要给银行提供自己的身份证、账号和密码；银行方面给出用户帐户的余额以及查询的日志。用户还可以查询一段时间所有的操作（流水）。&lt;/p&gt;
&lt;p&gt;（5）转帐：（对不同用户转账有限制，请看账户类型说明）&lt;/p&gt;
&lt;p&gt;    用户转帐时需要判断是否能够满足转账条件。如满足，需要给银行提供转出帐户的账号、身份证号码、密码和用户名称及转入帐户的帐号和用户名称，用户也需要提供转账金额。系统方面将产生转账日志、转出用户帐户的余额等信息。&lt;/p&gt;
&lt;p&gt;（6）改密码：&lt;/p&gt;
&lt;p&gt;用户到银行改密码时需要给银行提供身份证、帐号、以及密码，并且输入新的密码。系统方面将产生相关日志。&lt;/p&gt;
&lt;p&gt;（7）销户：&lt;/p&gt;
&lt;p&gt;用户到银行销户时需要给银行提供身份证、帐号以及密码，并且把帐户的余额全部取出。系统方面将产生相关日志。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;不同类型用户的特别限制和权限：&lt;/p&gt;
&lt;p style=&#34;margin-left:72.0000pt;&#34;&gt;
  （1）&amp;nbsp;所有的用户可开两种账户&amp;mdash;活期和定期。用户的活期和定期账号之间可以转账。
&lt;/p&gt;
&lt;p style=&#34;margin-left:72.0000pt;&#34;&gt;
  （2）&amp;nbsp;普通用户不能产生透支。
&lt;/p&gt;
&lt;p style=&#34;margin-left:72.0000pt;&#34;&gt;
  （3）&amp;nbsp;VIP用户的初始存款额（包括活期和定期）要求大于100万，&amp;nbsp;每月平均日余额要求不低于10万。如果连续2个月月平均日余额要低于10万，&amp;nbsp;将收取每月1000元的管理费。VIP用户将能够透支最多&amp;nbsp;10万元。&amp;nbsp;但要求透支的款项在规定的时间（30天）内归还。如不归还，账户将被冻结。
&lt;/p&gt;
&lt;p style=&#34;margin-left:72.0000pt;&#34;&gt;
  （4）&amp;nbsp;转账只能在个人用户之间进行，或在企业用户之间进行。
&lt;/p&gt;
&lt;p style=&#34;margin-left:72.0000pt;&#34;&gt;
  （5）&amp;nbsp;普通用户只能接收转账转入，不能转钱到别人的账户。但普通用户可以在他自己的账号内转账。VIP和企业用户容许转入、转出。
&lt;/p&gt;
&lt;p style=&#34;margin-left:72.0000pt;&#34;&gt;
  （6）&amp;nbsp;企业用户容许多个账号操作人。&amp;nbsp;我们指定其中的一到两个人作为账户超级用户，可以要求增加账户操作人。不同账户操作人必须使用不同密码。&amp;nbsp;
&lt;/p&gt;
&lt;p style=&#34;margin-left:72.0000pt;&#34;&gt;
  （7）&amp;nbsp;企业用户不容许透支。要求账面存款余额总数（包括所有的账户）不小于1万元。
&lt;/p&gt;
&lt;p style=&#34;margin-left:18.0000pt;&#34;&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p style=&#34;margin-left:39.3000pt;&#34;&gt;
  2．&amp;nbsp;&amp;nbsp;&amp;nbsp;银行雇员分类:&amp;nbsp;前台操作员，&amp;nbsp;银行经理，银行业务总管、系统管理员。&amp;nbsp;他们各自的职责:
&lt;/p&gt;
&lt;p&gt;系统必须能存储所有的雇员信息（自己调研）。银行经理管理一个或多个前台操作员，同时他可以做所有的前台操作员操作。银行业务总管管理一个或多个银行经理，他可以做所有的银行前台操作员及银行经理的工作。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;银行雇员操作：&lt;/p&gt;
&lt;p style=&#34;margin-left:72.0000pt;&#34;&gt;
  （1）&amp;nbsp;前台操作员：对账户所有的操作。雇员本身所作的操作的日报，月报，季度报和年报（包括数据和日志）。前台操作员向一个银行经理报告。
&lt;/p&gt;
&lt;p style=&#34;margin-left:72.0000pt;&#34;&gt;
  （2）&amp;nbsp;银行经理：作为前台操作员的所有操作，部门操作的日报，月报，季度报和年报（包括数据和日志，&amp;nbsp;及每个成员的报告）。银行经理必须较容易查到他部门人员总数及具体情况。银行经理向银行业务总管报告。&amp;nbsp;
&lt;/p&gt;
&lt;p style=&#34;margin-left:72.0000pt;&#34;&gt;
  （3）&amp;nbsp;银行业务总管（包括个人账户和企业账户两类）：作为前台操作员和部门经理的所有操作，整个银行相关业务操作的日报，月报，季度报和年报（包括数据和日志，&amp;nbsp;及每个成员的报告，每个部门的报告）。银行业务总管应较容易查到他所管人员总数及具体情况。
&lt;/p&gt;
&lt;p style=&#34;margin-left:72.0000pt;&#34;&gt;
  （4）&amp;nbsp;系统管理员：雇员管理。&amp;nbsp;产生整个银行的总报表和总日志（日报，月报，季度报和年报）。
&lt;/p&gt;
&lt;p style=&#34;margin-left:72.0000pt;&#34;&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p style=&#34;margin-left:39.3000pt;&#34;&gt;
  3．&amp;nbsp;（加分&amp;nbsp;20%）&amp;nbsp;银行系统网络接口
&lt;/p&gt;
&lt;p style=&#34;margin-left:39.3000pt;&#34;&gt;
  &amp;nbsp;&amp;nbsp;提供外面银行在线操作要求（必须提供通过网络提供各种操作需要的信息）。在线操作必须产生专用的日志。
&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;项目三：银行管理系统后台数据库及接口设计（上交11月21日，当堂运行+ftp上交）&lt;/p&gt;
&lt;p&gt;    数据存储采用数据库（建议用MYSQL.把business logic 层修改以支持数据库。&lt;/p&gt;
&lt;p&gt;项目四： 银行管理系统UI设计（开放设计，上交11月28日，当堂运行+ftp上交）&lt;/p&gt;
&lt;p&gt;所用的用户输入和输出采用GUI。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;说明： 项目总成绩计算：项目1： 20%&lt;/p&gt;
&lt;p&gt;                       项目2： 50%&lt;/p&gt;
&lt;p&gt;                       项目3： 15%&lt;/p&gt;
&lt;p&gt;                       项目4： 15% &lt;/p&gt;
&lt;p&gt;更多说明：&lt;/p&gt;
&lt;p&gt;1.运行报告主要是指：系统所实现的所有功能的运行截图；&lt;/p&gt;
&lt;p&gt;2.所谓“冻结”的意思是：只能查询余额，不能进行存款、取款的操作；不要求实现“解冻”，也就是这个账号一旦被冻结，这辈子就“冻”死了；&lt;/p&gt;</description>
    </item>
    <item>
      <title>三分钟Qt Quick入门</title>
      <link>https://ykyi.net/?p=833/</link>
      <pubDate>Tue, 03 Jul 2012 07:32:35 +0000</pubDate>
      <guid>https://ykyi.net/?p=833/</guid>
      <description>&lt;p&gt;Qt Quick是一种设计用户界面的新方法。&lt;/p&gt;
&lt;p&gt;在介绍Qt Quick之前，让我们先看一下现念的用户界面UI是什么样的。在桌面操作系统下，标准的按钮，文本框，窗体仍然能满足要求。但是这些千篇一律的灰色单调的控件渐渐让用户感到厌倦了。用户们更想看到平滑观感的，光泽的，动态的的用户界面。Qt Quick就是为了实现这些的目标。&lt;/p&gt;
&lt;p&gt;Qt Quick包括两个部分。第一部分是QtDeclarative模块。这个模块负责把Qt Quick集成到Qt应用程序中。第二部分是一种界面描述语言：QML。使用QtDeclarative使得开发者能够在C++和QML之间共享数据对象，也可以把C++类插入到QML之中，等等。QML是个全新的语言，专门为设计用户界面设计，在其它的开发中也有用武之地。&lt;/p&gt;
&lt;p&gt;迫不及待了吧。让我们看一个简单的例子：&lt;/p&gt;
&lt;p&gt;import Qt 4.6&lt;/p&gt;
&lt;p&gt;Rectangle {&lt;br&gt;
width: 200&lt;br&gt;
height: 200&lt;/p&gt;
&lt;p&gt;Text {&lt;br&gt;
text: &amp;ldquo;hello! ykyi.net&amp;rdquo;&lt;br&gt;
font.pointSize: 10&lt;br&gt;
font.bold: true&lt;/p&gt;
&lt;p&gt;anchors.centerIn: parent&lt;br&gt;
}&lt;br&gt;
}&lt;/p&gt;
&lt;p&gt;读完这断代码，再尝试在Qt Creator中运行它。不用我多费口舌，你就恍然大悟了。每一个以大写字母开头的单词定义了一个新的对象。最外面的矩形则是主窗体，可以给它设置属性。比如anchors属性把Text限定在窗体的中央。这样，即使窗体放大了，文本仍然显示在窗体正中央。&lt;/p&gt;
&lt;p&gt;前文，我有说过平滑观感的，光泽的，动态的的用户界面。那么Qt Quick怎么做到呢？简单！看看下面的代码，编辑Text的属性，设置rotation:NumberAnimation。不可思议的事情就发生了！&lt;/p&gt;
&lt;p&gt;rotation: NumberAnimation {&lt;br&gt;
to: 360;&lt;br&gt;
duration: 1500;&lt;br&gt;
running: true;&lt;br&gt;
repeat: true;&lt;br&gt;
}&lt;/p&gt;
&lt;p&gt;现在，指定的文本疯狂的转动起来。我们已经看到在Qt Quick中开发有物资的界面是多么简单。我们所展示的只是Qt Quick特效的凤毛一角，最终能创造出什么样的奇幻效果只受限于你的想象力。&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>Barebox介绍</title>
      <link>https://ykyi.net/?p=831/</link>
      <pubDate>Mon, 02 Jul 2012 12:39:14 +0000</pubDate>
      <guid>https://ykyi.net/?p=831/</guid>
      <description>&lt;p&gt;从裸机上电开始启动计算机的过程听起来是相当复杂的。在PC的世界里，BIOS统治这个领域已经几十年了。不过，哲学上讲任何世界都是从出生，到繁荣，再后到死亡的过程。BIOS的寿命也即将迎来终结。BIOS的掘墓者即是EFI。对于MAC用户来说，EFI的使用已经有好长一段时间了。而在嵌入式Linux的世界里，u-boot则在长时间里扮演着老大哥的角色。&lt;/p&gt;
&lt;p&gt;U-boot，或者来自DENX的das U-boot提供了非常丰富的功能。如：网络，脚本，支持FLASH(这里的flash是存储方面的flash，而不是adobe的那个flash)。一般的嵌入式系统工程序师需要的工具，都提供好了。&lt;/p&gt;
&lt;p&gt;还是那句话，对于万事万物，都是生生死死的过程啊。u-boot的功能越来越强大。催生了新的事物的诞生。它的名字就是：Barebox。&lt;/p&gt;
&lt;p&gt;Barebox最开始被称之为：u-boot-v2，它是一个像u-boot一样野心勃勃的bootloader。不过Barebox更有Linux的味道一些。它的发展抛弃了u-boot而越来越像Linux。它有文件系统，有基本的shell，甚至还有与Linux近似的驱动模块。&lt;/p&gt;
&lt;p&gt;Barebox的另一个创新即是，bootloader可以被构建成一个用户空间的应用程序。这样的好处是显而易近的，你可以更方便的开方和调试Barebox。&lt;/p&gt;
&lt;p&gt;说了这么多，看看Barebox是个什么样子呢？&lt;/p&gt;
&lt;p&gt;uboot:/&lt;/p&gt;
&lt;p&gt;uboot:/ ls&lt;br&gt;
. .. dev env&lt;br&gt;
 &lt;/p&gt;
&lt;p&gt;和Linux一样，dev目录夹下面放了系统的设备文件。比如，mem设备文件描述了计算机的内存。&lt;/p&gt;
&lt;p&gt;再回到u-boot，它有一个特殊的命令：md。md命令可以查看内存的内容。对于Barebox，提供了同样的工具。不过这个工具是以一种POSIX的方式实现的：打开/dev/mem设备，lseek移动文件指针，read读出文件内容。这样的实现方式不仅仅提升了代码结构，它还使得md命令可以不需修改就应用到其它设备上，比如flash存诸器。&lt;/p&gt;
&lt;p&gt;如果你想测试一下Barebox到底如何。你可以有两种方法。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一：你可以下载Barebox的沙盒功能即把它构建成一个Linux的用户空间的应用。来自Barebox官方的解释是：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sandbox:&lt;br&gt;
If you develop features for Barebox, you can use the &amp;lsquo;sandbox&amp;rsquo; target which compiles Barebox as a POSIX application in the Linux userspace: it can be started like a normal command and even has network access (tun/tap). Files from the local filesytem can be used to simulate devices.   如果你要为Barebox开发功能，你可以使用&amp;rsquo;沙盒&amp;rsquo;。这种方式把Barebox构建成一个Linux的用户空间程序。它像一般的命令一样，而且还有网络功能。来自文件系统的文件可以被用来模拟设备。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第二：不说你也知道，把Barebox安装到真真正正的硬件上吧！对于我，我就尝试过在PC机的一块旧式的主板上安装Barebox。 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后，Barebox的官方网站是： &lt;a href=&#34;http://barebox.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;a href=&#34;http://barebox.org/&#34;&gt;http://barebox.org/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux如何设置IPv6地址</title>
      <link>https://ykyi.net/?p=824/</link>
      <pubDate>Sun, 01 Jul 2012 08:46:32 +0000</pubDate>
      <guid>https://ykyi.net/?p=824/</guid>
      <description>&lt;p&gt;IPv6最终全面取待IPv6是不可逆的潮流。本文则讲一下在Linux下如何配置IPv6地址。当然本文假设你使用静态IP（不必是公共IPv6地址或公共IPv4地址，可以是私有IPv4地址）。本文不适用使用DHCP获取地址的情况。&lt;/p&gt;
&lt;p&gt;首先，你要确保你使用的Linux的内核已经支持IPv6。当前比较新的Linux都已经内建IPv6了。&lt;/p&gt;
&lt;p&gt;用root用户登录，运行：&lt;/p&gt;
&lt;p&gt;# lsmod | grep ipv6&lt;/p&gt;
&lt;p&gt;看看系统有没有已经加载了IPv6模块。如果没有，尝试用以下命令加载： &lt;/p&gt;
&lt;p&gt;# /sbin/modprobe ipv6&lt;/p&gt;
&lt;p&gt;第二，你需要有你的静态IP地址。&lt;/p&gt;
&lt;p&gt;**IPv4地址如何转成IPv6地址呢？**如果你的IP是一个IPv4地址，那么可以换算得到IPv6的地址形式。比较简单的作法可以去到 &lt;a href=&#34;http://grox.net/utils/ipv6.php&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;a href=&#34;http://grox.net/utils/ipv6.php&#34;&gt;http://grox.net/utils/ipv6.php&lt;/a&gt;&lt;/a&gt;。在左边的下拉列表中选择: IPv4 to 6to4 Address，在右边的编辑框中填上你的IPv4地址。点击: Calculate 则得到了你的IPv4地址的IPv6转化格式。&lt;/p&gt;
&lt;h2 id=&#34;配置ipv6地址&#34;&gt;配置IPv6地址&lt;/h2&gt;
&lt;p&gt;一般的Linux发行版用 /etc/network/interfaces 文件配置网卡。如果没有这个文件，那么请注意 /etc/network 目录下其它文件或者目录。&lt;/p&gt;
&lt;p&gt;假如要配置的Linux的静态IPv4地址是 192.168.1.10，这个IPv4地址转换成对应的IPv6地址则是 2002:c0a8:10a:: 。再提醒一下，上文提到过如何把IPv4地址转成IPv6地址。&lt;/p&gt;
&lt;p&gt;网关的IPv4地址是 192.168.1.1，这个IPv4地址转成对应的IPv6的地址是:2002:c0a8:0101:: 。&lt;/p&gt;
&lt;p&gt;那么 /etc/network/interfaces 文件应该配置成如下：&lt;/p&gt;
&lt;p&gt;#IPV6 static configuration(我是注释)&lt;br&gt;
iface eth0 inet6 static&lt;br&gt;
pre-up modprobe ipv6&lt;br&gt;
address 2002:c0a8:10a::&lt;br&gt;
netmask 64&lt;br&gt;
gateway 2002:c0a8:0101::&lt;/p&gt;
&lt;p&gt;注意 &amp;ldquo;pre-up&amp;rdquo; 命令。这一行保证系统在启动的时候加载支持ipv6的模块。&lt;br&gt;
最后重新启发动网络，如下：&lt;/p&gt;
&lt;p&gt;# /etc/init.d/networking restart&lt;/p&gt;
&lt;p&gt;你现在可以使用你的IPv6地址了。&lt;/p&gt;
&lt;h2 id=&#34;测试ipv6地址&#34;&gt;测试IPv6地址：&lt;/h2&gt;
&lt;p&gt;检测路由：&lt;/p&gt;
&lt;p&gt;# ip -6 route show&lt;/p&gt;
&lt;p&gt;如果IPv6工作正常的话，应该会有如下的提示。&lt;/p&gt;
&lt;p&gt;2002:c0a8:0100/64 dev eth0 proto kernel scope link src 2002:c0a8:10a&lt;/p&gt;</description>
    </item>
    <item>
      <title>X86平台的中断和异常</title>
      <link>https://ykyi.net/?p=821/</link>
      <pubDate>Sat, 30 Jun 2012 04:42:06 +0000</pubDate>
      <guid>https://ykyi.net/?p=821/</guid>
      <description>&lt;p&gt;英特尔的官方文档如下定义x86平台下的中断和异常：&lt;/p&gt;
&lt;h2 id=&#34;中断&#34;&gt;中断：&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;可屏弊中断(Maskable Interrupts)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;            所有由I/O设备发出的IRQ(Interupt Requests)都是可屏弊中断。可屏弊中断可以有两个状态：屏弊和未屏弊。屏弊状态的中断会被中断控制硬件忽略。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不可屏弊中断(Nonmaskable Interrupts)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;           只有一些关键的事件（如硬件失败）会发出不可屏弊中断。不可屏弊中断总是可以被CPU识别到。&lt;/p&gt;
&lt;h2 id=&#34;heading&#34;&gt; &lt;/h2&gt;
&lt;h2 id=&#34;异常&#34;&gt;异常：&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;处理器可侦测异常(Processor-detected Exceptions)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;           CPU执行指令时侦测到不正常的状态(anomalous condition)时产生这个异常。这种异常又根据存在内核栈上的EIP寄存器的值被划分为三组。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;错误(Faults)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;           发生错误时，一般情况下可以被纠正。纠正以后，程序继续运行，不会损失连续性。保存下的EIP寄存器的值就是产生这个错误的指令，当异常处理句柄（exception handler）结束后，程序从这条指令继续运行。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;陷入(Traps)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;          当被中止的指令无需重新执行时就产生陷入，这点与错误(Faults)不同。陷入主要被用来实现调试器。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;中止(Aborts)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;           严重出错。控制硬件出现故障，此时不可能把造成异常的指令精确地址存入EIP寄存器。Aborts被用来报告严重的出错，比如硬件出错或者无效的，不一致的系统表结构。由控制硬件单元发出的中断信号被用来把控制权转交给中止异常句柄(Abort Exception Handler)。句柄通常只有强制结束造成Abort的程序。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可编程异常(Programmed Exceptions)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;          这是由程序员发出的。程序员可以用int 或者int 3指令发出可编程异常。Into(检查溢出)bound(检查数组越界)指令也可以用来发出可编程异常。可编程异常常常被称之为软中断(software interrupts)。这种异常通常用来实现系统调用，还被用来在调试器中报告事件。(into和bound指令在IA64体系中已经被废弃了，见另一篇博文：&lt;a href=&#34;http://ykyi.net/2012/06/c%E8%AF%AD%E8%A8%80%E5%92%8C%E5%AE%83%E7%9A%84%E5%AE%89%E5%85%A8%E6%80%A7/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;C语言和它的安全性&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>中山大学离散数学考试试题</title>
      <link>https://ykyi.net/?p=815/</link>
      <pubDate>Fri, 29 Jun 2012 05:39:07 +0000</pubDate>
      <guid>https://ykyi.net/?p=815/</guid>
      <description>&lt;h3 id=&#34;离散数学期末试题a卷&#34;&gt;&lt;strong&gt;《离散数学》期末试题(A卷)&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt;ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(考试形式:闭卷  考试时间:2小时)&lt;/p&gt;
&lt;p&gt;《中山大学授予学士学位工作细则》第六条&lt;/p&gt;
&lt;p&gt;考试作弊不授予学士学位&lt;/p&gt;
&lt;p&gt;方向：                       姓名：                   学号：            &lt;/p&gt;
&lt;p&gt;出卷：                      复核：            &lt;/p&gt;
&lt;p style=&#34;margin-left:13.2500pt;&#34;&gt;
  1.&amp;nbsp;(10&amp;nbsp;points)&amp;nbsp;&amp;nbsp;A,&amp;nbsp;B&amp;nbsp;and&amp;nbsp;C&amp;nbsp;are&amp;nbsp;sets,&amp;nbsp;prove&amp;nbsp;or&amp;nbsp;disprove&amp;nbsp;the&amp;nbsp;following&amp;nbsp;statements.
&lt;/p&gt;
&lt;p style=&#34;margin-left:10.5000pt;&#34;&gt;
  (1).&amp;nbsp;if&amp;nbsp;A&amp;nbsp;&amp;ndash;&amp;nbsp;B&amp;nbsp;=&amp;nbsp;A&amp;nbsp;&amp;ndash;&amp;nbsp;C,&amp;nbsp;then&amp;nbsp;B&amp;nbsp;=&amp;nbsp;C
&lt;/p&gt;
&lt;p style=&#34;margin-left:10.5000pt;&#34;&gt;
  (2).&amp;nbsp;if&amp;nbsp;A&amp;nbsp;&amp;acute;&amp;nbsp;B&amp;nbsp;=&amp;nbsp;A&amp;nbsp;&amp;acute;&amp;nbsp;C,&amp;nbsp;A&amp;nbsp;&amp;sup1;&amp;nbsp;&amp;AElig;,&amp;nbsp;then&amp;nbsp;B&amp;nbsp;=&amp;nbsp;C
&lt;/p&gt;
&lt;p style=&#34;margin-left:13.2500pt;&#34;&gt;
  2.&amp;nbsp;(10&amp;nbsp;points)&amp;nbsp;&amp;nbsp;Write&amp;nbsp;each&amp;nbsp;of&amp;nbsp;the&amp;nbsp;following&amp;nbsp;statements&amp;nbsp;in&amp;nbsp;terms&amp;nbsp;of&amp;nbsp;propositional&amp;nbsp;variables,&amp;nbsp;predicates,&amp;nbsp;quantifiers&amp;nbsp;and&amp;nbsp;logical&amp;nbsp;connectives.&amp;nbsp;You&amp;nbsp;can&amp;nbsp;choose&amp;nbsp;any&amp;nbsp;propositional&amp;nbsp;variables&amp;nbsp;and&amp;nbsp;predicates&amp;nbsp;freely.
&lt;/p&gt;
&lt;p style=&#34;margin-left:10.5000pt;&#34;&gt;
  (1).&amp;nbsp;If&amp;nbsp;I&amp;nbsp;like&amp;nbsp;the&amp;nbsp;course&amp;nbsp;or&amp;nbsp;the&amp;nbsp;teacher,&amp;nbsp;I&amp;nbsp;will&amp;nbsp;attend&amp;nbsp;the&amp;nbsp;class. (statement&amp;nbsp;and&amp;nbsp;its&amp;nbsp;negation)
&lt;/p&gt;
&lt;p style=&#34;margin-left:10.5000pt;&#34;&gt;
  (2).&amp;nbsp;For&amp;nbsp;all&amp;nbsp;students&amp;nbsp;of&amp;nbsp;our&amp;nbsp;school,&amp;nbsp;someone&amp;nbsp;studies&amp;nbsp;hard&amp;nbsp;and&amp;nbsp;has&amp;nbsp;good&amp;nbsp;score,&amp;nbsp;someone&amp;nbsp;studies&amp;nbsp;hard&amp;nbsp;and&amp;nbsp;does&amp;nbsp;not&amp;nbsp;have&amp;nbsp;good&amp;nbsp;score.
&lt;/p&gt;
&lt;p style=&#34;margin-left:10.5000pt;&#34;&gt;
  Note:&amp;nbsp;The&amp;nbsp;first&amp;nbsp;question&amp;nbsp;is&amp;nbsp;expressed&amp;nbsp;in&amp;nbsp;propositional&amp;nbsp;logic,&amp;nbsp;the&amp;nbsp;second&amp;nbsp;is&amp;nbsp;expressed&amp;nbsp;in&amp;nbsp;predicate&amp;nbsp;logic.
&lt;/p&gt;
&lt;p style=&#34;margin-left:13.2500pt;&#34;&gt;
  3.&amp;nbsp;(15&amp;nbsp;points)&amp;nbsp;Let&amp;nbsp;A={a,b,c,d,e},&amp;nbsp;a&amp;nbsp;relation&amp;nbsp;R&amp;nbsp;on&amp;nbsp;A&amp;nbsp;is&amp;nbsp;{(a,b),&amp;nbsp;(b,b),&amp;nbsp;(b,c),&amp;nbsp;(b,d),&amp;nbsp;(c,d),&amp;nbsp;(d,d),&amp;nbsp;(d,e),&amp;nbsp;(e,d)}.
&lt;/p&gt;
&lt;p style=&#34;margin-left:10.5000pt;&#34;&gt;
  (1)&amp;nbsp;Give&amp;nbsp;the&amp;nbsp;digraph&amp;nbsp;and&amp;nbsp;matrix&amp;nbsp;of&amp;nbsp;relation&amp;nbsp;R;
&lt;/p&gt;
&lt;p style=&#34;margin-left:10.5000pt;&#34;&gt;
  (2)&amp;nbsp;Compute&amp;nbsp;R2,&amp;nbsp;reflexive&amp;nbsp;closure&amp;nbsp;r(R)&amp;nbsp;and&amp;nbsp;symmetric&amp;nbsp;closure&amp;nbsp;s(R).
&lt;/p&gt;
&lt;p style=&#34;margin-left:13.2500pt;&#34;&gt;
  4.&amp;nbsp;(15&amp;nbsp;points)&amp;nbsp;Let&amp;nbsp;S&amp;Icirc;Z+&amp;nbsp;and&amp;nbsp;A=S&amp;times;S.&amp;nbsp;Define&amp;nbsp;the&amp;nbsp;following&amp;nbsp;relation&amp;nbsp;R&amp;nbsp;on&amp;nbsp;A:
&lt;/p&gt;
&lt;p style=&#34;margin-left:13.2000pt;&#34;&gt;
  (a,b)&amp;nbsp;R&amp;nbsp;(a&amp;prime;,b&amp;prime;)&amp;nbsp;if&amp;nbsp;and&amp;nbsp;only&amp;nbsp;if&amp;nbsp;ab&amp;prime;=a&amp;prime;b
&lt;/p&gt;
&lt;p style=&#34;margin-left:10.5000pt;&#34;&gt;
  (1)&amp;nbsp;Show&amp;nbsp;that&amp;nbsp;R&amp;nbsp;is&amp;nbsp;an&amp;nbsp;equivalent&amp;nbsp;relation;
&lt;/p&gt;
&lt;p style=&#34;margin-left:10.5000pt;&#34;&gt;
  (2)&amp;nbsp;Let&amp;nbsp;S={1,2,3,4,5,6,7,8,9},&amp;nbsp;compute&amp;nbsp;the&amp;nbsp;equivalent&amp;nbsp;class&amp;nbsp;[(2,4)].
&lt;/p&gt;
&lt;p&gt;5. (10 points) Let function f(x, y)=( x+3y, 2x+y), (x, y)ÎR×R, prove that f is bijection.&lt;/p&gt;
&lt;p&gt;6. (15 points) Let A={2, 4, 5, 6, 8, 10, 12, 20, 120}, R is the relation of divisibility on A.&lt;/p&gt;
&lt;p style=&#34;margin-left:10.5000pt;&#34;&gt;
  (1)&amp;nbsp;Draw&amp;nbsp;the&amp;nbsp;Hasse&amp;nbsp;diagram&amp;nbsp;of&amp;nbsp;the&amp;nbsp;poset&amp;nbsp;&lt;A,&amp;nbsp;R&gt;;
&lt;/p&gt;
&lt;p style=&#34;margin-left:10.5000pt;&#34;&gt;
  (2)&amp;nbsp;Find&amp;nbsp;all&amp;nbsp;the&amp;nbsp;minimal&amp;nbsp;elements,&amp;nbsp;the&amp;nbsp;maximal&amp;nbsp;elements,&amp;nbsp;the&amp;nbsp;least&amp;nbsp;element&amp;nbsp;and&amp;nbsp;the&amp;nbsp;greatest&amp;nbsp;element&amp;nbsp;of&amp;nbsp;the&amp;nbsp;poset&amp;nbsp;&lt;A,&amp;nbsp;R&gt;&amp;nbsp;if&amp;nbsp;they&amp;nbsp;exist;
&lt;/p&gt;
&lt;p style=&#34;margin-left:10.5000pt;&#34;&gt;
  (3)&amp;nbsp;Let&amp;nbsp;B&amp;nbsp;=&amp;nbsp;{2,&amp;nbsp;4,&amp;nbsp;6},&amp;nbsp;find&amp;nbsp;the&amp;nbsp;upper&amp;nbsp;bound,&amp;nbsp;the&amp;nbsp;lower&amp;nbsp;bound,&amp;nbsp;the&amp;nbsp;least&amp;nbsp;upper&amp;nbsp;bound&amp;nbsp;and&amp;nbsp;the&amp;nbsp;greatest&amp;nbsp;lower&amp;nbsp;bound&amp;nbsp;of&amp;nbsp;B&amp;nbsp;if&amp;nbsp;they&amp;nbsp;exist.
&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p style=&#34;margin-left:13.2500pt;&#34;&gt;
  7.&amp;nbsp;(15&amp;nbsp;points)&amp;nbsp;Use&amp;nbsp;the&amp;nbsp;labeling&amp;nbsp;algorithm&amp;nbsp;(Ford-Fulkerson&amp;rsquo;s)&amp;nbsp;to&amp;nbsp;find&amp;nbsp;a&amp;nbsp;maximum&amp;nbsp;flow&amp;nbsp;for&amp;nbsp;the&amp;nbsp;following&amp;nbsp;transport&amp;nbsp;network&amp;nbsp;in&amp;nbsp;Fig.&amp;nbsp;1.&amp;nbsp;Use&amp;nbsp;of&amp;nbsp;figures&amp;nbsp;is&amp;nbsp;required&amp;nbsp;to&amp;nbsp;show&amp;nbsp;the&amp;nbsp;variety&amp;nbsp;of&amp;nbsp;flows&amp;nbsp;during&amp;nbsp;the&amp;nbsp;procedure.
&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;img decoding=&#34;async&#34; alt=&#34;labeling algorithm (Ford-Fulkerson’s) to find a maximum flow for the following transport network&#34; src=&#34;https://ykyi.net/imgs/discrete_math/Ford-Fulkerson.jpg&#34; /&gt; 
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>什么是MediaWiki的Gadget(小部件)</title>
      <link>https://ykyi.net/?p=812/</link>
      <pubDate>Thu, 28 Jun 2012 02:52:41 +0000</pubDate>
      <guid>https://ykyi.net/?p=812/</guid>
      <description>&lt;p&gt; &lt;/p&gt;
&lt;div&gt;
  &lt;p&gt;
    译自MediaWiki的官网，URL：&amp;nbsp;&lt;a href=&#34;http://www.mediawiki.org/wiki/Extension:Gadgets&#34;&gt;http://www.mediawiki.org/wiki/Extension:Gadgets&lt;/a&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;Gadget简介：&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    MediaWiki，为用户提供了一种方法，使用户方便使用其它用户基于Javascript或者CSS创建的小部件Gadget.
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    Gadget是由Javascript或者CSS代码片断组成的，被放置在MediaWiki名字空间里(对于MediaWiki的名字空间的概念请参看其它文章)。每一个Gadget都在MediaWiki:Gadgets-definition中占用一行，用来定义这个gadget。定义包括这个Gadget的名字，和描述以及组成这个Gadget的Javascript和CSS代码。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    因为Gadget被放置在MediaWiki名字空间里，只有系统管理员可以编辑Gadget。这很容易理解：只有充分被信任的用户才可以编辑被其它更多用户使用的Javascript代码。Javascript代码是把双刃剑，如果被用来做坏事，会很容易被用来实现劫持账号或者监视用户的功能。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;下载Gadget：&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    从https://gerrit.wikimedia.org/r/gitweb?p=mediawiki/extensions/Gadgets.git;a=tree&amp;nbsp;可以下载到Gadget，或者也可以用git工具clone一份gadget，如下：
  &lt;/p&gt;
  &lt;p&gt;
    git&amp;nbsp;clone&amp;nbsp;https://gerrit.wikimedia.org/r/p/mediawiki/extensions/Gadgets.git
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;如何安装：&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    把Gadget目录复制到你安装MediaWiki的扩展目录(Extensions&amp;nbsp;Folder)。然后在localSetting.php文件中，接近文件末尾的地方加上一行：
  &lt;/p&gt;
  &lt;p&gt;
    require_once(&amp;nbsp;&#34;$IP/extensions/Gadgets/Gadgets.php&#34;&amp;nbsp;);
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;使用Gadget:&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    可以使用的Gadget定义在MediaWiki:Gadgets-definion。只要有一个有效的Gadget在MediaWiki:Gadgets-define被定义，就能在每个用户的Special:Preference的Gadgets节选择是否启用这个Gadget(小部件)。在Special:Gadgets也能浏览Gadgets的列表，并有链接指向各自的系统消息(System&amp;nbsp;Message)，以方便编辑。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;定义Gadget的格式：&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    在MediaWiki:Gadgets-definition中的每个Gadget的定义都以一个或者多个&#34;*&#34;开始，必须符合下面的格式定义。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;*&amp;nbsp;Gadget的名字&amp;nbsp;[&amp;nbsp;选项(可以忽略)&amp;nbsp;]&amp;nbsp;|&amp;nbsp;页名字
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;(*&amp;nbsp;gadget_name&amp;nbsp;[options&amp;nbsp;(can&amp;nbsp;be&amp;nbsp;omitted)]&amp;nbsp;|&amp;nbsp;page&amp;nbsp;names)
  &lt;/p&gt;
  &lt;p&gt;
    第一个域，Gadget的名字指的是gadget的内部名字。这隐含了一个系统消息的引用(System&amp;nbsp;Message)。此例中，如果你定义了内部名为&amp;nbsp;my_gadget_name&amp;nbsp;这样一个gadget，则在MediaWiki:Gadget-my_gadget_name有一个使用wiki语法的关于这个gadget的简短描述。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    注意，gadget的内部命令规则：必须以字母起头，后面可以接26个字母的大小写或者数字，以及连字符&amp;ldquo;-&amp;rdquo;，下划线&amp;ldquo;_&amp;rdquo;，冒号&amp;ldquo;:&amp;rdquo;，点号&amp;ldquo;.&amp;rdquo;。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;选项的格式：&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    [option1&amp;nbsp;|&amp;nbsp;option2&amp;nbsp;|&amp;nbsp;&amp;#8230;&amp;nbsp;optionN]
  &lt;/p&gt;
  &lt;p&gt;
    空格将被忽略。每一个选项可以包括一个选项名，或者选项名还能被赋值，这些值以逗号隔开。如：&amp;nbsp;option&amp;nbsp;=&amp;nbsp;value1,&amp;nbsp;value2,&amp;nbsp;value3
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    举一些Gadget定义的例子：
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;*&amp;nbsp;mygadget|mygadget.js|mygadget.css
  &lt;/p&gt;
  &lt;p&gt;
    or
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;*&amp;nbsp;mygadget[ResourceLoader]|mygadget.js|mygadget.css
  &lt;/p&gt;
  &lt;p&gt;
    or
  &lt;/p&gt;
  &lt;p&gt;
    *&amp;nbsp;mygadget[rights=foo,bar]|mygadget.js|mygadget.css
  &lt;/p&gt;
  &lt;p&gt;
    or
  &lt;/p&gt;
  &lt;p&gt;
    *&amp;nbsp;mygadget[&amp;nbsp;ResourceLoader&amp;nbsp;|&amp;nbsp;rights=foo,&amp;nbsp;bar&amp;nbsp;]&amp;nbsp;|&amp;nbsp;mygadget.js&amp;nbsp;|&amp;nbsp;mygadget.css
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;选项的说明:&lt;/strong&gt;
  &lt;/p&gt;
  &lt;table&gt;
    &lt;tr&gt;
      &lt;td style=&#34;width:68px;&#34;&gt;
        &lt;p&gt;
          选项名
        &lt;/p&gt;
      &lt;/td&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;td style=&amp;quot;width:150px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      参数
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td style=&amp;quot;width:359px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      描述
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;

&amp;lt;tr&amp;gt;
  &amp;lt;td style=&amp;quot;width:68px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      ResourceLoader
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td style=&amp;quot;width:150px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      None
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td style=&amp;quot;width:359px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      注明Gadget与ResourceLoader兼容。
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;

&amp;lt;tr&amp;gt;
  &amp;lt;td style=&amp;quot;width:68px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      dependencies
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td style=&amp;quot;width:150px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      用逗号分隔开的ResourceLoader模块名
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td style=&amp;quot;width:359px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      这里有&amp;lt;a href=&amp;quot;http://www.mediawiki.org/wiki/ResourceLoader/Default_modules&amp;quot;&amp;gt;默认依赖的模块列表&amp;lt;/a&amp;gt;.如果当前的gadget没有与ResourceLoader兼容的资源，这个选项将失效。
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;

&amp;lt;tr&amp;gt;
  &amp;lt;td style=&amp;quot;width:68px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      rights
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td style=&amp;quot;width:150px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      用逗号分隔开的权限名
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td style=&amp;quot;width:359px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      权限名列表在这里&amp;amp;nbsp;&amp;lt;a href=&amp;quot;http://www.mediawiki.org/wiki/Manual:User_rights#List_of_permissions&amp;quot;&amp;gt;privileges&amp;lt;/a&amp;gt;.
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;

&amp;lt;tr&amp;gt;
  &amp;lt;td style=&amp;quot;width:68px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      skins
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td style=&amp;quot;width:150px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      用逗号分隔开的皮肤名
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td style=&amp;quot;width:359px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      皮肤名列表在这里&amp;amp;nbsp;&amp;lt;a href=&amp;quot;http://www.mediawiki.org/wiki/Manual:Skins&amp;quot;&amp;gt;skins&amp;lt;/a&amp;gt;.
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;

&amp;lt;tr&amp;gt;
  &amp;lt;td style=&amp;quot;width:68px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      default
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td style=&amp;quot;width:150px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      无
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
  
  &amp;lt;td style=&amp;quot;width:359px;&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;
      注明对每个用户，包括匿名用名默认启用的gadget。不过注册用户仍然可以在它们的使用偏好设定中禁用gadget.
    &amp;lt;/p&amp;gt;
  &amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/table&gt;
  &lt;p&gt;
    你可以为你的gadget指定额外的依赖，如：
  &lt;/p&gt;</description>
    </item>
    <item>
      <title>显卡信息检测利器，GPU Caps Viewer介绍</title>
      <link>https://ykyi.net/?p=808/</link>
      <pubDate>Tue, 26 Jun 2012 23:22:05 +0000</pubDate>
      <guid>https://ykyi.net/?p=808/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;text-align: justify; &#34;&gt;怎么知道我的显示是不是支持OpenCL？GPU Caps Viewer可以告诉你答案。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class=&#34;KonaBody&#34;&gt;
  &lt;div class=&#34;desch2&#34;&gt;
    &lt;div&gt;
      &amp;nbsp;
    &lt;/div&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div&amp;gt;
  &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;GPU Caps Viewer是一款让监控你的显卡工作情况的好工具。&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;比如，如果你是一个骨灰级游戏玩家，或一个WEB开发者，需要一款图形显示卡方面的应用软件，那么GPU Caps Viewer是你的最佳选择。&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;GPU Caps Viewer的操作界面非常直观。你可以方便地查看你的GPU的各种信息，包括：光影核心(Shader Core),BIOS,设备ID号，次设备ID号，GPU的温度，当前和最大时钟，GPU的负载，显卡的驱动程序，OpenGL, OpenCL，CUDA，PhySX，并且支持多GPU。&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;你还可以启动一个OpenGL或者OpenCL的演示程序，查看OpenGL的版本号和它的扩展链表，CUDA设备的数目,核心数据 &amp;amp;#8212; 如名字，计算力，光影时钟，多处理器，变形和网格尺寸(warp and grid size)等等。&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;还可以查看更多的内容。你可以查看到显卡的OpenCL信息，如版本号，CL设备的数目，CL设备的类型，计算单元，时钟，驱动程序，全局和局部内存，2D和3D图象的尺寸，工作项目的尺寸(work item size)，常量缓冲区，最大采样器，扩展，工作组的尺寸，等等。&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;另外，还能查看到系统信息。如CPU的名字，CPU的型号，CPU的核心，使用了什么操作系统，内存的信息，显示模式等等。界面上有各种链接导向相应的网页以供查看更详细的信息。界面上的大部分信息可以被导出到txt或者xml文件。&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;需要注意的是，GPU Caps Viewer运行时使用非常多的系统资源，而且软件作者也没有提供一个帮助文档。面对满界面的专业术语，GPU Caps Viewer软件的定位应该是高级用户。该软件可以在各大下载论坛下载到。&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;本文一开始的问题&amp;amp;ldquo;&amp;lt;strong&amp;gt;如何知道显卡是否支持OpenCL&amp;lt;/strong&amp;gt;&amp;amp;rdquo;则可以在OpenCL标签项中得到答案。如果显示卡不支持OpenCL,则不会有关于这块显卡OpenCL方面的信息，当然也不能运行OpenCL的演示程序(Demo)。&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;copyright ykyi.net&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/p&amp;gt;&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>ThreadX简介</title>
      <link>https://ykyi.net/?p=806/</link>
      <pubDate>Tue, 26 Jun 2012 06:49:21 +0000</pubDate>
      <guid>https://ykyi.net/?p=806/</guid>
      <description>&lt;p&gt; &lt;/p&gt;
&lt;div&gt;
  ThreadX是由在美国加利费尼亚州，圣地亚戈的Express Logic有限责任公司开发并注册商标。它是一个实时操作系统，类似于VxWorks, Nucleus RTOS, OSE, QNX, LynxOS这些实时操作系统。ThreadX的作者是William Lamie，它是Express Logic有限公司的董事长兼CEO。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  为什么ThreadX取这样一个名字呢？ThreadX的这个名字缘于线程(Thread)是被操作系统调度的单位，字母X就表示切换线程。ThreadX可以被看成是SystemC的QThreads的抢先式实现。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  与大多数实时操作系统一样，ThreadX的内核是多任务抢先式内核，支持快速响应中断，内存管理，线程通讯，互斥，事件，线程同步等特性。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  ThreadX的一些独有的特性有：优先级继承，抢先阀值，高效定时器，pico内核设计，事件链，高速软定时器，以及精致的内核尺寸。ThreadX是开源发布的，并且使用ThreadX不需要任何授权费用。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  ThreadX常常被使用在实时嵌入式操作系统中，特别是嵌入程度很大的嵌入式系统(Deeply embedded system)。ThreadX的开发通常都在运行Linux或者windows操作系统的机器上用交叉编译环境开发。交叉编译工具可以生成在目标平台上运行的二进制代码。已经有很多可以用来开发ThreadX的开发工具，比如：Wind River Workbench, ARM RealView, Green Hills Software&#39;s MULTI, Metrowerks CodeWarrior, IAR C-SPY,Lauterbach TRACE32, 和visionCLICK
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  最近，Hewlett-Packard已经被授权可以使用ThreadX开发喷墨打印机，激光打印机，一体化设备。早些时候，开发多功能激光打印机使用lynxOS操作系统，目前仍然有很多打印机设备设用lynOS。如今，ThreadX已经被广泛使用在很多消费电子设备，医疗设备，datanetworking applications，还有SoC的开发。
&lt;/div&gt;</description>
    </item>
    <item>
      <title>红帽的云计算机解决方案</title>
      <link>https://ykyi.net/?p=803/</link>
      <pubDate>Mon, 25 Jun 2012 03:42:48 +0000</pubDate>
      <guid>https://ykyi.net/?p=803/</guid>
      <description>&lt;p&gt; &lt;/p&gt;
&lt;div&gt;
  Red Hat Cloud
&lt;/div&gt;
&lt;div&gt;
  未来的云计算一定是开放的
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  对于一个公司负责IT的领导层来讲，选择一个正确的云计算机架构是一件极为重要的战略决策。这将影响到你的企业在这个十年的竞争力和灵活性。所以，务必谨慎选择。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  如果这个事做正确了，云计算将帮助你从过去的简单控制资源的配额过渡到真正的革命性变化。但是，只有一个开放的云计算解决方案可以做到。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  只有红帽提供了一个真正的开放云计算解决方案
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  红帽作为开源软件业的引领者，为你提供了构建一个开放去计算解决方案所需要的一切。拥抱全面开放的云计算吧，你的企业才真正认识到什么是云。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  1. 让数据在云之间自由迁移。
&lt;/div&gt;
&lt;div&gt;
  2. 全面利用已有的IT投资和基础设施。
&lt;/div&gt;
&lt;div&gt;
  3. 跨越物理服务器，多种虚拟化平台，以及运行着各种各样不同技术栈的公共云。
&lt;/div&gt;
&lt;div&gt;
  4. 使企业平滑过渡到云时代，在每一个步骤都能获得持续的收益。
&lt;/div&gt;
&lt;div&gt;
  5. 你对选用什么技术有真正的话语权。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  更多的选择：
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  红帽拥用最有活力的生态系统，一大批认证的云计算提供商，硬件提供商，Paas(Platform-as-a-service)中间件的提供商。毫无疑问，红帽是能够给你提供最多最自由选择的云计算平台。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  红帽的开放云让IT公司或者企业的IT部门在经济上容易承受，并使用开放的应用程序编程接口(API)，充许用户自由的迁移到其它的云，使你能够控制和领导你的IT愿景(Let you control and lead your IT vision).
&lt;/div&gt;
&lt;div&gt;
  We can strengthen your open cloud by drawing on more than a decade of experience and technology powering mission-critical infrastructures and applications for the world&#39;s most demanding organizations&amp;mdash;including top public clouds. All while providing the Red Hat service levels and control our customers expect.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>flexcoin全世界第一家Bitcoin銀行</title>
      <link>https://ykyi.net/?p=799/</link>
      <pubDate>Sun, 24 Jun 2012 07:39:58 +0000</pubDate>
      <guid>https://ykyi.net/?p=799/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;Bitcoin是互聯網上一種虛擬貨幣，欲知更多自己搜索下，已經有很多文章介紹了。&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;Flexcoin.com是網路上第一家基於於Bitcoin的銀行。Flexcoin使你可以在全世界所以可以連接到互聯網的地方使用Bitcoin。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;如果你把Bitcoin存到flexcoin.com，你就有了一個賬戶可以轉出以及收款。另外，如果在每月月底你的賬戶中有正數值的余額的話，flexcoin還會給你一部分利息。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;換言之，就如同真實世界中的銀行一樣，只是這裏使用的是Bitcoin，而不是任何政府發行的貨幣。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;Flexcon是整個Bitcoin體系中一個非常重要的部分。我們的技術使我們可以為用戶做到通過用戶名快速轉賬到一個用戶名下，而不是一串奇怪的數字標志的用戶名。如下：&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;Before Flexcoin: 1555hjPG7pRwTHVMfukPvjXexQMHFE3qu6&amp;nbsp;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;After Flexcoin: coffeeshop&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;Flexcoin解決了Bitcoin貨幣體系中一個很大的問題。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;Flexcoin出現前，當別人給你發來Bitcoin，你只有從你初次接收它的設備上操作它。你不能夠，至少不能輕易地通過你的手持設備或者其他什麼設備使用它。一般地講，只有在你初化接收和發送Bitcoin的機器上才能操作Bitcoin。通過使用Flexcoin，你甚至可以把Bitcoin發送到一個電郵地址。Flexcoin的設計使即使不怎麼懂技術的用戶也能夠使用。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;Flexcoin做的工作看起來很簡單，他提供了一個集中的處理你所有Bitcoin財產的地方。Flexcoin就是全世界第一家Bitcoin銀行。你可以通過任何可以使用Web的設備用一個賬號來管理所以屬於你的Bitcoin。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;這樣就使你可以在各種場合各個時間段也能夠發送和接收Bitcoin。只要你有一臺可以用Web方式登錄到Flexcon.com的設備。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;Flexcoin也是整個Bitcoin界的安全引領者。比如，Flexcoin是第一個實現了在電郵件絕不放置URL的機構。從Flexcoin發出的電郵絕對不會有鏈接或者圖象。如果你收到一封違反剛才聲明的電郵，那一定是欺詐郵件。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;Bitcoin的官方網站是 www.bitcoin.com&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  copyright ykyi.net
&lt;/div&gt;</description>
    </item>
    <item>
      <title>MediaWiki入门教程</title>
      <link>https://ykyi.net/?p=795/</link>
      <pubDate>Sat, 23 Jun 2012 13:27:25 +0000</pubDate>
      <guid>https://ykyi.net/?p=795/</guid>
      <description>&lt;p&gt; &lt;/p&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;MediaWiki是这个世界上使用人数最多的百科建站系统。全球最著名的Wikipedia.com就是用MediaWiki建立的。另外，MediaWiki是在GPL协议下免费开源工程，这意味着你可以免费使用它。下面将介绍如何使用MediaWiki.&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;h2 id=&#34;如何安装mediawiki&#34;&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;如何安装MediaWiki？&lt;/span&gt;&lt;/h2&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;从官网下载到MediaWiki的安装包，解压到服务器的根目录下面。然后用你的域名访问网站，就会提示你一步一步安装了。注意最后一个步骤会生成一个LocalSettings.php文件，你需要把这个文件上传到网站的根目录。如果没有把生成的LocalSettings.php放到根目录，下次输入域名访问网站会提示找不到LocalSettings.php。其实整个安装都超级简单！&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;h2 id=&#34;怎么使mediawiki只能够被私人使用&#34;&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;怎么使MediaWiki只能够被私人使用？&lt;/span&gt;&lt;/h2&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;在安装阶段有这个选项配置MediaWiki会被如何使用。如果错过了，可以删除根目录下的LocalSettings.php，再输入域名访问网站重新生成LocalSetting.php。这样有点麻烦，也可以直接编辑LocalSettings。比如:&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;# 禁止未登录用户编辑内容.&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;$wgGroupPermissions[&amp;#8216;*&amp;#8217;][&amp;#8216;edit&amp;#8217;] = false;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;# 禁止用户注册，除非系统管理员创建用户。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;$wgGroupPermissions[&amp;#8216;*&amp;#8217;][&amp;#8216;createaccount&amp;#8217;] = false;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;h2 id=&#34;怎么创建一个页面&#34;&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;怎么创建一个页面？&lt;/span&gt;&lt;/h2&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;在这个例子中，我们会教你创建一个页面。页面的内容就是&#39;如何创建一个页面&#39;。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;在网站的右上角上点击：登录。 然后用你的管理员账号登录。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;在MediaWiki中创建一个页面的方法有点特殊。首先，你在搜索框中输入你将要编辑的词条名字，然后点击搜索。如果词条不存在的话，就会显示一个页面告诉你没有这个词条。在这个页面上会有一个选项提示你创建这个词条。点击&amp;ldquo;创建词条&amp;rdquo;。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;输入以下内容：&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;&amp;nbsp;== Create a page ==&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;* 把词条输入搜索框，然后搜索。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;* 搜索结果显示没有匹配到任何页面，这时有一个选项让你创建一个页面。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;* MediaWiki标志语言(MediaKiki Markup Language也常被称为:wikitext)可以在 http://www.mediawiki.org/wiki/Markup_spec 找到。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;* 各种编辑页面的例子可以在 http://meta.wikimedia.org/wiki/Help:Editing and http://meta.wikimedia.org/wiki/Help:Wikitext_examples 找到。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;点击&#34;预览&#34;按钮，可以看到页面的预览效果。点击&#34;保存页面&#34;，则这个页面被编辑完成了。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;h2 id=&#34;怎么改名一个页面&#34;&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;怎么改名一个页面？&lt;/span&gt;&lt;/h2&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;有时候你想要把一个页面改名。MediaWiki处理改名的逻辑实际上是把这个页面使用新的名字移动到一个新的位置，MediaWiki会记住旧的名字，还会建立一个到新页面的引用。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;在页面的上部找到&#34;移动&#34;标签页，点击!&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;填好新的页面名字，点击&#34;移动页面&#34;按钮。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;系统会让你确认一次，然后改名就完成了。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;h2 id=&#34;怎么改变mediawiki的logo呢&#34;&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;怎么改变MediaWiki的Logo呢？&lt;/span&gt;&lt;/h2&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;常常有人问如何把网站左上方的网站Logo换掉。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;首先你创建一个宽135象素，长135-150象素的logo图象文件。把logo上传到服务器某个位置。默认是放在/skins/common/images/wiki.png。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;编辑LocalSetting.php文件，修改 $wgLogo变量。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;刷新页面，现在你可以看到新的Logo了。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;h2 id=&#34;怎么在页面中建立内部链接internal-links&#34;&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;怎么在页面中建立内部链接(Internal Links)？&lt;/span&gt;&lt;/h2&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;不像标准的HTML语法，在编辑MediaWiki的页面时建立指向内部页面的链接是非常容易的。比如你要建立一个到词条名为&amp;ldquo;我爱香港&amp;rdquo;的内部链接，则在编辑页面时在词条名前加井号。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;如: #我爱香港&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;MediaWiki的内部链接的颜色有两种，一种是红色，一种是绿色。当内部链接的颜色是红色时，表示还没有收录这个词条，如果你点击的话，会提示你建立新词条。如果是绿色，则相反。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;h2 id=&#34;如何改变mediawiki的导航菜单&#34;&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;如何改变MediaWiki的导航菜单？&lt;/span&gt;&lt;/h2&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;比如我想要把我的wiki站点上所有的category都列在导航条上，那我就需要修改导航条。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;在搜索框中输入: Mediawiki:Sidebar。搜索结果会给出导航条的页面。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;选择&amp;ldquo;编辑&amp;rdquo;。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;增加一行以**起头，|符号前面的字符表示导航项将要显示的名字，|后表示页面的名字。&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size:16px;&#34;&gt;最后选择保存页面，完成！&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style=&#34;font-size: 16px; &#34;&gt;copyright ykyi.net&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>It’s a mistake to include Xen in a Linux distro</title>
      <link>https://ykyi.net/?p=788/</link>
      <pubDate>Fri, 22 Jun 2012 13:21:30 +0000</pubDate>
      <guid>https://ykyi.net/?p=788/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;&lt;span style=&#34;font-family: &#39;lucida sans unicode&#39;, &#39;lucida grande&#39;, sans-serif; &#34;&gt;As the title show, it&amp;rsquo;s a mistake to include Xen in a linux distro. Why?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family: &#39;lucida sans unicode&#39;, &#39;lucida grande&#39;, sans-serif; font-size: 16px; &#34;&gt;Somebody would argue that Xen is a very useful technology. Xen does the virtualization work very well and many projects are using Xen which prove Xen is so great.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;&lt;span style=&#34;font-family: &#39;lucida sans unicode&#39;, &#39;lucida grande&#39;, sans-serif; &#34;&gt;I&amp;rsquo;m not mean Xen is not good. However, just because Xen is a hypervisor that is based on another microkernel that is not Linux kernel itself. Linux distros that ship Xen today actually are running an entirely different Operating System kernel that most users even don&amp;rsquo;t notice that. Xen should be a separate, purpose-built kernel, so it should never be a part of the Linux kernel. Isn&amp;rsquo;t it strange that you think you are running a linux OS, but this &amp;rsquo;linux&amp;rsquo; has a kernel that is not linux, which is another kernel. You take away the Linux kernel, how could you say the OS is Linux.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>什麼是敏感指令</title>
      <link>https://ykyi.net/?p=778/</link>
      <pubDate>Thu, 21 Jun 2012 08:20:55 +0000</pubDate>
      <guid>https://ykyi.net/?p=778/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size: 14px; &#34;&gt;1974年，&lt;/span&gt;&lt;span style=&#34;font-size: 14px; &#34;&gt;Popek和Goldberg在美國电脑協會的通訊期刊上發表了一篇論文&amp;quot;虛擬化第三代架構的一般性要求&amp;quot;(Formal Requirements for Virtualizable Third Generation Architectures)。在這篇文章中，提出了敏感指令的概念。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: 14px; &#34;&gt;敏感指令(&lt;/span&gt;&lt;span style=&#34;font-size: 14px; &#34;&gt;Sensitive Instructions&lt;/span&gt;&lt;span style=&#34;font-size: 14px; &#34;&gt;)的定義：&lt;strong&gt; 敏感指令是這樣一組指令，這些指令的行為取決於指令執行時處理器的工作模式，以及指令在記憶體中的位置。&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: 14px;&#34;&gt;&lt;b&gt;——-&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: 14px;&#34;&gt;對敏感指令的處理是虛擬化技術的一個關鍵點。在用戶態執行的敏感指令如果總會造成陷入(always generates a trap)，這樣的敏感指令也屬於特權 指令。在不使用Wmware提出的動態二進制翻譯機制的情況下，除非所有的敏感指令都是特權指令，虛擬機管理程式才能保證正確運行。換言之，如果某種處理器架構的所有的敏感指令都是特權指令的一個子集，我們就可以說這種處理器架構是可虛擬化的。在這種情況下，我們就可以肜經典的“陷入後模擬“(trap-and-emulate)的方法實現虛擬化。按照這個定義，在嵌入式工業中最常見的ARM架構則不是可虛擬化的，因為ARM的敏感指令有些是特權指令，有些則不是。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size: 14px; &#34;&gt;原文 from the paper &lt;a href=&#34;http://systems.cs.columbia.edu/files/wpid-ols2010-kvmarm.pdf&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&amp;ldquo;KVM for ARM&lt;/a&gt;&amp;rdquo; by Christoffer Dall and Jason Nieh, Columbia University：&lt;/span&gt;&lt;span style=&#34;font-size: 14px; &#34;&gt;Popek and Goldberg define sensitive instructions as the group of instructions where the effect of their execution depends on the mode of the processor or the location of the instruction in physical memory. A sensitive instruction is also privileged if it always generates a trap, when executed in user mode. The VMM can only guarantee correct execution without the use of dynamic translation if all sensitive instructions are also privileged. In other words, an architecture is virtualizable if and only if the set of sensitive instrucctions is a subset of the seet of privileged instructions. If that is the case, the VMM can be implemented using a classic trap-and-emulate solution. Unfortunately, ARM is not virtualizable as the architecture defines both sensitive privileged instructions and sensitive non-privileged instructions.&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>traceroute failed.Specify protocal traceroute used manually to fix it.</title>
      <link>https://ykyi.net/?p=751/</link>
      <pubDate>Wed, 20 Jun 2012 14:37:16 +0000</pubDate>
      <guid>https://ykyi.net/?p=751/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-family:lucida sans unicode,lucida grande,sans-serif;&#34;&gt;&lt;span style=&#34;font-size: 16px; &#34;&gt;Today, I ran the traceroute program on a machine running FreeBSD. It failed once and again.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family:lucida sans unicode,lucida grande,sans-serif;&#34;&gt;&lt;span style=&#34;font-size: 16px; &#34;&gt;Traceroute complained:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family:lucida sans unicode,lucida grande,sans-serif;&#34;&gt;&lt;span style=&#34;font-size: 16px; &#34;&gt;&lt;span style=&#34;color: rgb(51, 51, 51); line-height: 19px; text-align: left; &#34;&gt;traceroute: sendto: Permission denied.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&#34;text-align: left;&#34;&gt;
  &lt;span style=&#34;font-family:lucida sans unicode,lucida grande,sans-serif;&#34;&gt;&lt;span style=&#34;font-size: 16px; &#34;&gt;&lt;font color=&#34;#333333&#34;&gt;&lt;span style=&#34;line-height: 19px; &#34;&gt;So I tried to ping. Ping failed, too. I then checked out the configuration of the firewall, which actually denied the pass through of ICMP packet. So I set it to allow ICMP pacakges to pass through the firewall. Ping worked as I expected. But traceroute still failed.&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;</description>
    </item>
    <item>
      <title>如何正确地提交内核补丁包</title>
      <link>https://ykyi.net/?p=716/</link>
      <pubDate>Wed, 20 Jun 2012 11:39:56 +0000</pubDate>
      <guid>https://ykyi.net/?p=716/</guid>
      <description>&lt;p&gt;原文：&lt;a href=&#34;https://lwn.net/Articles/500443/&#34;&gt;https://lwn.net/Articles/500443/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;翻译：&lt;a href=&#34;http://ykyi.net&#34;&gt;ykyi.net &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: rgb(0, 0, 0); font-family: &#39;Times New Roman&#39;; font-size: medium; &#34;&gt;Greg Kroah-Hartman(又Greg KH)在执行一个了不起的作务：减少内核开发者，尤其是维护者的暴躁情绪。他在日本横滨举行的全球Linux大会上的讲演呼吁公众理解内核维护者的工作，内核贡献者的什么样的行为会导致内核维护者变得暴戾。但是，如果内核贡献者们能够遵守一些约束，他代表他自己做了许多承诺。&lt;/span&gt;&lt;/p&gt;
&lt;p style=&#34;color: rgb(0, 0, 0); font-family: &#39;Times New Roman&#39;; font-size: medium; &#34;&gt;
  Greg&amp;nbsp;Kroah&amp;nbsp;Hartman把Linux内核称之为&#34;有史以来最宏大的软件开发项目&#34;，而且它的开发速度也是&amp;ldquo;亘古未有&amp;rdquo;。从3.0到3.4，有373个公司的2833位开发者参于了Linux内核的开发。这一年，(2011年的5月到，2012年的5月)，Linux内核在每个小时会有5.79处变动。而且这个开发速度仍然要加速，如果你看看3.4的开发过程，每小时共有7.21处变动。这里所说的变动仅仅指能够被合并到主干的补丁包，而那些被拒绝的补丁包没有被统计进来。
&lt;/p&gt;
&lt;p style=&#34;color: rgb(0, 0, 0); font-family: &#39;Times New Roman&#39;; font-size: medium; &#34;&gt;
  补丁包修改了哪些文件，内核开发者就把补丁包发给负责这些文件的维护者。所以的内核维护者，现在大概有700人。他们把改变应用到130个子系统的维护者那里。再从子系统的维护者到Linus的Linux内核代码分支。最后并必Linux内核的主干。如果提交的补丁包一路通过的话。
&lt;/p&gt;
&lt;p style=&#34;color: rgb(0, 0, 0); font-family: &#39;Times New Roman&#39;; font-size: medium; &#34;&gt;
  因此，来看看为什么一些补丁包不会被接受呢？Greg&amp;nbsp;Kroah&amp;nbsp;Hartman以刚过去的两个星期收到的补丁包为例，这两个星期刚好处于3.5版本的Merge Window时间。Merge Window是一个他确不应该接收到许多补丁包的时间段。他应该在Merge Window开始前收到所以有可能会在Merge Window其间被发往Linux Torvalds的补丁包。不过，他说他在这两个星期的时间里收到487个补丁包。其中的大多数都有很多问题，有些补丁包来自那些本应该对内核有更好理解的内核开发者们。
&lt;/p&gt;
&lt;h4 style=&#34;color: rgb(0, 0, 0); font-family: &#39;Times New Roman&#39;; font-size: medium; &#34;&gt;
  坏的补丁包
&lt;/h4&gt;
&lt;p style=&#34;color: rgb(0, 0, 0); font-family: &#39;Times New Roman&#39;; font-size: medium; &#34;&gt;
  Greg KH举例说明了一些他收到的坏的补丁包。其中一个补丁包被命名为：patch 48/48(一个有48个补丁集的最后一个)，但是其它的47个都没有。他还收到一堆补丁但没有写清楚先后顺序。如此，他要么猜测一个顺序，这毫无疑问会失败。另一个替代方案就是安全不管这个补丁了。另外还收到过有10个补丁的补丁集，但是2号补丁确丢失了。
&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux内核维护者的职责</title>
      <link>https://ykyi.net/?p=710/</link>
      <pubDate>Wed, 20 Jun 2012 08:48:58 +0000</pubDate>
      <guid>https://ykyi.net/?p=710/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family: &#39;comic sans ms&#39;, cursive; &#34;&gt;原文: &lt;/span&gt;&lt;/span&gt;&lt;a href=&#34;http://www.linuxfoundation.org/news-media/blogs/browse/2012/06/role-linux-kernel-maintainer&#34;&gt;http://www.linuxfoundation.org/news-media/blogs/browse/2012/06/role-linux-kernel-maintainer&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;翻译: &lt;a href=&#34;http://ykyi.net&#34;&gt;ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p style=&#34;margin: 1em 0px; font-size: 1.08em; line-height: 1.53em; color: rgb(77, 77, 77); font-family: Tahoma, Verdana, Arial, Helvetica, &#39;Bitstream Vera Sans&#39;, sans-serif; &#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family: &#39;comic sans ms&#39;, cursive; &#34;&gt;&lt;span style=&#34;line-height: 1.53em; &#34;&gt;几个星期前在日本举行的Linux大会(LinuxCon)上，我做了一个演讲，&lt;/span&gt;&lt;span style=&#34;line-height: 1.53em; &#34;&gt;题目是&#34;Linux内核维护者，他们在做什么，如何能够帮到他们&#34;。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style=&#34;margin: 1em 0px; font-size: 1.08em; line-height: 1.53em; color: rgb(77, 77, 77); font-family: Tahoma, Verdana, Arial, Helvetica, &#39;Bitstream Vera Sans&#39;, sans-serif; &#34;&gt;
  &lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;font-family: &#39;comic sans ms&#39;, cursive; &#34;&gt;&lt;span style=&#34;line-height: 1.53em; &#34;&gt;这个演讲的视频可以通过这个&lt;/span&gt;&lt;a href=&#34;http://video.linux.com/videos/linux-kernel-maintainers-what-they-do-and-how-you-can-help-them&#34; style=&#34;font-size: 1.08em; line-height: 1.53em; color: rgb(51, 102, 153); &#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;链接&lt;/a&gt;&lt;span style=&#34;line-height: 1.53em; &#34;&gt;看到。如果你想要幻灯片，和我的讲演稿，可以在&lt;/span&gt;&lt;a href=&#34;https://github.com/gregkh/presentation-linux-maintainer&#34; style=&#34;font-size: 1.08em; line-height: 1.53em; color: rgb(51, 102, 153); &#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;这个地址&lt;/a&gt;&lt;span style=&#34;line-height: 1.53em; &#34;&gt;获得。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;</description>
    </item>
    <item>
      <title>中山大学软件学院11级硕士研究生2012年上学期软件项目管理期末考试试题</title>
      <link>https://ykyi.net/?p=705/</link>
      <pubDate>Wed, 20 Jun 2012 05:54:51 +0000</pubDate>
      <guid>https://ykyi.net/?p=705/</guid>
      <description>&lt;p&gt;如题，这是中山大学软件学院02年上学期期末的软件项目管理期末考试试题 for MSE 11.&lt;/p&gt;
&lt;p&gt;The final exam of Software Project Management in the first semester of 2012 for MSE 11, Software School, Sun Yat-sen University.&lt;/p&gt;
&lt;p&gt;一 概念题，名词解释(每题5分，共30分)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;WBS (Work Breakdown Structure)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CPM (Critical Path Method)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;里程碑 (Milestone)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;RAM (Responsibility Assignment Matrix)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SPI (Software Process Improvement)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;决策树&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;二. 问答题(每题10分，共70分)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;请具体解释项目管理知识体系的九大知识域？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如何理解迭代式开发，有何优缺点？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;什么是CMMI? CMMI的五个级别各有什么要求？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;简述软件项目的风险管理过程。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如何估算软件项目的成本。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;项目经理应用哪些能力？为什么？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;请具体解释五大项目管理过程组。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>What is 802.11 and their friends.</title>
      <link>https://ykyi.net/?p=687/</link>
      <pubDate>Tue, 19 Jun 2012 11:05:52 +0000</pubDate>
      <guid>https://ykyi.net/?p=687/</guid>
      <description>&lt;p&gt;WLAN(Wireless Lan) was invented in University of Hawaii, 1970, under the leadership of Professor Norman Abramson.The wireless network communicated using radios, without using phone lines making it easy to deploy over Hawaii islands.&lt;/p&gt;
&lt;p&gt;Original WLAN hardware was used as an alternative to cabled network where cabling was impossible or difficult. The protocals of WLAN at that time was proprietary. Many companies and universities appealed to establish a set of protocals as industry protocals. In the end of the 1990s, IEEE 802.11(Wifi) came to satisfy the urgent need. Subsequent amendments such as 802.11a, 802.11b, 802.11g, 802.11n was published in the following years. Other proprietary protocals was then graduately replaced by 802.11 family.&lt;/p&gt;</description>
    </item>
    <item>
      <title>关于博主About the blog master</title>
      <link>https://ykyi.net/about-2/</link>
      <pubDate>Tue, 19 Jun 2012 06:00:33 +0000</pubDate>
      <guid>https://ykyi.net/about-2/</guid>
      <description>&lt;p style=&#34;font-size: 13px;&#34;&gt;
  80后IT人。2001年接触编程。
&lt;/p&gt;
&lt;p style=&#34;font-size: 13px;&#34;&gt;
  本科毕业于南京气象学院(现南京信息工程大学)。2005年。
&lt;/p&gt;
&lt;p style=&#34;font-size: 13px;&#34;&gt;
  硕士研究生毕业于中山大学。2013年。
&lt;/p&gt;
&lt;p style=&#34;font-size: 13px;&#34;&gt;
  之前供职于金山软件，目前供职于深圳腾讯。
&lt;/p&gt;
&lt;p style=&#34;font-size: 13px;&#34;&gt;
  联系qq:&amp;nbsp;16236914
&lt;/p&gt;
&lt;p style=&#34;font-size: 13px;&#34;&gt;
  Email: &amp;nbsp;kamuszhou(at)qq.com
&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;I am the webmaster. I was born in the 1980s.&lt;/p&gt;
&lt;p&gt;I started my programming life since the year 2001, and I always keep my eyes on the constant and fast evolution occured in the cyber space.&lt;/p&gt;
&lt;p&gt;I graduated from Nanjing Institute of Meteorology(Now renamed to Nanjing University of Info Science &amp;amp; Tech) in 2005 and I got the master degree in Sun Yat-sen University in 2013.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A very brief Introduction to Neural Network.</title>
      <link>https://ykyi.net/?p=658/</link>
      <pubDate>Mon, 18 Jun 2012 14:42:23 +0000</pubDate>
      <guid>https://ykyi.net/?p=658/</guid>
      <description>&lt;p&gt; &lt;/p&gt;
&lt;div&gt;
  I have huge interests in the mysterious Artificial Intelligence. Because of the lack of time to devote into learning AI, I still barely know AI related theories. Tonight I read something about Neural Network, which plays a important role in the AI field.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  So, what is A NEURAL NETWORK?
&lt;/div&gt;
&lt;div&gt;
  A neural network is a massively parallel distributed processor made up of simple processing units that has a natural propensity for storing experiential knowledge and making it available for use. It resemble the brain in two respects:
&lt;/div&gt;
&lt;div&gt;
  knowledge is acquired by the network from its environment through a learning process.
&lt;/div&gt;
&lt;div&gt;
  Interneuron connection strengths &amp;nbsp;known as synaptic weights, are used to store the acquired knowledge.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Let us take the human vision as an example to demonstrate why it is necessary to study neural network. Human vision is a very complex information processing task. It is the function of the visual system to provide a representation of the the environment around us and to supply the information we need to interact with the environment. The brain accomplishes recognition task at the same time. For instance, the brain can recognize a familiar face embedded in an unfamiliar scene in shorter than a blink of eye, actually 100-200ms, whereas tasks of much lesser complexity take a great deal longer on a very powerful computer.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  What&#39;s the reason makes the biological brains so efficient? How to let our machines think and do reasoning like biological brains do. The course of Neural Network has been trying to answer these questions from the day the course was established.
&lt;/div&gt;
&lt;div&gt;
  A typical neural network has many useful properties and capacities. 1. Nonlinearity 2. Input-output Mapping 3. Adaptivity 4. Evidential Response 5. Contextual Information 6. Fault Tolerance 7. VLSI(Very Large Scale Integrated) Implementability. 8. Uniformity of Analysis and Design 9. Neurobiological Analogy.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>A easy way to add copyright information automatically into post(English Version英文版)</title>
      <link>https://ykyi.net/?p=641/</link>
      <pubDate>Sun, 17 Jun 2012 05:26:26 +0000</pubDate>
      <guid>https://ykyi.net/?p=641/</guid>
      <description>&lt;p&gt; &lt;/p&gt;
&lt;p style=&#34;margin: 0px 0px 0.8em; padding: 0px; border: 0px; font-family: Verdana, Geneva, sans-serif; vertical-align: baseline; line-height: 1.3em; color: rgb(0, 0, 0); &#34;&gt;
  &lt;span style=&#34;line-height: 1.3em; &#34;&gt;Several weeks ago, I decided to write about two blog posts every day. I used to write copyright information manually in the post. Apparently, it&#39;s better to let the machine do this type of trivial work automatically. So, I searched the plugins to try to find a convenient one. Indeed, I found the plugin named &#34;add post URL&#34; which is able to help the author to insert copyright information into the post. When I clicked the &#39;DETAIL&#39; button to see more. A warning message popped up: &#34;&lt;/span&gt;&lt;span style=&#34;line-height: 1.3em; font-family: arial, helvetica, sans-serif; &#34;&gt;&lt;span style=&#34;line-height: 16px; &#34;&gt;&lt;span style=&#34;background-color: rgb(255, 240, 245); &#34;&gt;This plugin has&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;strong style=&#34;color: rgb(51, 51, 51); font-family: sans-serif; line-height: 16px; background-color: rgb(255, 255, 224); &#34;&gt;&lt;span style=&#34;background-color: rgb(255, 240, 245); &#34;&gt;not been tested&lt;/span&gt;&lt;/strong&gt;&lt;span style=&#34;line-height: 16px; &#34;&gt;&lt;span style=&#34;background-color: rgb(255, 240, 245); &#34;&gt;&amp;nbsp;with your current version of WordPress&#34;. I was scared. Because I once had a bad experience about how untested plugin ruined my wordpress as a whole. So, the option of using plugin to insert copyright information was ruled out.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;</description>
    </item>
    <item>
      <title>为什么要虚拟化</title>
      <link>https://ykyi.net/?p=633/</link>
      <pubDate>Sat, 16 Jun 2012 03:55:35 +0000</pubDate>
      <guid>https://ykyi.net/?p=633/</guid>
      <description>&lt;p&gt;如今，虚拟化是炙手可热的一个高频词。一些质疑虚拟化的人经常会问：我们为什么要搞虚拟化呢，计算机硬件变得越来越便宜了啊！另一方面，一些痴迷虚拟化技术的狂人们在他们的桌式机上用虚拟机运行着四五个操作系统。他们或许也有同样的疑问。仅管他们看着虚拟机里旧式操作系统，模拟出的旧式硬件，觉得非常爽非常有成就感。但是他们却不太解释得清楚究竟为什么需要虚拟化技术。那么，这篇文章将要告诉你我们需要虚拟化技术的原因。&lt;/p&gt;
&lt;h2 id=&#34;整合-consolidation&#34;&gt;整合 Consolidation：&lt;/h2&gt;
&lt;p&gt;使用虚拟化技术的最常见原因是需要整合：把多台机器的工作负载全部整合到同一台机器上面。在更少的物理机器上运行更多的虚拟机。但是你肯定要问：计算机已经越来越便宜了呀。没错，计算机越来越便宜了。但是如果机器非常多的话，这个价格你是绝对不能忽略的。&lt;/p&gt;
&lt;h2 id=&#34;典型的数据中心-a-typicalfull-data-center&#34;&gt;典型的数据中心 A Typical(full) data center&lt;/h2&gt;
&lt;p&gt;让我们来看一看当今世界的数据中心。如今的数据中心里急缺存放机器的空间，房子里满满的塞满了机器，你找不到更多的地方来添置计算机或空调之类的设施。空间利用率已经接近极限了。但是，大多数机器的资源利用率却非常地低。大概平均只有10-20%的的资源利用率。简言之，数据中心的物理空间已经饱合，但是物理机器的使用能力确远远没有利用足够。那么，如果数据中心要承担多更的工作负载，你会再建一个数据中心呢还是想办法把没有利用好的资源利用起来。&lt;/p&gt;
&lt;p&gt;只有数据中心还有空间让你添置机器，当然多加一台机器就相当容易的解决问题了。但无论如论你放不上新的机器的时候，你应该会有很大的麻烦说服BOSS新建一个数据中心。另外一个大问题是，即使BOSS答应新建一个数据中心来解决问题，但是巨大的电力供应从哪里来呢。一个一千万瓦功率的数据中心不是说接入电网就可以接入电网的。你或许还要说服电网的领导批准提升电网的供电能力。&lt;/p&gt;
&lt;p&gt;虚拟化是解决这个问题的最佳办法。用虚拟化把所以机器的性能都利用起来吧！&lt;/p&gt;
&lt;h2 id=&#34;隔离硬件hardware-isolation&#34;&gt;隔离硬件(Hardware Isolation)&lt;/h2&gt;
&lt;p&gt;硬件的性能每个月都在快速提高。但是，当我们把工作负载转移到一台新的服务器的时候，我们还需要先在裸机上安装操作系统，然后再配置各种软件环境，再把所有的数据转移到这台新服务器上来。忙到最后我们还要心惊肉跳的祈祷一切顺利！&lt;/p&gt;
&lt;p&gt;如果使用虚拟化，你就不必这么麻烦了，因为不再直接与硬件层交互。你只需要在新的机器上部署好虚拟环境，再把虚拟机整个移过来。不需要再额外配置什么鬼东西，因为配置就在虚拟机里面，你已经把虚拟机整个搬来了。&lt;/p&gt;
&lt;h2 id=&#34;历史遗留的旧操作系统legacy-operating-system&#34;&gt;历史遗留的旧操作系统(Legacy Operating System)&lt;/h2&gt;
&lt;p&gt;计算机工业走了这么多年，碰到要维护旧的操作系统并不鲜见。不幸的是，你有一个致关重要的程序只能够在这个恐龙级别的操作系统下运行。但大多数老旧的操作系统不能够在新的硬件上运行呀，你又没有办法再配置一台旧硬件的机器。&lt;/p&gt;
&lt;p&gt;解决方案就是使用虚拟化。比如Vmware的Binary rewriting，或者Xen又或者KVM都可以。工作原理则是虚拟层模拟了简单的硬件，从你的旧操作系统看过去，多核CPU变成了老旧操作系统支持的旧时代CPU，当然频率却变快了。多核，ACPI设备发现，中断路由，支持10G以太网，支持SATA都不会成为你运行旧操作系统的障碍，因为虚拟层(Virtualization Layer)！&lt;/p&gt;
&lt;p&gt;当然了，虚拟化本身会占用一些性能。但是因为采用了虚拟化，你才能在非常快速的新硬件上运行旧操作系统，这样得到的效率提高要远远高于在原生态支持旧操作系统的旧硬件上运行。因此，还为你节省了电费。&lt;/p&gt;
&lt;h2 id=&#34;测试testing&#34;&gt;测试(Testing)&lt;/h2&gt;
&lt;p&gt;不管你是学习软件开发的在校学生，还是大银行的首席信息官，你一定缺少足够多的测试硬件吧。&lt;/p&gt;
&lt;p&gt;虚拟化可以解决这一问题。在虚拟机上测试新发布的Fedora Rawhide或者Debian Unstable先，而不是直接格掉机器安装。还能给你的开发团队一把虚拟机，让每人一台虚拟机想测试什么就测试什么。&lt;/p&gt;
&lt;h2 id=&#34;维护maintenace&#34;&gt;维护(Maintenace)&lt;/h2&gt;
&lt;p&gt;有了虚拟化，能方便很多方面的维护。&lt;/p&gt;
&lt;p&gt;比如使用即时迁移技术，像Vmware的vmotion，Xen的Live Migration，你可以在保持虚拟机上的操作系统正常工作的情况下把虚拟机从一台物理机器移动到另一台物理机器。这项技术确实非常有用啊，不仅仅可以用来在你的朋友面前炫燿。&lt;/p&gt;
&lt;p&gt;还有很多情况，你可以使用到即时迁移技术。比如物理机的硬件故障。有一台机器的CPU风扇坏了，CPU的保护系统自动启用使用CPU工作在一个非常慢的速度。那么你就可以把虚拟机即时迁移到另一台健康的机器上，然后修理那台坏的机器而不致于产生Downtime。又如，某台虚拟机的工作负载越来越大，那么你可以这台虚拟机所在的物理机上另外一些虚拟机器迁移到其它物理机上，为这台需要更多资源的虚拟机提供更多支持。有时候你需要升级某台机器的硬件，那么先把这台机器上所有的虚拟机即时迁移到其它机器，再开始你的硬件升级工作，还是没有任何Downtime。酷毙了，是吗？&lt;/p&gt;
&lt;h2 id=&#34;节省能源power-saveing&#34;&gt;节省能源(Power Saveing)&lt;/h2&gt;
&lt;p&gt;举个例子，你有100台服务器运行着各种各样的100个服务程序。但每台服务器的负载只有不到50%，那么你可以用50台物理机器虚拟出100台虚拟机运行100个服务程序。一下子节省了50%的电力，不是吗？想想，一个功率是一千万瓦的数据中心如果能节省50%的电力，这是个多么了不起的数字啊！为你节省了电费钱，还为对抗全球变暖做出了贡献。&lt;/p&gt;
&lt;h2 id=&#34;安全和性能隔离security-and-performance-isolation&#34;&gt;安全和性能隔离(Security and performance isolation)&lt;/h2&gt;
&lt;p&gt;如果你采用虚拟机把不同的程序运行在不同的虚拟机里面，那么如果其中有一个程序出错，吃光了所有的内存，它也不至于影响其它程序。因为其它程序运行在不同的虚拟机里，它们仍然运行得很好，一点都不会受到那个出错程序的影响。如果这些程序运行在同一个OS下，那情况就不妙了。&lt;/p&gt;
&lt;p&gt;一个相似的情况下，如果有一台虚拟机被入侵者攻陷，那么入侵者仅仅只控制了这一台虚拟机，暂时不能对其它虚拟机造成直接威胁。当然，这些虚拟机应该相互隔离的很好，每台虚拟机都运行着自己的内核，大多数虚拟化技术都是这样做的。但有一种虚拟化技术叫做容器技术(Container Technoloties)，如Linux VServer, Virtuozzo/OpenVZ和Solaris Zones，它们实现的虚拟化的隔离性要相当低一些，得到的好处是虚拟化自身消耗更少的硬件资源。&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>一个更方便的在wordpress博客的文章中自动添加版权信息的方法(Chinese Version 中文版)</title>
      <link>https://ykyi.net/?p=628/</link>
      <pubDate>Fri, 15 Jun 2012 13:17:18 +0000</pubDate>
      <guid>https://ykyi.net/?p=628/</guid>
      <description>&lt;p&gt;从半个月前，我决定每天都写两篇左右篇客，或者原创，或者翻译。对于国内的抄袭风气，大家都很清楚，转载别人的文章时把别人的版权信息改成自己的。虽然没有非常好的办法对付抄袭。但至少也需要摆明原创作者的态度还是很必要的。&lt;/p&gt;
&lt;p&gt;一开始，我在每篇博文里手动添加版权信息和链接。虽然工作量不算太大，但对于这种高度重复性的工作，能让机器做还是交给机器做吧。&lt;/p&gt;
&lt;p&gt;首先当然想到的是找相关自动插入版权信息的wordpress插件，虽然也找到一款。名字叫add post，如果没有记错的话！点击Detail查看详细说明的时候发现已经很久没有更新了，而且有一个警告说对于我当前使用的wordpress版本没有经过测试。没有经过测试这句话吓到我了，我不想因为一个插件给我的博客引用不稳定性。于是放弃了使用插件。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;不能使用插件那就只能自己改代码。谷歌了一下，自然搜索到前人写的相关贴子。贴子介绍说找到single.php文件。single.php文件是发贴发贴的文件，我不确定是不是文件名和所有的主题相关，会不会因为使用不同的主题，这个文件名会不太一样。然后找到这段代码：&lt;/p&gt;
&lt;?php the_content(); ?&gt;
&lt;div&gt;
  &lt;!&amp;#8211;
&lt;/div&gt;
&lt;div&gt;
  Pagination for Multi-page posts
&lt;/div&gt;
&lt;div&gt;
  ~~~ &amp;#8211;&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;?php wp_link_pages(&#39;before=&lt;p class=&#34;multi-page&#34;&gt;Pages:&amp;after=&lt;/p&gt;&#39;); // if this is a multipage post then show the navigation ?&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  然后在这段代码的&lt;?php the_content(); ?&gt; 下面插入生成版本信息的代码。但问题是，这种方法并不可靠。非常多的博客使用了其它相关的插件会干扰这种做法。比如，我使用了一个自动生成相关文章列表的插件。于是版本信息被加到了相关文章列表下面，离真正的文章正文有很远的距离。这必不令人满意。另有文章指出可以修改function.php文件，自定义一个和the_content()类似的函数，然后把single.php中的the_content()函数替换掉来完成这个任务。我看了一下，不太满意。修改的地方超过了两个文件，觉得改动有点多。另外写的那个自定义函数对于没有太多wordpress的代码经验的人来讲并不是非常容易读懂。至少我就不明白那个自定义函数的参数的意义，应该和wordpress的标准代码相关。另外，我很怀疑如果用了这种方式，可以会使我的显示相关博文列表的插件失效。一下子没有找到非常好的解决方法。于是去吃晚饭。吃完晚饭后回到电脑前突然来了灵感。可以在用替换字符串的方法增加版权信息呀。想法是这样的。
&lt;/div&gt;
&lt;div&gt;
  1. 在编辑文章的时候，在你需要插入版本信息的地方加入特殊的字符串。比如我选择了在每篇博文最后敲入字符串 &amp;ldquo;copyright &amp;nbsp;ykyi.net&amp;rdquo;
&lt;/div&gt;
&lt;div&gt;
  2. 在发表文章阶段把这个特殊字符串替换成html代码，显示你的版本信息。
&lt;/div&gt;
&lt;div&gt;
  是不是既简单又灵活呢！
&lt;/div&gt;
&lt;div&gt;
  注意要实现这个想法，需要明白 the_content() 和 get_the_content() 两个wordpress函数的区别。在调用the_content()函数的时候，文章的内容就已经打印出来了。但get_the_content()是把文章的内容做为函数返回值返回。所以在修改single.php文件时，要把 the_content()用get_the_content()函数代替。
&lt;/div&gt;
&lt;div&gt;
  下面贴出我的代码。看官如果需要可以修改相应部分：
&lt;/div&gt;
&lt;div&gt;
  &lt;div&gt;
    &lt;?php
  &lt;/div&gt;
  &lt;div&gt;
    $thread_content = get_the_content();&amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    $thread_permalink = get_permalink();
  &lt;/div&gt;
  &lt;div&gt;
    $thread_title = get_the_title($post_id);
  &lt;/div&gt;
  &lt;div&gt;
    $dogeye_copyright = &#34;&lt;pre&gt;除非明确声明，本站所以文章均为&lt;a href=&#39;http://ykyi.net&#39; target=&#39;_blank&#39;&gt;DogEye博客&lt;/a&gt;原创或者自主翻译。&lt;br/&gt;如转载，请注明出处。&lt;a href=\&#34;$thread_permalink\&#34; target=&#39;_blank&#39;&gt;$thread_title $thread_permalink&lt;/a&gt;&lt;/pre&gt;&#34;;
  &lt;/div&gt;
  &lt;div&gt;
    $thread_content = str_replace(&#39;copyright &amp;nbsp;ykyi.net&#39;, $dogeye_copyright, $thread_content);
  &lt;/div&gt;
  &lt;div&gt;
    echo $thread_content;
  &lt;/div&gt;
  &lt;div&gt;
    ?&gt;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    代码应该非常容易读懂了。而且你可以非常灵活地控制要插入的位置，还可以灵活决定插入多处版本声明。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    copyright ykyi.net
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>C语言和它的安全性</title>
      <link>https://ykyi.net/?p=615/</link>
      <pubDate>Fri, 15 Jun 2012 12:28:26 +0000</pubDate>
      <guid>https://ykyi.net/?p=615/</guid>
      <description>&lt;p&gt;原文: &lt;a href=&#34;http://avikivity.blogspot.com/2011/08/c-assembly-and-security.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;a href=&#34;http://avikivity.blogspot.com/2011/08/c-assembly-and-security.html&#34;&gt;http://avikivity.blogspot.com/2011/08/c-assembly-and-security.html&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ykyi.net 翻译。&lt;/p&gt;
&lt;p&gt;我们看下面一个C语言的句子：&lt;/p&gt;
&lt;p&gt;a = b + c&lt;/p&gt;
&lt;p&gt;什么时候这个句子会造成错误呢？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;a, b, c 不是我们想要的值。也就是我们把变量名写错了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;写了加法，但是我们要的不是加法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;做了加法后值溢出了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;a和b是无符号类型，而c却是有符号类型并且是负数，b+c后得到负数又赋给a.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;sizeof(a)比sizeof(b)和sizeof(c)要小。又溢出了！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;a是有符号型，b和c是无符号型。b+c后赋给a，溢出后，a变成负值。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;a是无符号型，b和c是有符号型；再次溢出。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我们不能期望C语言本身能避免所有这些错误，但我们可不可以通过在运行时Trap上述的一些错误改进C语言使之更安全呢？结果时，除非牺牲性能，否则做不到。但我们能牺牲性能吗？&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;♦ 为了处理第(3)种情况，我们需要Trap所以有符号数的加法和所以无符号数的加法指令。&lt;/p&gt;
&lt;p&gt;♦ 为了处理第(4)种情况，需要一个混杂有符号和无符号的加法指令被Trap。&lt;/p&gt;
&lt;p&gt;♦ 为了处理第(5)种情况，需要Trap存储有符号数和无符号数的指令。在Trap中检查寄存器中的值与存入的内存地址是否匹配。&lt;/p&gt;
&lt;p&gt;♦ (6)和(7)与上类似。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;这些看似简单的问题在安全，漏洞方面经常出现。我们很难发现并修复这些问题，因为没有所需要的处理器指令。当然我们可以用已经存在的指令模拟它们。但是这样做肯定会损害性能并且使程序的体积增大。因为程序性能是可以被度量的，而度量安全问题则比较困难。结果时留下了很多充满漏洞的代码(exploitable code)。&lt;/p&gt;
&lt;p&gt;不禁要问，为什么我们没有这些指令呢？在上世纪的七，八十年代，正在快速成长的计算机工业界面临的最大问题是性能，而不是安全。那时的代码量很小，也很容易做检查；网络还在最初级的阶段，很小，而且基本上是私有的；基本不存在恶意的攻击。&lt;/p&gt;
&lt;p&gt;C语言在当时的作法是为了能够在适合当时所有的处理器，因此C语言的语义模仿当时的处理器指令集。之后，C语言大获成功，大量的处理器则针对C语言做优化，很多指令直接针对C语言的语义做优化或可以直接对应到C语言的语义。这样，使得C语言更加流行了。&lt;/p&gt;
&lt;p&gt;X86的世界里有两个指令: INTO和BOUND是极好的例子。INTO(INTerrupt on Overflow)可以在一个加法指令或者减法指令之后。INTO可以用来作为上文指到过的Trap有符号加减法的指令。BOUND则对数组操作是否越界做检查。但是BOUND极少被使用。最后，在x86体系过渡到64位体系的过程中，INTO指令和BOUND指令都被只留在历史的尘埃之中了。&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>十分钟，教你创建自己的聊天机器人</title>
      <link>https://ykyi.net/?p=602/</link>
      <pubDate>Thu, 14 Jun 2012 07:00:59 +0000</pubDate>
      <guid>https://ykyi.net/?p=602/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-family:times new roman,times,serif;&#34;&gt;&lt;span style=&#34;font-size: 14px; &#34;&gt;这几天在网络上闲逛发现一个帮助你创建聊天机器人(Chat Robot)的网站。尝试了一下，很有意思呀！&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family:times new roman,times,serif;&#34;&gt;&lt;span style=&#34;font-size: 14px; &#34;&gt;关于人工智能(AI Artificial Intelligence)是我一直感兴趣的领域，但一直未能分出时间系统学习。目前为止，知道的最深入的也只是基于贝叶斯统计算法的专家系统。至于机器学习，还有神经网络哥一点都不懂哈！希望以后能有时间学习并应用。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family:times new roman,times,serif;&#34;&gt;&lt;span style=&#34;font-size: 14px; &#34;&gt;言归正传。我发现的这个帮助你快速创建在线聊天机器人的网站是&lt;a href=&#34;http://pandorabots.com&#34;&gt; &lt;a href=&#34;http://www.pandorabots.com&#34;&gt;http://www.pandorabots.com&lt;/a&gt; &lt;/a&gt; 。你在这个网站注册以后就只需要几步就可以创建一个WEB页面上的聊天机器人了。这个网站的机器人技术是基于AIML语言的。前几天写过一篇关于&lt;a href=&#34;http://ykyi.net/2012/06/%E4%BB%80%E4%B9%88%E6%98%AFaiml%EF%BC%8C%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD%E6%A0%87%E5%BF%97%E8%AF%AD%E8%A8%80/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;AIML的博文，可以参考下&lt;/a&gt;。前期工作来自于自由软件设区&lt;a href=&#34;http://www.alicebot.org&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt; &lt;a href=&#34;https://www.alicebot.org&#34;&gt;www.alicebot.org&lt;/a&gt;&lt;/a&gt;。Pandorabots网站上的About介绍里说该网站还在继续语音识别，TTS(语音合成)等方面的研究，不过据我观赛。已经好久都没有更新了喔。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family:times new roman,times,serif;&#34;&gt;&lt;span style=&#34;font-size: 14px; &#34;&gt;STEP ONE：在pandorabots的首页，找到Sign-up for an Account，按ctrl+F 搜索一下 Sign，就能马上定位到了。点击这个链接就可以注册一个账号了。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family:times new roman,times,serif;&#34;&gt;&lt;span style=&#34;font-size: 14px; &#34;&gt;STEP TWO：和大多数注册过程一样，填上一些最基本的信息就注册成功。记得勾选上 By checking this box and clicking on the button labeled “Submit Account Request” you are agreeing to the Term Service 复选框。点击 SUBMIT ACCOUT REQUEST.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family:times new roman,times,serif;&#34;&gt;&lt;span style=&#34;font-size: 14px; &#34;&gt;STEP THREE：接着网站提示: There are no Pandorabots defined yet. You must first create a new  chat robot。点击 create 单词上的链接。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>一篇广外女生的外贸论文的中译英.节选.</title>
      <link>https://ykyi.net/?p=600/</link>
      <pubDate>Thu, 14 Jun 2012 05:44:29 +0000</pubDate>
      <guid>https://ykyi.net/?p=600/</guid>
      <description>&lt;p&gt;应一位广外女生的要求，帮她翻译了部分她的论文。好累好累&lt;del&gt;诸多术语不熟悉&lt;/del&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div&gt;
  进口配额制（Import Quotas）又称进口限额制。它是直接限制进口的一种重要措施。进口配额制是指一国政府在一定时期内（如一季度、半年或一年内），对某些商品的进口数量或金额规定一个数额加以直接的限制，在规定时限内，配额以内的货物可以进口，超过配额则不准进口，或者征收较高的关税、附加税或罚款后才能进口。
&lt;/div&gt;
&lt;div&gt;
  进口配额，又称进口限额。它是发达国家实行进口数量限制的重要手段之一。主要有两大类：(1)绝对配额。
&lt;/div&gt;
&lt;div&gt;
  (2)关税配额。&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  5.The definition of the import quotas.
&lt;/div&gt;
&lt;div&gt;
  Import Quotas, namely Import Limits, which is one of the most important measures to limit import. Import quotas is defined as the direct limitation impossed on some certain
&lt;/div&gt;
&lt;div&gt;
  import commodity on import quantity or sum in some periods(e.g. one quarter, one half-year or a whole year). In the limitation period, merchats in limitation range is granted to be imported, otherwise, will be refused or much higher tariffs will be impossed.
&lt;/div&gt;
&lt;div&gt;
  There are two kinds of Import Quotas.
&lt;/div&gt;
&lt;div&gt;
  1) Absolte Quotas.
&lt;/div&gt;
&lt;div&gt;
  2) Tariff Quotas.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  1． 在进口配额制下管理好使用好配额，扩大出口，增加外汇
&lt;/div&gt;
&lt;div&gt;
  在配额制下，进口国对某些商品直接限定数量或金额，在限定范围内，货物才许可进口。因此，对出口国来说，配额用完了就不能扩大出口。即使有的国家允许超配额商品进口，而进口国则要征收高额 关税或罚款，但这种关税非同一般关税，有时甚至高达百分之几百，罚款数额也很大。所以，实际上这种高额关税或罚款起到了禁止进口的作用。
&lt;/div&gt;
&lt;div&gt;
  这些配额都是通过谈判达成的双边协定，那么如何在配额制下管理好使用好我国的配额，扩大出口，增加外汇？&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  1. Manage the quotas well and make good use of it to expand export and raise foreign-currency(foreign reserves?) under the import quotas system.
&lt;/div&gt;
&lt;div&gt;
  Due to the fact that under the import quotas system, importing nations set a ceiling limit of the quantity and sum of the import commodity and import commodity gained the access permission only when the quota limit has not been used out. As for the exporting nations, it is not possible to expand export when no quotas is available. Even though in some nations, excess import happens only on the basis that the importing nation imposes higher tariffs, usually go up to several hundred percent, or levies heavy fines which is also very huge. Actually, it serves as a ban on imports.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  1.在品种和单价方面做到对我有利，以达到扩大出口，多收外汇的目的。对配额品种首先要选择售价高的高挡商品出口。当然这要求考虑到客户的需要和国内生产的可能，但总体来说，以出口高附加值
&lt;/div&gt;
&lt;div&gt;
  商品为主，同时，对于资源原料型和畅销品可适当增加价格出口。
&lt;/div&gt;
&lt;div&gt;
  The varieties and unit price should be in our favor in order to expand the export and raise the foreign reserve. High price and high class commodities should be given high priority. The customer demands and the production capacity are surely to take into consideration. Generally speaking, high value added products should take main account of the export, resource-based goods, raw materials, and best-selling goods can be slightly exported more on the meanwhilek.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  2要努力扩大配额地区的非配额品种出口。如欧盟对纺织品&amp;ldquo;篮子品种&amp;rdquo;敏感性较差，尽管协定中规定了我出口比例，但欧盟对它控制较松。这类品种我国约占二、三万吨，过去几年我国往往出口很少，数没有做足，今后应积极扩大出口&amp;ldquo;篮子品种&amp;rdquo;。但这类品种成交和出运要保持均衡，避免过分集中，而引起共同体注意和交涉。&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Best effort should be make to expand export of the commodities that are not be limited by import quotas. As a example, though export quotas on &#34;Bastket Species&#34; are specified in trade agreement, the EU is less sensitive to it and the leash has been loosed. This kind of product accout for two or three tons in our country, which has been export a small amout in the past years and it has not been exported enough. We should expand &#34;basket species&#34; export positively. However, balance must be control well to prevent being intensivly centralized which will result in the EU&#39;s attention and negotiation.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  3.要加强对客户的管理。配额品种一般是供不应求的商品，对进口商来说，利润是有保障的。因此，我们可以通过发放出口许可证，签发产地证和装船证书加以控制。
&lt;/div&gt;
&lt;div&gt;
  Customer management should be strengthed. In most cases, commodities suffering from quotas are in short supply. As for the importers, profits is well guaranted. So, we could control through taking measures such as releasing export licence, signing certificate of origin and shipment.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  4.为了履行对外缔结的协定义务，管理好配额品种的出口，各业务部门必须要有一个精确的统计资料。业务部门按时上报的配额使用情况，数字一定要正确。业务部门内部也要加强统计和联系，保证成 交出运数不超过配额数。
&lt;/div&gt;
&lt;div&gt;
  4. In order to fullfill well the trade agreement and manage well the quota commodities, every operating deparment must have prcise statistical materials. Opeating department has to report the quota usuage condition in time and the figure accuracy is a must. As inside the operating department, statistics and communications should be enforced to assure the quotas will not be accessed.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  copyright ykyi.net
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>怎么编译,构建,安装,使用WinKVM</title>
      <link>https://ykyi.net/?p=595/</link>
      <pubDate>Wed, 13 Jun 2012 16:00:19 +0000</pubDate>
      <guid>https://ykyi.net/?p=595/</guid>
      <description>&lt;p&gt; &lt;/p&gt;
&lt;p class=&#34;p0&#34; style=&#34;margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; &#34;&gt;
  &lt;span style=&#34;color: rgb(51, 51, 51); font-size: 12.5pt; font-family: &#39;Bitstream Vera Sans Mono&#39;; &#34;&gt;WinKVM&amp;nbsp;:&amp;nbsp;Windows&amp;nbsp;kernel-based&amp;nbsp;Virtual&amp;nbsp;Machine&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34; style=&#34;margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; &#34;&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p class=&#34;p0&#34; style=&#34;margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; &#34;&gt;
  WinKVM Windows下台下基于内核的虚拟机(Linux的KVM的windows移植)
&lt;/p&gt;
&lt;p class=&#34;p0&#34; style=&#34;margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; &#34;&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p class=&#34;p0&#34; style=&#34;margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; &#34;&gt;
  &lt;span style=&#34;color: rgb(51, 51, 51); font-size: 12.5pt; font-family: &#39;Bitstream Vera Sans Mono&#39;; &#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=&#34;p0&#34; style=&#34;margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; &#34;&gt;
  &lt;span style=&#34;color: rgb(51, 51, 51); font-size: 12.5pt; font-family: &#39;Bitstream Vera Sans Mono&#39;; &#34;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;h2 class=&#34;p0&#34; style=&#34;margin-bottom: 0pt; margin-top: 0pt; &#34;&gt;
  &lt;span style=&#34;color: rgb(51, 51, 51); font-size: 12.5pt; font-family: &#39;Bitstream Vera Sans Mono&#39;; &#34;&gt;怎么编译，构建WinKVM&lt;/span&gt;
&lt;/h2&gt;
&lt;p class=&#34;p0&#34; style=&#34;margin-bottom:0pt; margin-top:0pt; text-autospace:ideograph-other; &#34;&gt;
  &amp;nbsp;
&lt;/p&gt;</description>
    </item>
    <item>
      <title>什么是AIML，人工智能标志语言</title>
      <link>https://ykyi.net/?p=590/</link>
      <pubDate>Wed, 13 Jun 2012 04:00:14 +0000</pubDate>
      <guid>https://ykyi.net/?p=590/</guid>
      <description>&lt;p&gt; &lt;/p&gt;
&lt;div&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;div&gt;
    &lt;p&gt;
      AIML是Artificial&amp;nbsp;Intelligence&amp;nbsp;Markup&amp;nbsp;Language的缩写。这种语言基于XML，它易学习易掌握。使用AIML可以很容易的定制一个Alicebot或者从头开始创建一个Alicebot。Alicebot是种聊天机器人，参见&lt;a href=&#34;http://www.alicebot.org/&#34;&gt;http://www.alicebot.org/&lt;/a&gt;&amp;nbsp;。
    &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;p style=&amp;quot;margin-left:7.5000pt;&amp;quot;&amp;gt;
  下面简单的介绍下AIML的语法。
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;margin-left:7.5000pt;&amp;quot;&amp;gt;
  AIML语言中最重要的四个标志：
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;margin-left:18.0000pt;&amp;quot;&amp;gt;
  &amp;amp;middot;&amp;amp;nbsp;&amp;lt;aiml&amp;gt;:&amp;amp;nbsp;这个标签用来标志一个AIML文档的开始和结束。
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;margin-left:18.0000pt;&amp;quot;&amp;gt;
  &amp;amp;middot;&amp;amp;nbsp;&amp;lt;category&amp;gt;:&amp;amp;nbsp;这个标志表示在Alicebot的知识体系里暂时无法理解的东西。
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;margin-left:18.0000pt;&amp;quot;&amp;gt;
  &amp;amp;middot;&amp;amp;nbsp;&amp;lt;pattern&amp;gt;:&amp;amp;nbsp;用来描述一个简单的模式表示用户会同Alicebot说什么。
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;margin-left:18.0000pt;&amp;quot;&amp;gt;
  &amp;amp;middot;&amp;amp;nbsp;&amp;lt;template&amp;gt;:&amp;amp;nbsp;用来描述Alicebot的回复。
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;margin-left:7.5000pt;&amp;quot;&amp;gt;
  还有20余种标签会在AIML文件中经常碰到。你也可以创建你自己的&amp;amp;ldquo;定制标签&amp;amp;rdquo;。现在就开始学习使用AIML吧，这里有一个初级教程&amp;amp;nbsp;&amp;lt;a href=&amp;quot;http://www.alicebot.org/documentation/&amp;quot;&amp;gt;AIML&amp;amp;nbsp;Primer&amp;lt;/a&amp;gt;。
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;margin-left:7.5000pt;&amp;quot;&amp;gt;
  举例说明吧。免费的&amp;lt;a href=&amp;quot;http://www.alicebot.org/downloads/&amp;quot;&amp;gt;A.L.I.C.E.&amp;amp;nbsp;AIML&amp;lt;/a&amp;gt;&amp;amp;nbsp;已经包含了一个基本的知识库，描述了大概41,000个category。看这个例子：
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;margin-left:7.5000pt;&amp;quot;&amp;gt;
  &amp;lt;category&amp;gt;&amp;lt;br /&amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;pattern&amp;gt;WHAT&amp;amp;nbsp;ARE&amp;amp;nbsp;YOU&amp;lt;/pattern&amp;gt;&amp;lt;br /&amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;template&amp;gt;&amp;lt;br /&amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;think&amp;gt;&amp;lt;set&amp;amp;nbsp;name=&amp;quot;topic&amp;quot;&amp;gt;Me&amp;lt;/set&amp;gt;&amp;lt;/think&amp;gt;&amp;amp;nbsp;&amp;lt;br /&amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;I&amp;amp;nbsp;am&amp;amp;nbsp;the&amp;amp;nbsp;latest&amp;amp;nbsp;result&amp;amp;nbsp;in&amp;amp;nbsp;artificial&amp;amp;nbsp;intelligence,&amp;lt;br /&amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;which&amp;amp;nbsp;can&amp;amp;nbsp;reproduce&amp;amp;nbsp;the&amp;amp;nbsp;capabilities&amp;amp;nbsp;of&amp;amp;nbsp;the&amp;amp;nbsp;human&amp;amp;nbsp;brain&amp;lt;br /&amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;with&amp;amp;nbsp;greater&amp;amp;nbsp;speed&amp;amp;nbsp;and&amp;amp;nbsp;accuracy.&amp;lt;br /&amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;/template&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;/category&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;margin-left:7.5000pt;&amp;quot;&amp;gt;
  &amp;lt;aiml&amp;gt;标签在这里没有显示出来，因为这里只是文档的一个节选。
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;margin-left:7.5000pt;&amp;quot;&amp;gt;
  如你所见&amp;lt;categoray&amp;gt;与&amp;lt;/category&amp;gt;之间，就是描述一个category啦！每个category可以有一个pattern和一个template，还可以有一个&amp;lt;that&amp;gt;标签的，但是我不想在这里讨论它。
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;margin-left:7.5000pt;&amp;quot;&amp;gt;
  如上的category中的pattern只能够匹配精确的&amp;quot;what&amp;amp;nbsp;are&amp;amp;nbsp;you&amp;quot;(大小写忽略)。What&amp;amp;nbsp;are&amp;amp;nbsp;you&amp;amp;nbsp;你不会不认识吧，好吧，直译是&amp;quot;你是什么东西啊？&amp;quot;
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;margin-left:7.5000pt;&amp;quot;&amp;gt;
  每个category还有可能被另外一个category调用，此时使用&amp;lt;srai&amp;gt;标签，这里也不作深入讨论。可以参见&amp;lt;a href=&amp;quot;http://www.alicebot.org/documentation/srai.html&amp;quot;&amp;gt;reductionism&amp;lt;/a&amp;gt;.&amp;amp;nbsp;Reductionism大根是还原论，简约化的意思。很难译出！
&amp;lt;/p&amp;gt;

&amp;lt;p style=&amp;quot;margin-left:7.5000pt;&amp;quot;&amp;gt;
  不管哪种情况，如果这个category被激发了，alicebot就会回答：&amp;quot;I&amp;amp;nbsp;am&amp;amp;nbsp;the&amp;amp;nbsp;latest&amp;amp;nbsp;result&amp;amp;nbsp;in&amp;amp;nbsp;artificial&amp;amp;nbsp;intelligence&amp;amp;#8230;&amp;quot;&amp;amp;nbsp;，前面&amp;lt;template&amp;gt;里面的东东。意思是：我是最先进的人工智能的产物。我能够以超快的速度和准确度模拟人脑的功能。另外，还有一些其它有趣的事情发生呢。注间到&amp;lt;think&amp;gt;标签吗？这会让Alicebot联想到这个对话的相关的一个限制，比如上面的例子就告诉alicebot，这个对向在讨论你自己。set&amp;amp;nbsp;name=&amp;quot;topic&amp;quot;,又赋值Me。于是对于alicebot的其它N多category，同样是topic的值为Me的category会被优先采纳。由此，这个机制能让你更好更准确的控制对话的流程。想想还有更多的机制呢，就看你的创造力设计一个聪明的聊天机器人啦！
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/p&amp;gt;&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>使用Cscope阅读大型工程Linux内核的源代码教程</title>
      <link>https://ykyi.net/?p=586/</link>
      <pubDate>Tue, 12 Jun 2012 11:45:14 +0000</pubDate>
      <guid>https://ykyi.net/?p=586/</guid>
      <description>&lt;p&gt;Cscope是一个非常有用的工具，可以用来方便地阅读很大型工程的源代码。较之使用传统的Unix工具grep，使用Cscope可以省下你一大笔时间，大大提高阅读代码的效率。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;通过本教程，我会教给你如何使用Cscope阅读Linux内核的源代码。毫无疑问，你可以举一反三，用同样的方法阅读其它的大型工程的源代码，不仅仅是C语言写的工程，也可以是Java或者C++或者C#开发的工程。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;STEP 1 获得源代码：&lt;/p&gt;
&lt;p&gt;去到Linux内核的网站http://www.kernel.org下载随便一个版本的Linux内核源代码压缩包。然后解压缩，把源代码释放到某个目录。本文假设你把源代码释放到 /home/code/linux-2.6.26。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;STEP 2 选择一个目录存放Cscope所需要的数据库文件。&lt;/p&gt;
&lt;p&gt;本文假设选择用/home/cscope目录存放cscope的数据库文件和其它一些相关文件。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;STEP 3 生成文件 cscope.files&lt;/p&gt;
&lt;p&gt;在最简单的情况下，工程目录下的所有源代码都是我要关心的，于是可以跳过下面所述，简单地在工程的根目录下运行&amp;rsquo;cscope -R&amp;rsquo;命令，这样Cscope就会在工程目录下所有源代码中处理相关工作。&lt;/p&gt;
&lt;p&gt;但是你关心的代码并必工程目录下所有的代码，你还需要排除很多目录下的大量代码该如何做呢？在这种情况下，你需要生成一个文件cscope.files，这个文件包含 了所有cscope将要扫描的文件的文件名，每个名字占一行。最好使用绝对路径，这样你就可以在其它目录下，而不是现在创建cscope.files文件的目录下使用这个刚创建的数据库。下面的代码将完成这个任务（假设我要所有的java文件）：&lt;/p&gt;
&lt;p&gt;$ cd /   &lt;/p&gt;
&lt;p&gt;$ find /my/project/dir -name &amp;ldquo;*.java&amp;rdquo; &amp;gt; /my/cscope/dir/cscope.files&lt;/p&gt;
&lt;p&gt;对于Linux内核来讲，情况还要稍微复杂一点。因为我们还要排除好些文件夹，这些文件夹有存放文档的文件夹，存放脚本的文件夹，与处理器架构相关的汇编代码的目录夹，与处理器架构相关的C代码除了x86（大多数人已经仅仅对x86感兴趣），另外还会排除所有的驱动文件目录夹，因为驱动占了内核很大一部分，但驱动代码通常不是我们要关心的。如果不排除这些目录的话，cscope当然也能工作，但是却给我们增加了麻烦，因为大大增加了重复的定义出现的概率。下面看我怎么做：&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;    $ LNX=/home/linux-2.6.26&lt;/p&gt;
&lt;p&gt;    $ cd /    &lt;/p&gt;
&lt;p&gt;    $ find  $LNX                                                                \&lt;/p&gt;
&lt;p&gt;    -path &amp;quot;$LNX/arch/*&amp;quot; ! -path &amp;quot;$LNX/arch/i386*&amp;quot; -prune -o               \&lt;/p&gt;
&lt;p&gt;    -path &amp;quot;$LNX/include/asm-*&amp;quot; ! -path &amp;quot;$LNX/include/asm-i386*&amp;quot; -prune -o \&lt;/p&gt;
&lt;p&gt;    -path &amp;quot;$LNX/tmp*&amp;quot; -prune -o                                           \&lt;/p&gt;
&lt;p&gt;    -path &amp;quot;$LNX/Documentation*&amp;quot; -prune -o                                 \&lt;/p&gt;
&lt;p&gt;    -path &amp;quot;$LNX/scripts*&amp;quot; -prune -o                                       \&lt;/p&gt;
&lt;p&gt;    -path &amp;quot;$LNX/drivers*&amp;quot; -prune -o                                       \&lt;/p&gt;
&lt;p&gt;    -name &amp;quot;*.[chxsS]&amp;quot; -print &amp;gt;/home/jru/cscope/cscope.files&lt;/p&gt;</description>
    </item>
    <item>
      <title>KVM你问我答 FAQ (四)</title>
      <link>https://ykyi.net/?p=579/</link>
      <pubDate>Mon, 11 Jun 2012 15:19:17 +0000</pubDate>
      <guid>https://ykyi.net/?p=579/</guid>
      <description>&lt;p&gt;&lt;strong&gt;KVM&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;Xen&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;有什么区别？&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Xen&lt;span style=&#34;font-family: 宋体;&#34;&gt;是一个外部虚拟机管理程序&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;(External hypervisor)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，它承担了管理物理机器的任务并把物理机器的各种资源分配给客户机。与&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;Xen&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;不同，&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;KVM&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;本身是&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;Linux&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;内核的一部分，它使用&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;Linux&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;自己的进程调度和内存管理。这就天然决定了&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;KVM&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;易于使用并于体积会很小。仅管体积小，但&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;KVM&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的功能确不少。比如，&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;KVM&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;可以把客户机从内存中兑换到物理磁盘上，如同&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;swap&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;普通进程一样释放&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;RAM&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;KVM&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;目前只在提供支持硬件虚拟化的&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;x86&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;机器上运行（如&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;vt/svm&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;指令集）。从这这方面讲，&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;Xen&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;通过修改客户机操作系统，充许虚拟机运行在没有硬件虚拟化技术的&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;x86&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;平台上运行。这种虚拟化技术称之为准虚拟化&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;paravirtualization&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，参见另一贴：&lt;/span&gt;&lt;a href=&#34;http://ykyi.net/2012/06/linux%E7%9A%84%E8%99%9A%E6%8B%9F%E5%8C%96%E6%8A%80%E6%9C%AF-kvm-%E5%92%8C-qemu/&#34;&gt;Linux&lt;span style=&#34;font-family: 宋体;&#34;&gt;的虚拟化技术&lt;/span&gt;&lt;/a&gt;。&lt;span style=&#34;font-family: Arial;&#34;&gt;KVM&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;在&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;CPU&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;级别不支持&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;paravirtualization&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，但为了指高&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;I/O&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;性能，会对设备驱动程序支持准虚拟化。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KVM&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;Vmware&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;有什么区别呢？&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;VMware&lt;span style=&#34;font-family: 宋体;&#34;&gt;是一个商用专用虚拟化产品，&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;KVM&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;是在&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;GPL&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;许可证下发布的自由软件。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KVM&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;QEMU&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;有什么区别？&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;QEMU&lt;span style=&#34;font-family: 宋体;&#34;&gt;是模拟器。参见&lt;/span&gt;&lt;a href=&#34;http://ykyi.net/2012/06/linux%E7%9A%84%E8%99%9A%E6%8B%9F%E5%8C%96%E6%8A%80%E6%9C%AF-kvm-%E5%92%8C-qemu/&#34;&gt;Linux&lt;span style=&#34;font-family: 宋体;&#34;&gt;的虚拟化技术 &lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;KVM &amp;amp; QEMU&lt;/span&gt;&lt;/a&gt; 。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KVM&lt;span style=&#34;font-family: 宋体;&#34;&gt;有&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;windows&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;下的移移植版本吗？&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>KVM你问我答 FAQ (三)</title>
      <link>https://ykyi.net/?p=574/</link>
      <pubDate>Sun, 10 Jun 2012 13:12:57 +0000</pubDate>
      <guid>https://ykyi.net/?p=574/</guid>
      <description>&lt;h3 dir=&#34;ltr&#34;&gt;
  我在使用QEMU，如何知道我有没有启用KVM的硬件加速功能?
&lt;/h3&gt;
&lt;p&gt;如果你怀疑你没有启用KVM提供的硬件加速功能。你可以按照下面的步骤做检查。首先，看看你有没有得到下面的提示信息：&lt;/p&gt;
&lt;p&gt;qemu-system-x86_64 -hda myvm.qcow2&lt;br&gt;
open /dev/kvm: No such file or directory&lt;br&gt;
Could not initialize KVM, will disable KVM support&lt;/p&gt;
&lt;p&gt;如果是这种情况，请再检查：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;kvm模块被正确载入了吗？ lsmod | grep kvm.&lt;/li&gt;
&lt;li&gt;查看 dmesg 的输出，保证没有这个提示信息： “KVM, disabled by BIOS”.&lt;/li&gt;
&lt;li&gt;请确保/dev/kvm 确实存在，而且你有权限使用它。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;其它诊断方式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如果你能使用 QEMU monitor ( ctrl-alt-2, 再 ctrl-alt-1 回到 VM 的显示屏 )，敲入 info kvm 命令。如果正常的话，应该有“KVM support: enabled”这条信息输出。&lt;/li&gt;
&lt;li&gt;在host机上敲 lsmod | grep kvm 命令，看看输出的最右栏。如果kvm在正常运行的话，这个数字不能是0。这行的数字与架构相关的模块(一般指的是kvm_intel,或kvm_amd)有联系，它显示了有多少个VM正在使用这个模块。举例说明，如果你有两个虚拟机正在使用KVM模块，host机的CPU使用的是vt技术，那么就会得到：&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;# lsmod | grep kvm&lt;br&gt;
kvm_intel              44896  2&lt;br&gt;
kvm                   159656  1 kvm_intel&lt;/p&gt;</description>
    </item>
    <item>
      <title>Six factors to help you create a great website</title>
      <link>https://ykyi.net/?p=519/</link>
      <pubDate>Sat, 09 Jun 2012 16:07:17 +0000</pubDate>
      <guid>https://ykyi.net/?p=519/</guid>
      <description>&lt;p&gt;I’m wondering how to create a great site to put me in bucks.&lt;br&gt;
I would like to share some ideas with you in the hope it would be helpful.  [&lt;a href=&#34;http://ykyi.net&#34;&gt;originally post on zausiu’s blog http://ykyi.net&lt;/a&gt;]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Content is the most important thing. If your website is a long-term business, don’t even think about black-hat SEO. Appropriate legal SEO is necessary, but it can’t be too over-killing. High quality content is worthier of your time and effort.Search engine’s algorithm is quickly changing. If your website is friendly to the visitor, it’s friendly to SE too.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Visitors can benifit from your site. That’s why they will come back. Useless website cannot survive in the internet world.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the huge wave of SNS age, take advantage of the SNS is a must. As you know, something sprend in social network like infectious virus.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you have enough time and technology support. Consider develop related desttop version application and app for mobile phone. Those apps must be able to update automatically, and you can control them in the server side. So, you can push all kinds of infomation to the apps, which will guide the users to visit your website, so your site traffic increases. What is more, the apps will be released to various kinds of download sites. Most likely your website URL will be post there which are your high-quality external links. You surely know how much the high-quality external links means to your site.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You’d better have a team, even though you are versatile and are able to play a number of roles. Remember it’s not a age for lone heroes any more, everybody is limited in some aspects.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>KVM你问我答 FAQ (二)</title>
      <link>https://ykyi.net/?p=505/</link>
      <pubDate>Sat, 09 Jun 2012 08:26:26 +0000</pubDate>
      <guid>https://ykyi.net/?p=505/</guid>
      <description>&lt;h2 dir=&#34;ltr&#34;&gt;
  如果我的没有root权限，怎么使用KVM呢？
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;最简洁的做法就是创建一个组，比如kvm组，然后把将要使用kvm的用户添加到组里面。然后用chown命令把/dev/kvm的所有组改成kvm。如果你的系统里安装了udev，你还可以通过配置udev的方式使得linux自动把新创建的设备设成正确的组。比如在ubuntu的/etc/udev/rules.d/40-permissions.rules文件中增加一行：&lt;br&gt;
KERNEL==”kvm”, GROUP=”kvm”&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;h3 dir=&#34;ltr&#34;&gt;
  怎么做才能得到kvm的最佳性能呢？
&lt;/h3&gt;
&lt;h3 dir=&#34;ltr&#34;&gt;
  See the &lt;a href=&#34;http://www.linux-kvm.org/page/Tuning_KVM&#34;&gt;Tuning KVM&lt;/a&gt; page.
&lt;/h3&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;h3 dir=&#34;ltr&#34;&gt;
  KVM稳定吗？
&lt;/h3&gt;
&lt;p&gt;****KVM非常稳定而且已经用于工作生产环境之中。对于所有的开始工程，开发版的稳定性总是逊于稳定发行版。建议使用稳定发行版。KVM已经被使用比较长一段时间，模拟常用的操作系统和配置。一但有问题出现，开发者会在第一时间修复。参看&lt;a href=&#34;http://www.linux-kvm.org/page/Guest_Support_Status&#34;&gt;Guest Support Status&lt;/a&gt;，列举了目前运行良好的操作系统。****zausiu’s blog &lt;a href=&#34;http://ykyi.net&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;h3 dir=&#34;ltr&#34;&gt;
  KVM真的可以用于生产环境吗？
&lt;/h3&gt;
&lt;p&gt;****为了稳定性，强列建议你使用你使用的发行版提供的KVM模块。如前面所述，及早使用新特性总是令人开心的事情。但是，你常常要要承担一定的风险，一些未知的问题可能在使用时暴露出来。在生产环境中，最好使用你使用的发行版提供的稳定版，而开发版本，如果你愿意，可以使用在不是那么重要的环境下。&lt;/p&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;h3 dir=&#34;ltr&#34;&gt;
  如果我用kill -9杀掉VM进程会发生什么事呢？
&lt;/h3&gt;
&lt;p&gt;****From the guest’s perspective, it is as if you yanked the power cord out. From the host’s perspective, the process is killed and all resources it uses are reclaimed.&lt;br&gt;
从客户虚拟机的立场来看，这就如同被拨掉了电源。从Host机的立场看，仅仅是VM进程被杀死了，这个VM进程所申请的所有系统资源被回收给操作系统。如前文所说，对于linux内核，VM进程就是一个普通的进程。&lt;/p&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;h3 dir=&#34;ltr&#34;&gt;
  请帮助我设置客户机的网络。
&lt;/h3&gt;
&lt;p&gt;****可以参考这里 &lt;a href=&#34;http://www.linux-kvm.org/page/Networking&#34;&gt;Networking&lt;/a&gt; 设置网站，也可以找找QEMU的网络设置相关文档。&lt;/p&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;h3 dir=&#34;ltr&#34;&gt;
  哪里有更多KVM的文档呢？
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;绝大多数问题都在QEMU的 &lt;a href=&#34;http://www.nongnu.org/qemu/user-doc.html&#34;&gt;documentation&lt;/a&gt;中被提到了，还有部分在扩展&lt;a href=&#34;http://qemu-buch.de/cgi-bin/moin.cgi/FrequentlyAskedQuestions&#34;&gt;FAQ&lt;/a&gt; ( 已经废弃的老板 &lt;a href=&#34;http://kidsquid.com/cgi-bin/moin.cgi/FrequentlyAskedQuestions&#34;&gt;FAQ&lt;/a&gt;).&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>KVM你问我答FAQ (一)</title>
      <link>https://ykyi.net/?p=502/</link>
      <pubDate>Sat, 09 Jun 2012 05:12:04 +0000</pubDate>
      <guid>https://ykyi.net/?p=502/</guid>
      <description>&lt;h3 dir=&#34;ltr&#34;&gt;
  使用KVM需要哪些准备？
&lt;/h3&gt;
&lt;p&gt;****你需要一台运行Linux的x86的机器。它的CPU是有VT技术支持的英特尔cpu或者有SVM（又常被称为AMD-V）支持的AMD的CPU.&lt;/p&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;h3 dir=&#34;ltr&#34;&gt;
  KVM支持64位的处理器吗？
&lt;/h3&gt;
&lt;p&gt;****KVM支持64位的处理器！此时，你可以运行32位或者64位的客户机。&lt;/p&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;h3 dir=&#34;ltr&#34;&gt;
  What is Intel VT / AMD-V / hvm?
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;英特尔VT，是什么？AMD-V又是什么？hvm是什么？&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.intel.com/technology/itj/2006/v10i3/1-hardware/6-vt-x-vt-i-solutions.htm&#34;&gt;Intel VT&lt;/a&gt; 和&lt;a href=&#34;http://www.amd.com/us-en/Processors/ProductInformation/0,,30_118_8826_14287,00.html&#34;&gt;AMD’s AMD-V&lt;/a&gt; 都指的是指令集扩展。它们在硬件层面帮助实现虚拟机管理技术。这种技术使得在虚拟机上运行的速度接近直接在真实机器上运行的速度。HVM是硬件虚拟机的缩写(Hardware Virtual Machine )则是一个生产商中立的词汇(vendor-neutral term)，它常常用来指代x86指定集扩展。&lt;/p&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;h3 dir=&#34;ltr&#34;&gt;
  从哪里得到KVM内核模块呢？
&lt;/h3&gt;
&lt;p&gt;****可以从这里获得 &lt;a href=&#34;http://www.linux-kvm.org/page/Getting_the_kvm_kernel_modules&#34;&gt;http://www.linux-kvm.org/page/Getting_the_kvm_kernel_modules&lt;/a&gt; 。&lt;/p&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;h3 dir=&#34;ltr&#34;&gt;
  我如何知道我的CPU支持Intel VT技术或者AMD-V技术呢？
&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;&lt;em&gt;如果你的Linux操作系统比较新，尝试以下的指令：&lt;br&gt;
. egrep ‘^flags.&lt;/em&gt;(vmx|svm)’ /proc/cpuinfo&lt;/strong&gt;&lt;/em&gt;*&lt;/p&gt;
&lt;p&gt;如果出现一些文字，那说说你的CPU支持虚拟化。你也可以在/proc/cpuinfo文件中找到处理器模块的名字，然后到供应商的网站上查询。&lt;br&gt;
注意：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如果安装了Xen hypervisor，为了防止被劫持，你在dom0和domU中都得不到这些输出。dom0和domU是Xen hypervisor的术语。如果你没有安装Xen，直接忽略。&lt;/li&gt;
&lt;li&gt;一些产商默认在BIOS定设中禁用了CPU的虚拟化支持。你需要先在BIOS中打开虚拟化支持。&lt;/li&gt;
&lt;li&gt;如果你用的是intel cpu，对于内核版本2.6.15以前的Linux，你得不到这样的输出。如果你用的是amd cpu，对于内核版 本2.6.16以前的linux，你得不到这样的输出。如果你不确定你的Linux内核版本，用#uname -r 命令查看。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;h3 dir=&#34;ltr&#34;&gt;
  出现 &amp;#8220;KVM: disabled by BIOS&amp;#8221; error 错误
&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Check if there is an option to enable it in the BIOS. If not, look for a more recent BIOS on the vendor’s web site.&lt;br&gt;
在BIOS设定在找找看有没有启用cpu虚拟化的选项，如果没有，去到主板厂商的网站上面看看有没有新的BIOS发布并支持打开cpu虚拟化，那么你需要刷新BIOS.&lt;br&gt;
注意：&lt;br&gt;
1.对于部分硬件(如 HP nx 6320)，你需要先关掉主机电源，再打开主机电源才能使BIOS中启用cpu虚拟化支持生效。&lt;br&gt;
2.BIOS的部分设定有可能与启用CPU虚拟化冲突。比如在Thinkpad T500上，启用Intel AMT技术会出现冲突。这样kvm-intel在载入时会抱怨”disabled by bios”错误。&lt;br&gt;
3. 在一些Dell的硬件中，你还需要禁用”Trusted Execution”，否则不能打开VT。&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>在嵌入式系统部署虚拟化的八大理由</title>
      <link>https://ykyi.net/?p=489/</link>
      <pubDate>Fri, 08 Jun 2012 08:52:06 +0000</pubDate>
      <guid>https://ykyi.net/?p=489/</guid>
      <description>&lt;p&gt;在服务器和桌面上部署虚拟化已经越来越流行。但是大多数一定没有想过在嵌入式环境下部署虚拟化。&lt;/p&gt;
&lt;p&gt;Hypervisor(又被称之为虚拟机管理程序virtual machine monitor)如今已经在这颗星球上所有的数据中心遍地开花。因为它给数据中心带来了节省硬件，节省能源的费用，还降低了管理的成本。事实上，从兆兆级的路由器到富媒体的机顶盒，再到手机等等嵌入式系统，它们同样能从虚拟化中受益。 &lt;a href=&#34;http://ykyi.net&#34;&gt;zausiu’s blog http://ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;因为嵌入式系统的资源非常有限。它们还通常是定制的系统，软硬件紧密结合在一起。初看来，在嵌入式设备中部署虚拟化显得过于隆重。但下文告诉你在嵌入式设备中部署虚拟化的八大理由。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;更坚固&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;定制的硬件是非常昂贵的，如果把多种物理设备集成到一起就能降低成本。集成在一起当然比分布式的环境要简单得多。如果所有的虚拟机运行在相同的服务机上，划分网络的风险就不存在了，硬件故障也有了‘原子性’(hardware failures are atomic)，而且在虚拟化环境下已经有非常成熟的解决方案处理硬件故障，这样的故障通常会让没有部署虚拟化的系统崩溃。&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;更安全&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;试想，如果一个部署了java虚拟机的手机系统把java stack和通讯栈运行在两个虚拟机上。那么即使应用程序管理部分被攻破了，也不会危险到通迅栈。对于恶意代码，虚拟机环境是一个大沙箱。&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;更可靠&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;通过虚拟化可以把特权代码和一般代码分开，能够阻止和减少整个设备的故障率。&lt;/p&gt;
&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;易于管理和开发&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;即使是运行实行操作系统，你不要因为那些非常有限的管理功能就心满意足了。一个运行windows的负责管理功能的虚拟机能够运行图形介面的程序，方便了用户也方便了开发者。&lt;/p&gt;
&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;硬件虚拟化&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;VMM相当适合硬件虚拟化。它连同虚拟控制器一起动态的切分或者合并物理资源。对于大型的，分布式的嵌入式设备如路由器则可以在部署了虚拟化的情况下自由的切分或合并。&lt;a href=&#34;http://ykyi.net&#34;&gt;Zausiu’s blog http://ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;ol start=&#34;6&#34;&gt;
&lt;li&gt;效率&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;单核世界已经快速离我们远去，即将消失在历史长河中。而大多数嵌入式软件没有充分利用多核或多处理机的优势。那么，虚拟化帮助系统充分利用嵌入式系统的性能。&lt;/p&gt;
&lt;ol start=&#34;7&#34;&gt;
&lt;li&gt;新特性&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一些振奋人心的超酷特性，如：快照，实时迁移(live migration)，External Hibernation能够加强嵌入式设备的可用性，且方便可级。&lt;/p&gt;
&lt;ol start=&#34;8&#34;&gt;
&lt;li&gt;法律问题&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;从商用专有代码连接GPL代码会被迫遵守GPL协议。而把GPL代码运行在虚拟机上就可以规僻GPL协议的约束了。&lt;/p&gt;
&lt;p&gt;这篇文章译自： &lt;a href=&#34;http://www.linuxplanet.com/linuxplanet/reports/6490/1&#34;&gt;http://www.linuxplanet.com/linuxplanet/reports/6490/1&lt;/a&gt; 这八大理由中的很多条目我觉得没有说服力！&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux的虚拟化技术 KVM 和 QEMU</title>
      <link>https://ykyi.net/?p=484/</link>
      <pubDate>Thu, 07 Jun 2012 17:36:55 +0000</pubDate>
      <guid>https://ykyi.net/?p=484/</guid>
      <description>&lt;p&gt;Linux 2.6.20发布以后。一个称之为KVM的非常优秀的虚拟化框架加入了linux代码主干。KVM是Kernel-based Virtual Machine的首字母简写。这篇文章将在理论层面和实践层面都会简单介绍KVM是如何工作的。&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;简单的理论背景：&lt;br&gt;
目前有几种虚拟化的方式。&lt;br&gt;
其中一种称之为准虚拟化(para-virtulization)。使用准虚拟化的时候，为了达到虚拟化的目的，客户机系统必须被修改。修改后的客户机知道它运行在虚拟的环境中，与虚拟机管理程序(Supervisor)协同工作。这样的好处理较之全虚拟化，性能上有一定的优势。&lt;br&gt;
另一种称之为全虚拟化(full virtualization)。使用这种技术则不需要修改操作系统。但相对于准虚拟化技术，全虚拟代技术牺牲了一些性能。因为没有客户机OS的参于，是非常困难得到很高的虚拟化效率的。但自从CPU产商在硬件层面推出虚拟化支持的时候，情况就不一样了。如Intel的VT，AMD的AMD-V虚拟化技术。KVM就是利用了CPU的虚拟化支持技术实现了。并且KVM作为linux内核的一个模块加载，天然继承了linux内核的诸多优势。基于KVM的虚拟机，被当成一个标准的Linux进程被Linux内核调度。这个KVM虚拟机看到的都是虚拟的硬件。对于一个标准的Linux进程，有两种运行模式：内核态和用户态。KVM给虚拟机进程加入了第三个模式：客户模式(guest mode)。而客户模式又有它自己的内核态和用户态。&lt;/p&gt;
&lt;p&gt;KVM包括两部分组件：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一个设备驱动程序用来管理虚拟化硬件。这个驱动是一个字符驱动，用来管理虚拟化硬件(for managing the virtualization hardware)。&lt;/li&gt;
&lt;li&gt;一个用户空间运行的模拟器。通常选择QEMU稍作修改。QEMU是由一个叫Fabrice Bellard的法国黑客写的。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;KVM与QEMU实战,在linux下安装windows xp：&lt;/p&gt;
&lt;p&gt;前期准备，需要安装KVM和QEMU.另外还有保证你已经编译了内核。&lt;br&gt;
真正的安装超级简单。&lt;br&gt;
第一步：# qemu-img create hda.img -f qcow 6G&lt;br&gt;
第二步: # kvm -no-acpi -m 256 -cdrom winxpsp2.iso -hda hda.img -boot d&lt;/p&gt;
&lt;p&gt;下面简单的解释下。&lt;br&gt;
第一步创建了一个虚拟磁盘（实际上就是文件系统上一个文件而已，不过话又说回来，unix的哲学就是所有的东东都是文件。）这条命令选择了QEMU的写时复制策略。这使得这个文件会按需增长。所以一开始这个文件不会太大，以后随着你的虚拟xp占用的空间增大而增大。不过这条命令把大小限制到第大6G.&lt;br&gt;
第二步：指定了win xp的镜像文件就开始安装啦！喔，这条命令使用了 -no-acpi 开关。据说acpi在QEMU中支持的不够好。不过我觉得问题应该得到解决了吧，所以也可以不用 -no-acpi。ykyi.net&lt;/p&gt;
&lt;p&gt;于是就装好啦！真的非常简单啊~~&lt;br&gt;
于是你就可以用这个虚拟的xp做一些你不愿意在真实OS上作的测试啦！或者使用只有在win下的软件。&lt;/p&gt;
&lt;p&gt;转贴请注明出处 &lt;a href=&#34;http://ykyi.net/2012/06/linux%E7%9A%84%E8%99%9A%E6%8B%9F%E5%8C%96%E6%8A%80%E6%9C%AF-kvm-%E5%92%8C-qemu/&#34;&gt;http://ykyi.net/2012/06/linux%E7%9A%84%E8%99%9A%E6%8B%9F%E5%8C%96%E6%8A%80%E6%9C%AF-kvm-%E5%92%8C-qemu/&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux用两种信号量 Linux has two kinds of semaphore</title>
      <link>https://ykyi.net/?p=480/</link>
      <pubDate>Tue, 05 Jun 2012 12:24:40 +0000</pubDate>
      <guid>https://ykyi.net/?p=480/</guid>
      <description>&lt;p&gt;面试中经常会考什么是信号量，对于linux,实际上有两种semaphore.&lt;/p&gt;
&lt;p&gt;第一种是指一种IPC(Inter-process communication进程通讯)的方法。这种IPC是从Unix SYstem V时代开始的，System V发布时加入了三种IPC，它们是semaphore信号量，message queues消息队列，shared memory共享内存。&lt;/p&gt;
&lt;p&gt;Linux中另一种Semaphore是内核用来同步的机制。在kernel中，semaphore通常当成一个二值信号量使用。获得信号量时有可能会睡眠，这样进程就会被调度开，放弃处理机；如果某段内核代码得到了一个信号量，这段代码还可以睡眠。这点不像spinlock，尝试得到spinlock会不停地忙等，得到spinlock后不充许睡眠。当然这个“不充许”不是语法层面的，而是应该被程序员遵守。否则整个系统的的性能就会被这代不遵守约定的代码毁掉了。&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>内核线程是什么东东 What is Kernel threads</title>
      <link>https://ykyi.net/?p=476/</link>
      <pubDate>Tue, 05 Jun 2012 05:45:13 +0000</pubDate>
      <guid>https://ykyi.net/?p=476/</guid>
      <description>&lt;p&gt;有一些Unix内核，比如Solaris和SVR4.2/MP，被组织成一些内核线程。一个内核线程是一个执行上下文且可以被调度；这样的内核线程可能与一个用户程序相关联，也有可以只执行一些内核函数。上下文切换的时候，切换内核线程上下文的开销远比切换用户进程上下文的开销要小。因为内核线程通常共用一个地址空间。而&lt;strong&gt;Linux的内核线程&lt;/strong&gt;则有不同。Linux的内核线程仅仅周期性的执行一个内核函数。而且，Linux内核进线程并不表示一个基本的可执行上下文。 zausiu&amp;rsquo;s blog. &lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some Unix Kernels, such as Solaris and SVR4.2/MP, are organized as a set of kernel threads. A kernel thread is an execution context that can be independently scheduled; it may be aasociated with a user program, or it may run only some kernel functions. Context switches between kernel threads are usually much less expensive than context switches between ordinary processes, because the former usually operate on a common address space. Linux uses kernel threads in a very limited way to execute a few kernel functions periodically; however, they do not represent the basic execution context abstractions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>十个选择Oracle Linux而不是RedHat企业版Linux的原因</title>
      <link>https://ykyi.net/?p=431/</link>
      <pubDate>Sun, 27 May 2012 06:19:36 +0000</pubDate>
      <guid>https://ykyi.net/?p=431/</guid>
      <description>&lt;p&gt;Linux&lt;span style=&#34;font-family: 宋体;&#34;&gt;在当今基于云的解决方案中被普通采用。而&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;Oracle Linux&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;目前最完整的集成解决方案。它提供了高性能和高可靠性，却只是选择&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;Redhat Linux&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的花费的&lt;/span&gt;&lt;span style=&#34;font-family: Arial;&#34;&gt;1/7&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 译！&lt;/p&gt;
&lt;p&gt;原因一: Oracle Linux成本低：&lt;/p&gt;
&lt;p&gt;Oracle Linux可以自由下载和部署。&lt;/p&gt;
&lt;p&gt;对Oracle Linux的支持订阅(Support Subscription)非常简单且价格便宜。&lt;/p&gt;
&lt;p&gt;支持花费(Support costs)不到Redhat的七分之一。&lt;/p&gt;
&lt;p&gt;你不能够下载Redhat Ent Linux，除非你购买了Support Subscription。&lt;/p&gt;
&lt;p&gt;而Redhat Ent Linux的订阅以及插件的价格都很贵。&lt;/p&gt;
&lt;p&gt;Redhat Ent Linux的授权许可证非常的复杂。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;原因二: Oracle Linux已包含管理工具。&lt;/p&gt;
&lt;p&gt;Oracle Linux支持用户使用免费的Oracle Linux服务器的生命期管理工具，这个工具相当于Redhat的卫星服务以及相关模块。&lt;/p&gt;
&lt;p&gt;同样的Oracle企业管理者工具也能被授权管理从应用到磁盘的整个解决方案。&lt;/p&gt;
&lt;p&gt;而红帽的卫星服务器用户则需要分别为每台服务器都申请许可证。可想而知，花费要高很多。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;原因三：Oracle Linux的高有效性。&lt;/p&gt;
&lt;p&gt;Oracle Linux includes OCFS2 and Oracle Linux Basic and Premier Support subscribers have free access to Oracle Clusterware&lt;/p&gt;
&lt;p&gt;Red Hat charges separately for add-ons that include clustering software for HA&lt;/p&gt;</description>
    </item>
    <item>
      <title>怎么订阅Linux内核邮件列表</title>
      <link>https://ykyi.net/?p=425/</link>
      <pubDate>Sun, 20 May 2012 06:07:40 +0000</pubDate>
      <guid>https://ykyi.net/?p=425/</guid>
      <description>&lt;p&gt;官方页面：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://vger.kernel.org/majordomo-info.html&#34;&gt;http://vger.kernel.org/majordomo-info.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As of now, subscription support is &lt;em&gt;not&lt;/em&gt; handled at the web!&lt;/p&gt;
&lt;p&gt;从现在开始，订阅操作不在通过web方式操作啦。&lt;/p&gt;
&lt;p&gt;All VGER list control activities (joining and leaving, that is) are handled via email server at address:&lt;/p&gt;
&lt;p&gt;所以的VGER列表的操作都通过邮件的方式搞定。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;majordomo@vger.kernel.org&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;All email sent to there &lt;strong&gt;must&lt;/strong&gt; be &lt;strong&gt;TEXT/PLAIN&lt;/strong&gt;, there can be no multipart messages, no VCARDs, nothing “fancy&amp;rsquo;&amp;rsquo;. In presense of such things, Majordomo will very likely do wrong thing.&lt;/p&gt;
&lt;p&gt;所以的邮件都必须以纯文本发送。不需要multipart message，不需要VCARD，不需要花哨的东东。如果你违反了，Majordomo系统就会出错。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: red;&#34;&gt;When you send there email, &lt;strong&gt;do make sure&lt;/strong&gt; that all of the email headers, both visible and transport level, have &lt;strong&gt;same&lt;/strong&gt; addresses in them. People experience problems when for example “From:&amp;rsquo;&amp;rsquo;, “Sender:&amp;rsquo;&amp;rsquo; and possible “Reply-To:&amp;rsquo;&amp;rsquo; headers present different addresses. &lt;strong&gt;The most common manifestation is complete &lt;em&gt;silence&lt;/em&gt; from VGER!&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>我的梦想.(卓越领导力三千字结课作业)</title>
      <link>https://ykyi.net/?p=422/</link>
      <pubDate>Sat, 12 May 2012 14:06:50 +0000</pubDate>
      <guid>https://ykyi.net/?p=422/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
                 我的梦想
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    虽然我的梦想没有马丁路德那么伟大，在我人生的每个阶段，我也有我的梦想。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    读幼儿园之前和幼儿园时代，我的梦想是参军打仗，因为我看到的电视画面中的士兵很英勇，战争很吸引我。我要杀光所有坏人，保卫祖国！没错，小时候我的梦想竟然是要做一个血淋淋地杀人机器。现在想来真是不靠谱啊，歌舞升平的和平年代，打打杀杀什么呀？难道我要加入基地组织吗？或者去非洲参加雇佣军？
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    后来顺利进入小学了。虽然当时也没预见到以后国内会无仗可打，出国打仗也会毫无希望，但我确实果断放弃了以后要参军打仗的梦想。因为我突然发觉我更愿意以后做一名数学家！擦，数学家啊！！！吓死人咩！！！仅仅因为我喜欢做数学题，做同龄人做不出来的数学题，考试数学考高分，参加数学竞赛，老师表扬，同学羡慕。因些而得来了无限荣光和急剧增长的成就感，我当想就想了。以后我要成为数学家，天天解题！那时哥要是知道微积分，极数啊，场论啊，复变函数啊什么的长什么模样，我怎么会想当数学家啊！
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    进入中学后，数学不再仅仅是玩一些算术的小把戏了，曾经在小学时代鄙视用方程解应用题的我一度变得迷惑了，数学竟然还可以这样玩的呀。要做数学家的梦想慢慢地就被磨灭了。中学时代时要么不是想着放学后打电脑游戏，要么就是要准备升学考试或者各种什么什么考试了。我也就对未来梦想这种宏大飘渺的主题变得没什么兴趣。在三日一小考，一月一大考的中学生活中，考出好成绩，不用被父母老师骂才是最朴实最生动的梦想呀！
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    上到大学后，我的私人时间瞬间变得充足起来，使我有时间和精力构思对未来的梦想。在这个从少年成长到青年的关键时期，随着社会经历的慢慢丰富，梦想变得切实可操作了。大学时的梦想相当的务实，即是毕业后能像表哥那样成为一位出色的软件工程师。更具体一点，是游戏了开发工程师。现在回想，我那时真不知道架构师，工程师和码农的区别。言归正传，为了实现我小小的梦想，我在整个大学阶段确实非常用功地学习，很多同学晚上都在宿舍玩游戏，我仍然坚持去晚自习。毕业前已经写出了好几个在同龄学生中极具竞争力的&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;PC&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;游戏。所以，凭借我写的几个游戏作品，在大四时我毫不废力的找到了游戏开发的工作。我还记得刚到游戏开发公司上班时的兴奋心情。我想，这能算得上是实现了一个小小梦想吧。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    但我的游戏开发的梦想很轻易地破灭了，而且经受的打击颇大。从那时我体会到一句话：当兴趣变成工作的以后，就大不一样了。现在回想当时对公司的失望以至对整个游戏开发行业的失望主要缘于自己的见识不够，不知道一家大型的游戏公司和小作坊型的游戏公司有相当大的差别。另外，在从学生到职业人的角色转变过程中相当地不适应。事实上，那时是有相当多的机会的呀！还有一个因素即是因为大学阶段因为在不恰当的时间帮助同学提高成绩，我的学位证被学校取消了。在毕业后的时间里，心里经常有一种失落时不时的跳出来，那就是有一天要回学校读完硕士，了结大学时没有学位证的心愿。在毕业后来到社会之中摸爬滚打的几年里，我渐渐形成了要创办自己的实业的想法。经过长年不间断的学习，我在&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;IT&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;技术上积累的技术已经相当全面。另外也从来没有间断过学习英语，英语水平一直在持续提高，生活阅历也更加丰富了。我的梦想，就是要有自己的实业，很可能是&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;IT&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;科技公司，再有其它投资组合，最终能让我实现财务自由。我把财务自由定义为，即使我每天睡大觉，我以前的劳动创造的各种盈利方式都能够帮我创造财富，带来现金流。实现财务自由后就可以做&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;N&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;多自己想做的事情啦！起码具备了周游世界的最基本的经济基础。在这个指导思想的指引下，我创办了一个小网站。半年后这个小网站开始盈利了，虽然很少，不过这正是我想要的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Earning Machine&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的模型啊！即使我后来基本不去管网站，它也一直在给我创造经济收益。第一次拿到谷歌寄来的美金支票，非常开心！我做的是一个简单的粤语歌词网站，给歌词附上了粤语注音，用户点击后可以听到单个字的粤语读音。这样一个简单的网站每个月可以给我带来一百元左右的收入。我想，如果我能把流量括大一百倍，那每个月就轻松有一万元收账嘿嘿。仅仅就这个非常简陋的小网站来讲，我觉得把流量括大一百倍并没太大问题。因为我还没有围饶社交网络做推广，也没有给网站做用户体验，还有很多功能也没有做。而我观察的一个类假的相关网站的网络流量竟然是我的几百倍。我觉得如果投入时间就能超越它。但我没有继续做下去！不是我没有执行力，我不太想做&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;WEB&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;方面，我做做&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ARM&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;嵌入式方面，我觉得在这方面一定会有更多更好的机会。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    去年下半年又返学校读书了，明年六月能顺利毕业。届时就能完成本科时的小小心愿，某种程度上也算是圆一个小小的梦想。在中大读软工硕士的时间里，仍然疯狂地学技术和英语，并跟进日新月异的&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;IT&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;业界的新闻。脑子里基本上有一些想法，我还需要认识更多的高手，除了互联网领域肯定还有其它方面的创业方向。昨天晚上，与一位以前在毒霸时相识的老同事聊天。它是位出色的逆向高手，离开珠海后，他在广州与朋友创办了一家做网页游戏的游戏公司，撑了近一年经营不下去。于是他去了深圳腾讯做回逆向工程老本行，但他只在腾讯做了七个月又离职了，和朋友去上海二次创业，仍然做网页游戏。他说他离职的原因就是放不下他心中的梦想。其实我也一样。在人生的每个阶段，不间断地为实现心中的梦想而努力这应该是人生的部分意义吧。如今，我思考我与我的梦想的距离。我具备了很广泛的计算机知识，从硬到软，从网络到桌面到&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;WEB&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;到嵌入式，具备了相对不错的英文水平。但我还欠缺广泛的优质的人脉关系，这方面还需要不断的积累。今年下半年，我会找我感兴趣的方向的兼职，希望能认识一些优秀的朋友。我们之间分享信息和体会，互相为实现各自的梦想提供支持。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    我非常希望能在四十岁前能实现财务自由梦想。虽然这样的想法听起来太多务实，还带着一点铜臭味。但我却也无需过多解释，每个人都能够理解。我是普通人，我只希望能给家人带来健康和幸福，希望有能力帮助保护我身边重要的人，所以我务实，而不是关注世界和平，关注拯救地球，关注消灭战争和贫困。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    如果财务自由的梦想不能实现呢？于是我一直在工薪层卖不断出卖劳动力生活，终未能实现目标呢？虽然为了实现梦想，我们当然要付出百倍的努力，但成功往往不仅仅受制于主动的努力程度，也受制于客观的各种不可抗条件。所以，对于每一个心怀梦想的年轻人，我觉得都应该有良好的心态面对可能的失败。我会努力追逐我的梦想，但如果做不到，我觉得不能丢掉两样东西，一件是乐观的心态，另一件是健康的身体。这两件东西是能完成任何一个目标的最低配置。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    如果我能及时实现财务自由我梦想。那我一定要开始我的周游列国之旅，还要认真学一门乐器，这才是真正的生命哈哈！在充分的实现的实现了自我价值的同时，我一定会把更多精力投入到回报社会中来。想想比尔盖茨的故事。比尔盖茨在今年年初《高端访问》节目上如此表示，&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;“&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;我的新梦想是希望能够平等地对待生命，人们消除了偏见，让这个世界变得更加公平。希望&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;20&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;年后，我所提到艾滋病、疟疾、结核病等重大疾病都彻底的消失，让贫困国家的人民摆脱贫困，获得公平对待的机会&lt;/span&gt;。”很多富有的西方商界人士在功成身退后都会把很多精力用于经营慈善基金。这大概是因为基督教主张账富源于社会，又要回报社会。我不信仰基督教，我也不会有比尔盖茨那样成功，但我非常认同这样的普世价值观，我也会力所能及的回报社会。或许我可以做义工，也可以资助贫困地区的教育。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    希望我能有幸实现我的一个又一个梦想！
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    (&lt;span style=&#34;font-family: 宋体;&#34;&gt;完&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;)&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>想钱想疯了.</title>
      <link>https://ykyi.net/?p=419/</link>
      <pubDate>Thu, 19 Apr 2012 05:35:29 +0000</pubDate>
      <guid>https://ykyi.net/?p=419/</guid>
      <description>&lt;p&gt;昨晚梦见自己开了一辆敞篷跑车~~&lt;/p&gt;
&lt;div&gt;
  好奇怪呀。我从来都对小车不感兴趣呢。
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
  三年前。珠海。与我同一天生日的一个好同事也离职了，准备去上海。
&lt;/div&gt;
&lt;div&gt;
  他说：“我要买辆兰博基尼”。
&lt;/div&gt;
&lt;div&gt;
  我居然不知道兰博基尼是什么。~~
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
  好久之前就想：我要创造出好几个Earning Machine。于是不管你到处游玩，做各种自己想做的事情，Earning Machine都会自动给你带来收益。啊哈哈哈~~自由啊！！！在这一指导思想下，确实实现了一个小小的试验性质的小案例，称之为Earning Machine Version I，但实在实在太少收益了。多次考虑过增强这个版本，但要投入太多时间，更有说服力的原因是在这个过程中积累的技术经验是我不感兴趣的方面。我还是面向技术的思维方式啊！
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
  学校的生活令我相当地满足呢，除了经常想到持续减少的银行账户余额，感到严重没有安全感。
&lt;/div&gt;
&lt;div&gt;
  这种不安是我疯狂看书的动力之一。我迫切希望快点完成读书的计划，在下半年再回到社会，找个工作，认识一班新朋友，或许能够有更多的思路实现Earning Machine Version II。
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
  之前还想，如果读博士学位，成为某个方面的资深专家，能不能把读博时的成果转化成巨大的经济收益呢？我问Dr. Woo，你能把你的学术成果转化成真金白银吗？Dr. Woo说现在很难。
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
  两三天前，广州好热好热。我以为夏天到了，于是把被子收了起来，铺上凉席。结果当天晚上就下雨又天冷了。靠~~连续三天五早晨时被冻醒，于是穿多件衣服睡，其实也满舒服的！！！应该再过几天又会很热了~~
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
  哎。时间资源实在太有限了。我下载了The Secret的英文原版打印出来了，才看了不到15页。买了笛子入门基础书，看了不到5页，有些东西看不懂。
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
  还有一个月就要考BEC高级了，希望自己能通过。应该能够通过吧~~我想！！！所以，暂时英语优先级最高分到最多时间资源，专业技术优先级其次，其它事情就放放吧~~~
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
  虽然阴沉沉地下着雨，去图书馆的路上却心情非常不错，因为觉得很满足，我在做我想做的事情！
&lt;/div&gt;</description>
    </item>
    <item>
      <title>写了一个输粤拼查汉字的功能</title>
      <link>https://ykyi.net/?p=415/</link>
      <pubDate>Tue, 03 Apr 2012 07:00:11 +0000</pubDate>
      <guid>https://ykyi.net/?p=415/</guid>
      <description>&lt;p&gt;虽然只是个小小的功能。但写出来却也不是一两个小时的事情，写了四个小时才写完~~~有个缺陷就是：对多音字支持得不够好~~&lt;/p&gt;
&lt;p&gt;主要技术障碍来自于对javasript不熟悉，用firefox浏览器调试时浏览器总是缓冲旧的javascript文件。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net/jyutping2char.php&#34;&gt;http://ykyi.net/jyutping2char.php&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;一直以来都有网友抱怨没有办法发音~ 这是因为目前的发音是通过flash技术实现的，但很多手机平台上的浏览器不支持flash技术，比如苹果的移动平台就不支持flash。&lt;/p&gt;
&lt;p&gt;鉴于HTML5是未来互联网的行业标准。我在计划写一个HTML5的版本。但是没有时间表约定~我也不知道什么时候可以完成。&lt;/p&gt;</description>
    </item>
    <item>
      <title>SWOT分析法</title>
      <link>https://ykyi.net/?p=411/</link>
      <pubDate>Tue, 20 Mar 2012 12:26:41 +0000</pubDate>
      <guid>https://ykyi.net/?p=411/</guid>
      <description>&lt;p&gt; &lt;/p&gt;
&lt;div&gt;
  SWOT
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  SWOT分析法又称态势分析法。早在20世纪80年代初由旧金山大学的管理学教授提出，它是一种能够较客观而准确地分析和研究一个单位现实情况的方法。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  S.W.O.T.分别是是英文单词STRENGTHS(优势)，WEAKNESSES(劣势)，OPPORTUNITIES(机会)，THREATS(威胁)的首字母缩写。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  其中竞争优势S可以是：技术技能优势，有形资产优势；无形资产优势；人力资源优势；组织体系优势；竞争能力优势。竞争劣势W可以是：缺乏具有竞争意义的技能技术；缺乏有竞争力的有形资产；无形资产；人力资源；组织资产。企业中的机会O可以是：客户群的扩大趋势或产品细分市场；技能技术向新产品新业务转移，为更大客户群服务；前身或后向整合；市场进入壁垒降低；获得购并竞争对手的能力；市场需求增长强劲，可快速扩张；出现向其他地理区域扩张，扩大市场份额的机会。企业生存的外部威胁可以是：出现将进入市场的强大的新竞争对手；替代产品抢占公司的销售额；主要产品市场增长率下降；汇率和外贸政策的不利变动；人口特征，社会消费方式的不利变动；客户或供应商的谈判能力提高；市场需求减少；容易受到经济萧条和业务周期的冲击。其中的SW属于内部因素，OT属于外部因素。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  企业进行SWOT分析时先罗列组织的内部优势和劣势，外部可能的机会与威胁。其次，对SO，ST，WO，WT策略进行甄别和选择，确定组织目前应采取的具体战略与仿真；优势、劣势与机会、威胁相组合，形成SO、ST、WO、WT策略。一共三个阶段。更详细的展开说。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  在第一阶段运用各种调查研究方法，分析出公司所处的各种环境因素，即外部环境因素和内部能力因素。外部环境因素包括机会因素和威胁因素，它们是外部环境对公司的发展直接有影响的有利和不利因素，属于客观因素，内部环境因素包括优势因素和弱点因素，它们是公司在其发展中自身存在的积极和消极因素，属主动因素，在调查分析这些因素时，不仅要考虑到历史与现状，而且更要考虑未来发展问题。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  在第二阶段构造SWOT矩阵。将调查得出的各种因素根据轻重缓急或影响程度等排序方式，构造SWOT矩阵。在此过程中，将那些对公司发展有直接的、重要的、大量的、迫切的、久远的影响因素优先排列出来，而将那些间接的、次要的、少许的、不急的、短暂的影响因素排列在后面。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  在第三阶段制定行动计划。在完成环境因素分析和SWOT矩阵的 构造后，便可以制定出相应的行动计划。制定计划的基本思路是：发挥优势因素，克服弱点因素，利用机会因素，化解威胁因素；考虑过去，立足当前，着眼未来。 运用系统分析的综合分析方法，将排列与考虑的各种环境因素相互匹配起来加以组合，得出一系列公司未来发展的可选择对策。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  总言之：SWOT是一种分析方法，用来确定企业本身的竞争优势，竞争劣势，机会和威胁，从而将公司的战略与公司内部资源、外部环境有机结合。因此，清楚的确定公司的资源优势和缺陷，了解公司所面临的机会和挑战，对于制定公司未来的发展战略有着至关重要的意义。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>gcc的-E选项什么意思</title>
      <link>https://ykyi.net/?p=408/</link>
      <pubDate>Wed, 22 Feb 2012 05:37:54 +0000</pubDate>
      <guid>https://ykyi.net/?p=408/</guid>
      <description>&lt;p&gt;gcc的-E选项可以为你生成预编译后的文件。预编译后的文件将把c文件中的宏以及该文件包含的所有头文件展开。这样就没有了一层一层进入嵌套包含的头文件。下面是一个使用gcc的-E选项的例子。&lt;/p&gt;
&lt;p&gt;下面是来自gcc mannual page的解释：&lt;/p&gt;
&lt;p&gt;-E Stop after the preprocessing stage; do not run the compiler proper. The output is in the form of  preprocessed source code, which is sent to the standard output. Input files which don&amp;rsquo;t require preprocessing are ignored.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;$ gcc -E drivers/char/mydrv.c -D__KERNEL__ -Iinclude -Iinclude/asm-x86/mach-default &amp;gt; mydrv.i&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;其中的-I选项告诉编译器在哪些目录中搜索所需要的头文件。&lt;/p&gt;
&lt;p&gt;还可以用gcc的-S选项生成汇编码的文件。如：&lt;/p&gt;
&lt;p&gt;$ gcc -S drivers/char/mydrv.c -D__KERNEL__ -Iinclude -Ianother/include/path&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt;ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>读论文 宏观层面的软件演化</title>
      <link>https://ykyi.net/?p=404/</link>
      <pubDate>Wed, 22 Feb 2012 05:30:46 +0000</pubDate>
      <guid>https://ykyi.net/?p=404/</guid>
      <description>&lt;p&gt;软件工程进展读论文报告&lt;/p&gt;
&lt;p&gt;论文：Macro-level software evolution: a case study of a large software compilation (宏观层面的软件演化：举例研究一个大型软件的编译)于2008年11月29号发表于实证软件工程。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;论文的背景和动机：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;软件演化(Software Evolution)一般研究的是由相互合作的团队开发的单个的软件产品。但是越来越多的软件系统包含了大量了不同的应用和运行库。很多这些应用和运行库是由不同的团队面向不同的目的开发的。这种大型软件系统是如何演化的呢？他们有些什么特性特点呢。但要研究这样的大型软件系统需要有这个系统所涉及的所有应用和库在各个时间点的源代码。这并非一件易事。因此才鲜有研究文献涉及该类型的系统。&lt;/p&gt;
&lt;p&gt;这些年，很多大型自由软件系统取得了巨大成功，例如Fedora Linux, Debian GNU/Linux, FreeBSD, OpenBSD。这些大型自由软件集成成百上千独立应用和库，并且几乎所有自由件的授权都充许自由得到相应的源代码。这为我们研究大型软件系统的演化提供了必要条件。&lt;/p&gt;
&lt;p&gt;构成大型软件系统的各个工程是独立开发的(某些软件系统把这些独立开发的工程称之为包)，但从整个软件系统的视角来看，它们之间却存在复杂的依存关系，甚至在某些情况下会是冲突关系。因此，单个的研究某特定工程的演化与在整个软件系统中研究软件的演化是不同的。&lt;/p&gt;
&lt;p&gt;论文旨在通过分析一个大型自由软件系统的演化来揭示大型自由软件系统的一般规律以至私有大型软件的某些规律和特点。&lt;/p&gt;
&lt;p&gt;论文中实证研究的定义、规划、执行与分析：&lt;/p&gt;
&lt;p&gt;Debian GNU/Linux是一个非常流行的大型软件系统。它包括了各种大大小小的应用和库，其中一些演化的非常迅速，其中一些又长期没有变化，不断有新的包加入该系统又不断有过时的包被抛弃。仅管这些包是相互独立开发并自我演化，但在Debian系统中，它们之前有着非常复杂的关系。这个复杂关系随着Debian系统的演化而变得更加复杂，使之越来越难以维护。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[定义]&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这篇论文，即以Debian软件系统为例，主要考察了九年以来Deiban系统中包的总数，包的大小，开发语言，包之间的相互依赖性等多个指标，在宏观上研究整个Debian软件系统的演化。最终得出一些大型自由软件的特点，分析这些特点能指导单独的软件研发使之能更好的集成进大型系统中。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[规划和执行]&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Debian组织成一个个包(package)，一般地讲每个包对应于一个应用或一个库，少数情况下对应于文档或其它。包分两种，一种是包含运行的二进制文件的包，另一个是源文件包。源代码包在构建以后通常生成一个或多个二进制包。Debian为每一个发行版本维护了一系列配置文件，这些配置文件设定了每个发行版所需要的运行环境，包含了哪些包。而每个包的配置文件也约定了它所依赖的其它包的关系。&lt;/p&gt;
&lt;p&gt;这份报告研究了Debian从2.0到4.0的所有稳定发行版号，即2.0,2.1,2.2,3.0,3.1,4.0。对于每一个待考察的版本，配置文件被事先写好的脚本分析，把分析到的数据存入数据库中。然后，每一个源码包被自动获取，源代码行数被SLOC工具分析得出；源代码所使用的编程语言也用SLOC工具识别到。而包与包之间的依赖性亦可由Debian发行版的配置文件中记录的Depends,Pre-Depends,Suggests,Recommends字段得到。这些信息被分析出来以后，包与包之间的依赖关系由一个有向图描述出来。有向图中的结点表示一个包，连接结点的边表示包与包之间的依赖关系。每个待研究的Debian发行版都会生成一个这样的IDG(Inter-Dependency Graph)，通过运用有向图的算法可以得到很多研究关心的数据，比如最流行的包(The most popular package)。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[分析]&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;发行版总大小&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;结果显示每隔两年，发行版的大小(统计发行版的所有源代码行数)就会增加一倍。截止2007年的Debian 4.0，已经共有4亿行代码和1万个包。如此大的规模会为未来的继续发展带来不小的麻烦，在最新的发行版中已经可以看到超大规模的几数级增长已经给某些时间点带来了延迟。&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;包的大小&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;而包的平均大小指标在九年内几乎维持不变。因为软件系统的总代码量迅速增长而平均包大小不变，这意味着越来越多的包被增加到系统中。Debian .4.0的包数目是Debian 2.0的包数目的10倍。为了应对包的不断增多，Debian系统需要迅速增加包维护者以及每个维护者需要应对的包数目。包数目的迅速增长也是一个非常棘手的问题，特别影响了包维护者的相互配合。&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;包的维护&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Debian维护者的任务之一就是跟踪新版本的软件包，给它们重新打包，更新相应的包描述。一但一个新版本的包发布了，包的名字就会相应变化。因此可以通过分析发行版的包的名称确定软件包有没有被维护过。&lt;/p&gt;
&lt;p&gt;分析数据后显示Debian 2.0的1096个包里面有721个可以在4.0中找到。这意味着Debian2.0中只有30%的包在九年后的Debian 4.0中被移除。再之，Debian 3.1的10106个包中，而在4.0中仍然存在的有7300个，这个比例也大概是30%。&lt;/p&gt;
&lt;p&gt;对于没有改变过的包。Debian 4.0中有132个包与Debian 2.0中毫无改变。换言之，Debian 2.0中不少于15%的包在九年后仍然没有任何改变在Debian 4.0中。&lt;/p&gt;
&lt;p&gt;必须指出的是未改变的包所包含的文件数目并不能反应所有的未改变的文件数目。后者的数字应该高一些：有相当多的文件在Debian的各个发行版之间没有改变，即使它们所属的包的名字变化了。&lt;/p&gt;
&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;开发语言&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;统计数据显示Debian各个发行版中最多使用的开发语言仍然是C语言，并且较之于第二名优势明显。但对于C语言，在第Debian 2.0中，C占了77%的份额；到了Debian 4.0，C语言的份额下降到了51%。而对于C++，则是从2.0时占6%的市场份额上升到了4.0时的19%。总体上看，C语言的重要性一直在相对减弱，而C++和其它一些开发语言都保持了一定增长的趋势。必须说明的一点时，仅管C语言的份额在下降，但从C语言代码绝的绝对数量上看仍然在快速增加。&lt;/p&gt;
&lt;p&gt;Shell语一直处在第三的位置，因为这种语言在几乎每个包中都有。从大量的小尺寸包到重量级的包，Shell无所不在。&lt;/p&gt;
&lt;p&gt;另一个值得关注的必然是Java。在Debian 3.0时，Java编写的应用仅仅占到0.5%。到了Debian 3.1发布时，这个数字飞速上升到1.7%，到了Debian 4.0時，增加到了3.1%，稳定地占据了第四的位置。Java的快速增长得益于几个大型应用使用Java语言进行开发，比如：Eclipse和Azureus。实际上，Java还是被低估了。因为授权许可证的问题，包含大量Java代码的Sun JDK和Sun JRE没有统计在内，而其它语言则至少包含了一个常用的开发环境。&lt;/p&gt;
&lt;p&gt;就代码量而言，一些比较生僻冷门的语言也占据了比较明显的份额。这是因为虽然这些生僻语言仅仅出现在少量包中，但这些开发包的尺寸却很大。比如，Ada语言在Debian 3.0中有57万行代码，其中的43万行都来自于Ada的编译器，开发库和开发工具。&lt;/p&gt;
&lt;p&gt;通过观察开发语言的使用率趋势，可以估算出有多少开发者比较熟悉某种开发语言。同时，不同语言的不断演化也反映出自由软件在开发语言层面的变化。&lt;/p&gt;</description>
    </item>
    <item>
      <title>怎么为Linux源代码生成补丁</title>
      <link>https://ykyi.net/?p=402/</link>
      <pubDate>Wed, 22 Feb 2012 05:27:48 +0000</pubDate>
      <guid>https://ykyi.net/?p=402/</guid>
      <description>&lt;p&gt;怎么为Linux源代码生成补丁&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;用diff命令来为linux源代码生成补丁。如：&lt;/p&gt;
&lt;p&gt;$ diff -Nur /path/to/original/kernel /path/to/your/kernel &amp;gt; change.patch&lt;/p&gt;
&lt;p&gt;注意原始的源代码在前，更改后的源代码在后。2.6.x内核的补丁包提交约定指出你需要在每个patch后面写上这样一行：&lt;/p&gt;
&lt;p&gt;Sined-off-by: name &lt;email&gt;&lt;/p&gt;
&lt;p&gt;这样注明这个补丁包由你制作并贡献给社区。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;参看 Documentation/SubmittingPatches可以知道更多关于提交linux源代码补丁的内容 。&lt;/p&gt;
&lt;p&gt;参看 Documentation/applying-patches.txt 可以知道更多如果打补丁包。&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>业务连续性读书报告</title>
      <link>https://ykyi.net/?p=397/</link>
      <pubDate>Fri, 13 Jan 2012 11:52:01 +0000</pubDate>
      <guid>https://ykyi.net/?p=397/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    第一部分&amp;nbsp;&amp;nbsp;概述
  &lt;/p&gt;
  &lt;p&gt;
    1&amp;nbsp;&lt;span style=&#34;font-family: 宋体;&#34;&gt;什么是业务连续性&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    业务连续性就是为了应对系统宕机，无法接受的性能下降之类的问题。
  &lt;/p&gt;
  &lt;p&gt;
    2&amp;nbsp;&lt;span style=&#34;font-family: 宋体;&#34;&gt;为什么要有业务连续性&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    因为如果系统宕机会造成无法估计的巨大损失。怕你不信，&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;PPT&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;里画了张表，列举了几个行业宕机会造成的损失估计。最低的一般零售业每小时损失一百万美金；损失最大的是投资银行，每小时造成接近七百万美金的损失。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    3&amp;nbsp;&lt;span style=&#34;font-family: 宋体;&#34;&gt;恢复时间&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Recovery&amp;nbsp;Time&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Recovery&amp;nbsp;Time&amp;nbsp;includes&lt;span style=&#34;font-family: 宋体;&#34;&gt;：&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;1.&amp;nbsp;&lt;/span&gt;Fault&amp;nbsp;detection&amp;nbsp;2.&amp;nbsp;Recovering&amp;nbsp;data&amp;nbsp;3.Bringing&amp;nbsp;apps&amp;nbsp;back&amp;nbsp;online。
  &lt;/p&gt;
  &lt;p&gt;
    4&amp;nbsp;&lt;span style=&#34;font-family: 宋体;&#34;&gt;灾难恢复和灾难重启的区别&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    灾难恢复是在人为干预下使用备份技术恢复数据把数据恢复到备份的某个完整点。而灾难重启则是重启镜像数据和应用程序。
  &lt;/p&gt;
  &lt;p&gt;
    5.&amp;nbsp;造成系统宕机的原因
  &lt;/p&gt;
  &lt;p&gt;
    有人为因素，系统本身的原因，支持系统的外围设备的故障&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;比如电网断电&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，另外还有自然灾难，战争什么的。苦逼的伊斯兰世界天天哭喊着要圣战啊。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    6.&amp;nbsp;业务连续性和灾难恢复
  &lt;/p&gt;
  &lt;p&gt;
    业务连续性是一盘大棋，包括：计划，准备，从灾难中恢复。它侧重在预防。而灾难恢复计划&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(Disaster&amp;nbsp;recovery&amp;nbsp;planning&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;abbreviated&amp;nbsp;as&amp;nbsp;BCP)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;应被看成业务连续性的一部分。灾难恢复侧重于事发后采取的措施和行动。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    7.&amp;nbsp;业务连续计划&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(BCP)&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    界定关键业务功能；收集当前业务流程的数据；风险管理；制定应急预案&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(Contingency&amp;nbsp;Plans)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和灾难恢复计划&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(DR&amp;nbsp;Plan)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;；培训；测式；维护。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    8.&amp;nbsp;业务连续性计划的生命周期
  &lt;/p&gt;
  &lt;p&gt;
    包括五个阶段。&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;1.&amp;nbsp;Implement,&amp;nbsp;Maintain,&amp;nbsp;and&amp;nbsp;assess&amp;nbsp;2.&amp;nbsp;Objectives&amp;nbsp;3.&amp;nbsp;Analysis&amp;nbsp;4.&amp;nbsp;Design&amp;nbsp;&amp;&amp;nbsp;Develop&amp;nbsp;5.&amp;nbsp;Train,&amp;nbsp;Test&amp;nbsp;&amp;&amp;nbsp;Document.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    9&amp;nbsp;&lt;span style=&#34;font-family: 宋体;&#34;&gt;单点失效&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    这个概念&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;N&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;多学科里都有提到哇。顾名思义都知道单点失效是什么咯。解决的方法就是冗余！&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;PPT&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;里列举了&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;HBA&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;失效，交换机&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;阵列端口失效，磁盘失效，主机失效，站点&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;存储阵列失效。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    10&amp;nbsp;&lt;span style=&#34;font-family: 宋体;&#34;&gt;业务连续性技术的解决方案&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    有三种。&amp;nbsp;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;A.&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;本地复制&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;B.&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;远端复制&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;C.&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;备份&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;恢复&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    11&amp;nbsp;EMC&lt;span style=&#34;font-family: 宋体;&#34;&gt;的相关产品&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    EMC&lt;span style=&#34;font-family: 宋体;&#34;&gt;在业务连续性方面的产品叫&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;PowerPath&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;PowerPath&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;是个基于&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Server&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的软应用，它在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;HBA&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和存储子系统间提供了多通路。嗱，它提供冗余通路。好明显冗余是为了防止单点失效；还提供了负载平衡；应用层的透明性。这个东东增强了数据的有效性和可达性。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    第二部分&amp;nbsp;解决方案
  &lt;/p&gt;
  &lt;p&gt;
    A)&amp;nbsp;备份和恢复
  &lt;/p&gt;
  &lt;p&gt;
    1.&amp;nbsp;备份是数据恢复和恢复的目的，可以使用的额外副本。主副本丢失或损坏时，使用备份副本。
  &lt;/p&gt;
  &lt;p&gt;
    2.&amp;nbsp;备份恢复的策略：复制数据，反射（或快照）后复制，远程备份等。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    3.&amp;nbsp;备份计划的原因包括以下几个方面：硬件损伤、人为因素、应用程序崩溃、安全机制失败、自然灾难、定期的以及公司的需求。
  &lt;/p&gt;
  &lt;p&gt;
    4.&amp;nbsp;数据库备份方法：热备份，生产不中断；冷备份，生产中断。
  &lt;/p&gt;
  &lt;p&gt;
    5.&amp;nbsp;备份粒度和等级：全备份，累积备份，增加的备份
  &lt;/p&gt;
  &lt;p&gt;
    6.&amp;nbsp;备份架构拓扑，3种基本备份拓扑：基于直接附属设备的备份，基于局域网的备份，基于SAN的备份。
  &lt;/p&gt;
  &lt;p&gt;
    7.&amp;nbsp;备份媒介，磁带，磁盘。
  &lt;/p&gt;
  &lt;p&gt;
    8.&amp;nbsp;管理备份过程
  &lt;/p&gt;
  &lt;p&gt;
    备份应用程序接口一般包括两类，CLI和GUI。
  &lt;/p&gt;
  &lt;p&gt;
    备份报告：目的是要便于阅读和提供重要信息，如：备份的数据量；完成备份数；备份不完整的号码（失败）；可能发生的错误类型。
  &lt;/p&gt;
  &lt;p&gt;
    备份日志的重要性：从日志中我们可以看到备份操作的强度和完整度等等，备份日志丢失，软件无法找到确定的备份文件来进行恢复。
  &lt;/p&gt;
  &lt;p&gt;
    B)&amp;nbsp;本地复制
  &lt;/p&gt;
  &lt;p&gt;
    1.&amp;nbsp;复制是产生拷贝数据的过程。
  &lt;/p&gt;
  &lt;p&gt;
    2.&amp;nbsp;备份关注两方面的，可恢复性，一致性。
  &lt;/p&gt;
  &lt;p&gt;
    3.&amp;nbsp;文件系统复制。
  &lt;/p&gt;
  &lt;p&gt;
    4.&amp;nbsp;数据库应用程序复制，包括数据和日志。
  &lt;/p&gt;
  &lt;p&gt;
    5.&amp;nbsp;本地复制技术，基于主机：基于存储阵列，分别举了几个例子。逻辑卷管理（&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;LVM&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;），基于镜像文件系统快照。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    C)&amp;nbsp;远程复制
  &lt;/p&gt;
  &lt;p&gt;
    1.&amp;nbsp;学习目标：阐释远程复制的概念，能从各方面讨论基于主机和基于阵列的远程复制技术。
  &lt;/p&gt;
  &lt;p&gt;
    2.&amp;nbsp;&amp;nbsp;同步复制：确保源和远程副本，在任何时候都相同的数据
  &lt;/p&gt;
  &lt;p&gt;
    3.&amp;nbsp;&amp;nbsp;异步复制：数据缓冲，并且送到远程
  &lt;/p&gt;
  &lt;p&gt;
    4.&amp;nbsp;&amp;nbsp;远程复制技术包括：基于主机的复制；基于阵列存储设备&lt;a href=&#34;http://ykyi.net&#34;&gt; zausiu&#39;s blog&lt;/a&gt;
  &lt;/p&gt;
  &lt;p&gt;
    /////////
  &lt;/p&gt;
  &lt;p&gt;
    介个是EMC存储课的作业.
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>In the flesh 本人地；活生生地。及其它与flesh有关的短语。</title>
      <link>https://ykyi.net/?p=394/</link>
      <pubDate>Sat, 07 Jan 2012 13:42:07 +0000</pubDate>
      <guid>https://ykyi.net/?p=394/</guid>
      <description>&lt;p&gt;&amp;lt;绝望的主妇&amp;gt;第二季第十九集中，susan 的感情进展地很不顺利。一天她独自去电影院。不巧的是，她在电影院里撞见了mike,还是和别的女孩一起来的。这真是无巧不成书。她为了避免尴尬赶快向旁边一位男士求救。还好他很配合，也很幽默。他说：Wow, i can’t believe I’m finally seeing the man himself, &lt;strong&gt;in the flesh.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 在这句说话里面，in the flesh means present and alive before one’s eyes or in person(活生生地在某人眼前或本人地)，也可以简单理解为”活生生地，本人地”&lt;/p&gt;
&lt;p&gt;例如： She is even more beautiful in the flesh. 她本人更漂亮&lt;/p&gt;
&lt;p&gt;一定要学会这句话喔。这可是在看照片时常用的啊。哈哈。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;flesh可以指“肉，肉体”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hi, what makes u lose so much flesh. 嗨，是什么使你变得如此消瘦。&lt;/p&gt;
&lt;p&gt;The spirit is willing but the flesh is weak. 心有余而力不足。&lt;/p&gt;
&lt;p&gt;**flesh and blood 可以用来泛指人体，人性(The human body or nature).&lt;br&gt;
**&lt;/p&gt;
&lt;p&gt;The work is more than flesh and blood can stand. 这项工作非人能忍受。&lt;/p&gt;</description>
    </item>
    <item>
      <title>英语里几个和knock有关的短语 knock off; knock out; knock up; knock yourself out</title>
      <link>https://ykyi.net/?p=390/</link>
      <pubDate>Sat, 07 Jan 2012 13:10:20 +0000</pubDate>
      <guid>https://ykyi.net/?p=390/</guid>
      <description>&lt;p&gt;knock是个普通的动词，但在日常口语中经常出现。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Knock off&lt;/strong&gt; : ‘住手’的意思！ Betty Applewhite把自己弱智的儿子caleb囚禁在basement，caleb总是不断地击打镣铐发出哐啷的声音。另一个儿子Matthew无法忍受时对地下室喊到： Knock it off !&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Knock out:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;拳击双赛中的”KO”，即把对方击倒，即 knock out 的缩写.&lt;/p&gt;
&lt;p&gt;但数学老师说”we can knock out x and y”这里的knock out 则是“消去”的意思。&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;knock-out 作名词解时却是“美女”的意思。 She is a knock-out. 她是个美女。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Knock up:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Knock up这是一个略显粗俗的美国俚语，意思是“to make sb. pregnant”(使某人怀孕)例如：&lt;/p&gt;
&lt;p&gt;You are so irresponsible, if u knock her up and then disappear.&lt;/p&gt;
&lt;p&gt;又如： The young girl said she was afraid of getting knocked up.&lt;/p&gt;
&lt;p&gt;在英式英语中，knock up 和 knock out 有相同的意思，表示“使筋疲力尽，使累垮”&lt;/p&gt;
&lt;p&gt;例如：This physical work knocked me up. 这个体力活使我筋疲力尽了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>A slap on the wrist 轻微的惩罚</title>
      <link>https://ykyi.net/?p=386/</link>
      <pubDate>Sat, 07 Jan 2012 12:24:03 +0000</pubDate>
      <guid>https://ykyi.net/?p=386/</guid>
      <description>&lt;p&gt;&amp;lt;绝望的主妇&amp;gt;第二季第九集中。Lynette找到stu,鼓动他上司Ed说明自己被解雇的真正原因是女上司Nina对他的性骚扰，Stu为保全工作决定找Ed摊牌，但同时又担心Nina的处境。&lt;/p&gt;
&lt;p&gt;So would Nina get in trouble ? 那么Nina会有麻烦吗？&lt;/p&gt;
&lt;p&gt;well, I‘m not gonna lie to u. There is a possibility she’d get a slap on the wrist. &lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 我不想撒谎，Nina有可能会受到轻微的处罰。&lt;/p&gt;
&lt;p&gt;这里 a slap on the wrist中的slap就是打一下。比如说，a slap on the face就是打耳光。 a slap on the wrist 就是在手腕上打一下。在手腕上打一下并不痛。作为习惯用语呢， a slap on the wrist 就是”轻微的惩罚”。&lt;/p&gt;
&lt;p&gt;比a slap on the wrist更轻的叫做“token punishment”.象征性惩罚。&lt;/p&gt;
&lt;p&gt;You got off easy this time, but stealing is a serious crime and next time it won’t just be a slap on the wrist.&lt;/p&gt;</description>
    </item>
    <item>
      <title>stab someone in the back 出卖别人</title>
      <link>https://ykyi.net/?p=382/</link>
      <pubDate>Fri, 06 Jan 2012 17:31:57 +0000</pubDate>
      <guid>https://ykyi.net/?p=382/</guid>
      <description>&lt;p&gt;《绝望的主妇》第2季第22集，大伙忙着帮susan收拾大火过后的残局，无意之间susan发现只有edie站在街对面袖手旁观，悠闲地吃冰棒(popsicle)，还洋洋得意地盯着susan. Susan当即像是明白了些什么，随后便跑到Edie家去想问个究竟…&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;没想到这一对质，Edie承认了她所做的一切，但她却振振有词，原因是她看了susan之前写给她的道歉信。susan做梦也想不到那封信怎么还会到Edie的手里。Mike花了大价钱赶走了私家侦探Oliver. Susan又想尽一切办法引开邮递员Gus的注意，偷出了那封信,没想到老天捉弄人， 在Julie回家后以为是邮递员弄错了，误把给Edie的信放在自己家里的信里了，于是她又给放了回去。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;当susan还是一头雾水的问”letter? what letter?” 。还是 Edie理直气壮地告诉她：The one where u admitted to stabbing me in the back by sleeping with Karl (在那封信里你承认了你在背后出卖我，与Karl睡觉。)&lt;/p&gt;
&lt;p&gt;Stab someone in the back 是指在背后暗箭伤人，出卖某人的意思.&lt;/p&gt;
&lt;p&gt;I cannot believe my best friend stabbed me in the back. 我不敢相信我最好的朋友竟然出卖我。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;顺便提到另一个谚语： Better an open enemy than a false friend. 公开的敌人胜过虚假的朋友。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
    <item>
      <title>英语习语中的Bite</title>
      <link>https://ykyi.net/?p=376/</link>
      <pubDate>Thu, 05 Jan 2012 16:33:42 +0000</pubDate>
      <guid>https://ykyi.net/?p=376/</guid>
      <description>&lt;p&gt;Bite这个词本来很简单，但是在实际运用中，可以活用的地方有很多。例如，在《绝望的主妇》第二季第二十集中，一次，Lynette在帮助上司Ed与妻子进行网络聊天时，他模仿Ed的口气暧昧地说： i will bite you good. (我会把你咬得全舒舒服服的.)&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt; http://ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;t Susan就像猫和老鼠一样，好像注定是天敌。Edie口中最尖酸的话好像都指向了susan,有一次，她脱口就骂Susan： You bitch! Susan总是要内敛一些，她没有直接骂Edie是bitch,但动动却表达了同样的意思。因为她迅速地回击说: Bite me ! 也就是说：你咬我吧。你能把我怎么样?&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Bite me 是对对方的一种挑衅。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Bite 可以利用的场合远不止此。如果你早上起晚了，而上班时间马上又要到了，那么早点又不能不吃，你可能会随便吃一口面包，这样你可以说：I will take a bite of bread this time.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;英语中，可以用go for a bite表示“出去吃饭”例如：&lt;/p&gt;
&lt;p&gt;what’s up ? 干什么呢？&lt;/p&gt;
&lt;p&gt;Well, i was wondering if you’d like to go for a bite. 嗯，我在想你是否想出去吃饭。&lt;/p&gt;
&lt;p&gt;再如，有一句广告词上写着: save those leftovers and go out for bite on Friday.（星期五不吃剩菜，出去吃）&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt; http://ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;还有四个与bite有关的短语，值得一学。&lt;/p&gt;
&lt;p&gt;**All bark and No bite.  **什么意思呢？中国的俗语里面也有类似的说话，即“叫唤的狗不咬人(Barking dogs seldom bite.)” All bark and No Bite的意思跟这个很相似，即“嘴上说说，实际上不会怎样””雷声大，雨点小。”例如： The new manager threatened to fire me but i know he won’t do it; he is all bark and no bite.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Get over somebody</title>
      <link>https://ykyi.net/?p=371/</link>
      <pubDate>Sat, 31 Dec 2011 07:41:17 +0000</pubDate>
      <guid>https://ykyi.net/?p=371/</guid>
      <description>&lt;p&gt;短语: &lt;strong&gt;get over 什么意思.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: #000000;&#34;&gt;I know you’re trying to get over Morty, but this is not the way to do it.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;我知道你在尽力忘了Morty,但是，这不是正确的作法。&lt;/p&gt;
&lt;p&gt;在这里get over 的意思是”忘却”，它还有”结束；熬过；康复” 的意思。如果说 He finally got over his divorce,那就指他人离婚中恢复过来，不再为此事烦恼或煎熬了，已回到正常的生活中了。&lt;/p&gt;
&lt;p&gt;Even though we have broken for such a long time, I still couldn’t get her over.&lt;/p&gt;
&lt;p&gt;虽然我们已经分手很长时间了，可我还是忘不了她。&lt;/p&gt;
&lt;p&gt;Get over除了当”忘记”讲，还有一个意思”克服，忍受”相当于over come.例如:&lt;/p&gt;
&lt;p&gt;No matter what it takes, we must get over this difficulty.&lt;/p&gt;
&lt;p&gt;It took me a long time to get over my flu.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A pillar of salt 什么意思. 盐柱子是什么意思. lot’s wife什么意思.</title>
      <link>https://ykyi.net/?p=368/</link>
      <pubDate>Fri, 30 Dec 2011 13:52:46 +0000</pubDate>
      <guid>https://ykyi.net/?p=368/</guid>
      <description>&lt;p&gt;&amp;lt;绝望的主妇&amp;gt; 第二季第十一集中，Bree对Andrew和男友Justin在自家前院的暧昧行为提出了批评，没想到反遭讥讽：“Oh, and you didn&amp;rsquo;t turn into a pillar of salt. Good for you。&amp;quot; 噢，还好，你没有变成盐柱子。&lt;/p&gt;
&lt;p&gt;怎么会变成盐柱子呢？原来这个典故来自于圣经里的故事。&lt;/p&gt;
&lt;p&gt;这个故事是这样的: &lt;/p&gt;
&lt;p&gt;当上帝开始摧毁罪恶之城所多玛和俄摩拉城时，他派出两位天使力劝善人罗德及其家人赶快离开，并警告他们在逃跑时千万不要往回看。但是罗德的妻子特别好奇，她想知道这座故乡城市到底会发生什么。在她回头看时，她变成了一个盐柱子。&lt;/p&gt;
&lt;p&gt;所以英语中就有了Lot&amp;rsquo;s Wife和a pillar of salt来指代&amp;quot;分好奇的人&amp;quot;。&lt;/p&gt;
&lt;p&gt;另外    &lt;a href=&#34;http://ykyi.net&#34;&gt;ykyi.net&lt;/a&gt; 还有两个关于salt的短语.&lt;/p&gt;
&lt;p&gt;worth one&amp;rsquo;s salt 是指称职，有能力，能胜任的意思。原因是盐曾作为工资支付手段，工资金salary也就是源于此。例如: That actor is not worth his salt. (那个演员不称职。）&lt;/p&gt;
&lt;p&gt;rub salt in an old wound 表示&amp;quot;故意提及伤心地往事&amp;quot; 例如:&lt;/p&gt;
&lt;p&gt;Do you remember that time you were giving a speech and you dropped your laptop computer?&lt;/p&gt;
&lt;p&gt;Oh, please, let&amp;rsquo;s not rub salt in old wounds.&lt;/p&gt;</description>
    </item>
    <item>
      <title>英语习语中Dead的用法</title>
      <link>https://ykyi.net/?p=365/</link>
      <pubDate>Thu, 29 Dec 2011 10:00:33 +0000</pubDate>
      <guid>https://ykyi.net/?p=365/</guid>
      <description>&lt;p&gt;绝望的主妇 第一季第13集中Lynette对Tom说的非常绝妙的一句话: I guess i just got so upset because —- oh, whatever, let’s not beat a dead horse, it’s over, Im sorry, good night. ( 想那事让我这么心烦就是因为—-哦，随他去吧，事已至此，也别白费口舌了，这件事到此为止，我很抱歉。晚安。)&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt;zausiu’s blog http://ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这句话中的beat a dead horse 这个表达非常形象，这里的beat也可用flog替换。大家想象一下，用鞋子抽打死马让它驰骋，就是再大的力也没有用。因此这个表达用来表示”徒劳，作无用功”或是指”对已摒 弃或认可的活动信念徒费精力”。英语中还有很多跟dead用关的用法。&lt;/p&gt;
&lt;p&gt;老友记中Earl先生想自杀的原因之一就是他觉得自己从事一个dead-end job (没有前途的工作)。&lt;/p&gt;
&lt;p&gt;dead-end 是美国俚语，意思是死胡同，与中文里穷途末路相似。&lt;/p&gt;
&lt;p&gt;美国作家Sidney Kingsley于1935年创作现实主义作品Dead End&amp;lt;死巷&amp;gt;。小说反映美国纽约大城市贫民窟中青少年的生活，1937年被编成电影Dead End Kids《死巷小子》。之后dead-end kid就是“穷孩子，浑小子或没有出息的男人”的意思。&lt;/p&gt;
&lt;p&gt;The City Hall is more often a dead end than a stepping-stone for improving one’s political careers. 在市政大厅里工作，对于一个需要政治前途的人来说，与其说是一块垫脚石，还不如说是一个死胡同。&lt;/p&gt;
&lt;p&gt;zausiu’s blog: &lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;再介绍一下dead in the water的意思。&lt;/p&gt;</description>
    </item>
    <item>
      <title>英语笔记</title>
      <link>https://ykyi.net/?p=362/</link>
      <pubDate>Thu, 29 Dec 2011 09:17:49 +0000</pubDate>
      <guid>https://ykyi.net/?p=362/</guid>
      <description>&lt;p&gt;# in/out someone’s hair (不)给添乱，烦扰。&lt;br&gt;
She was constantly in my hair, overseeing everything I did.&lt;/p&gt;
&lt;p&gt;# Flip-flop 突然改变立场&lt;br&gt;
Bree, could this flip-flop have something to do with the fact that Danielle is dating Mattew?&lt;/p&gt;
&lt;p&gt;# Fresh as paint 容光焕发&lt;br&gt;
You have been as fresh as paint over the last six months.&lt;br&gt;
容易与fresh paint(油漆未干混淆)&lt;/p&gt;
&lt;p&gt;# put an end to something&lt;/p&gt;
&lt;p&gt;# The last straw 最后一根稻草&lt;/p&gt;
&lt;p&gt;# Dead meat&lt;br&gt;
If u keep slamming the door like this, u’re dead meat.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unix网络编程 第13章 Daemon Processes and the inetd Superserver 笔记</title>
      <link>https://ykyi.net/?p=356/</link>
      <pubDate>Mon, 26 Dec 2011 16:59:47 +0000</pubDate>
      <guid>https://ykyi.net/?p=356/</guid>
      <description>&lt;p&gt;# The syslogd daemon runs in an infinite loop that calls select, waiting for any one of its three descriptors to be readable. it reads the log message and does what the configuration file says to do with that message. If the daemon receives the SIGHUP signal, it rereads its configuration file. So, what are the three descriptors that the select system call is waiting for ?  1. A unix domain socket is created and bound to the pathname /var/run/log (/dev/log on some systems). 2. A udp socket is created and bound to port 514(the syslog service). 3. The pathname /devklog is opened. Any error messages from within the kernel appears as input on this device. Newer implementation disable the creation of the UDP socket, unless specified by the administrator, as allowing anyone to send UDP datagrams to this port opens the system up to denial-of-service attacks, where some one could fill up the filesystem.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unix网络编程 第十二章 IPv4 and IPv6 Interoperability</title>
      <link>https://ykyi.net/?p=352/</link>
      <pubDate>Mon, 26 Dec 2011 13:28:35 +0000</pubDate>
      <guid>https://ykyi.net/?p=352/</guid>
      <description>&lt;p&gt;# Ethernet header contains a type fileld of 0x0800, which identifies the frame as an IPv4 frame.&lt;/p&gt;
&lt;p&gt;# 若支持dual-stack的server既有IPv4又有IPv6。则IP层让server透明地既可处理IPv4又可处理IPv6.该server需要绑定到wildcard且未设置IPV6_V6ONLY socket option.&lt;/p&gt;
&lt;p&gt;# UNP Page359 Figure 12.5 Summary of interoperability between IPv4 and IPv6 clients and servers.&lt;/p&gt;
&lt;p&gt;# 尽可能用IPv6,  since an IPv6 client can still communicate with IPv4 servers, and vice versa.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unix网络编程 第11章 Name and Address Conversions 笔记</title>
      <link>https://ykyi.net/?p=344/</link>
      <pubDate>Mon, 26 Dec 2011 12:48:53 +0000</pubDate>
      <guid>https://ykyi.net/?p=344/</guid>
      <description>&lt;p&gt;# gethostbyname 和 gethostbyaddr 用来在 IPv4 地址和 hostname 之间转换. getservbyport 和 getservbyname 则是与服务相关。gethostbyname出错时不设errno而是设h_errno，并有hstrerror()函数。&lt;/p&gt;
&lt;p&gt;# FQDN的全称是: Fully Qualified domain name. 技术上说必须以点号(period)终止.&lt;/p&gt;
&lt;p&gt;# AAAA 被称为 &amp;ldquo;quad A&amp;rdquo; rcord, 给出了从hostname到Ipv6地址的映射。 PTR用来把IP地址到hostname.&lt;/p&gt;
&lt;p&gt;# Entries in the DNS are known as Resource Records(RRs).&lt;/p&gt;
&lt;p&gt;# 一个点分十进制(dotted-decimal)IPv4的地址前加 0::ffff:就是 IPv6的字符串形式。&lt;/p&gt;
&lt;p&gt;# 与getpeername对应的函数不是gethostname而是getsockname.&lt;/p&gt;
&lt;p&gt;# getaddrinfo函数的host参数指定为dotted-decimal IPv4或 IPv6 hex string,会使得只有IPv4或IPv6的addrinfo返回。&lt;/p&gt;
&lt;p&gt;# 不给UDP套接字设置SO_REUSEADDR选项。We do not set the SO_REUSEADDR socket option for the UDP socket because this socket option can allow multiple sockets to bind the same UDP port on hosts that support multicasting. Since there is nothing like TCP&amp;rsquo;s TIME_WAIT state for a UDP socket, there is no need to set this socket option when the server is started.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Prof. Zixiang Xiong讲座 脏纸编码</title>
      <link>https://ykyi.net/?p=346/</link>
      <pubDate>Mon, 26 Dec 2011 11:11:28 +0000</pubDate>
      <guid>https://ykyi.net/?p=346/</guid>
      <description>&lt;div&gt;
  作为主要兴趣在&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Linux&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;方面的偏应用硕士，听了一个电信传输方面的学术讲座。所谓&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Dirty Paper Coding&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，我的理解是&lt;/span&gt;如果已知信道干扰，在发射机对发射信号预先减去该干扰，则发射信号经信道传输被接收机接收后，则信道干扰被自动抵消。很简单的&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Idea&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，但实际实施起来应该非常困难吧。&lt;/span&gt;Prof. Zixiang Xiong先介绍了他所工作的学校。呵。然后从&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Dirty-paper Coding&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的历史发展讲起。&lt;/span&gt;Instances of dirty paper coding include Costa precoding(1983) ,Tomlinson-Harashima precoding (1971) and the vector perturbation technique of Hochwald et al. (2005)。两位科学家&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Gelfand&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Pinsker&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;开创了这个领域，到信息理论的实际设计准则如何应用到实践之中。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Prof. Zixiang Xiong&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;提出了两种有效的编码设计方法。理论回到实路，再介绍这两种编码设计方法在图形图象的数据隐藏，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;MIMO&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;广播，抗噪预编码，无线网络传输协调方面的实际应用。&lt;/span&gt;Gaussian arbitrarily varying channel with a known interference signal at the encoder.&lt;/p&gt; 
  &lt;p&gt;
    好复杂好深奥的数学变换。本次讲座的收获也就是让我一定程度上开拓了视野，接触到&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;N&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;多电信方面的术语。小波变换，脏纸编码，数字水印之类。术业有专功，我要专功我的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Linux&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;去嘞。。。&lt;/span&gt; &lt;/div&gt;</description>
    </item>
    <item>
      <title>Sicily 1031 Campus 解题报告.</title>
      <link>https://ykyi.net/?p=339/</link>
      <pubDate>Mon, 26 Dec 2011 05:12:28 +0000</pubDate>
      <guid>https://ykyi.net/?p=339/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;div&gt;
    1 原题中文大意;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    Sicily 1031 Campus实际上就是求一个图中给出两点的最短路径的问题。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    2 算法思想及解题用到的主要数据结构;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    用 dijkstra 算法求给定两点的最短路径.
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    按路径长度递增次序产生最短路径算法： 　　把V分成两组： 　　（1）S：已求出最短路径的顶点的集合 　　（2）V-S=T：尚未确定最短路径的顶点集合 　　将T中顶点按最短路径递增的次序加入到S中， 　　保证：（1）从源点V0到S中各顶点的最短路径长度都不大于 　　从V0到T中任何顶点的最短路径长度 　　（2）每个顶点对应一个距离值 　　S中顶点：从V0到此顶点的最短路径长度 　　T中顶点：从V0到此顶点的只包括S中顶点作中间 　　顶点的最短路径长度 　　依据：可以证明V0到T中顶点Vk的最短路径，或是从V0到Vk的 　　直接路径的权值；或是从V0经S中顶点到Vk的路径权值之和。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    3 &amp;nbsp;逐步求精算法描述
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    用邻接矩阵存放图.1. 初使时令 S={V0},T={其余顶点}，T中顶点对应的距离值 　　若存在&lt;V0,Vi&gt;，d(V0,Vi)为&lt;V0,Vi&gt;弧上的权值 　　若不存在&lt;V0,Vi&gt;，d(V0,Vi)为&amp;prop; 　　2. 从T中选取一个其距离值为最小的顶点W且不在S中，加入S 　　3. 对T中顶点的距离值进行修改：若加进W作中间顶点，从V0到Vi的 　　距离值比不加W的路径要短，则修改此距离值 　　重复上述步骤2、3，直到S中包含所有顶点，即S=T为止
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    3 程序注释清单 // 这份代码通不过sicily。有case错误。我实在找不到原因。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;pre class=&#34;brush:cpp&#34;&gt;#include &amp;lt;map&amp;gt;
&lt;p&gt;#include &amp;lt;vector&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;string&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;iostream&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;cstdlib&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;cstdio&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;cstring&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;cassert&amp;gt;&lt;/p&gt;
&lt;p&gt;#define INFINITE 0x0FFFFFFF&lt;/p&gt;
&lt;p&gt;// 这个类的函数几乎不做参数有效性的检查.&lt;/p&gt;
&lt;p&gt;class graph_t&lt;/p&gt;</description>
    </item>
    <item>
      <title>我看过的unix/linux世界的好书</title>
      <link>https://ykyi.net/?p=330/</link>
      <pubDate>Sat, 24 Dec 2011 12:36:43 +0000</pubDate>
      <guid>https://ykyi.net/?p=330/</guid>
      <description>&lt;p&gt;&amp;ldquo;Advanced Programming in the Unix Environment&amp;rdquo; Volum I 2nd Edition 大名鼎鼎的  apue 作者是享誉 unix 世界的大牛 Richard Stevens.全书分两卷。第一卷我看了两遍， 第二卷翻了翻目录，不想看。&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Linux Device Drivers&amp;rdquo; 3rd Edition 简称LDD.这本书的中文版翻译的奇烂无比。果断读影印版的，要么就别看了。&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Managing Projects with GNU make&amp;rdquo; 讲GNU make的书. make这个古老的build工具。怎么 说呢。至少我觉得语法设计的非常不友好。无奈的历史问题。&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Version Control with Git&amp;rdquo; 讲git的书.混了个眼熟。一个人单独做小规模开发用不到那 么多特性咯。&lt;/p&gt;
&lt;p&gt;&amp;lt;Linux内核设计与实现&amp;gt; 很薄的一本讲linux kernel的书。这本书看的中文版。陈莉君翻 译的还不错。只有很少错误。&lt;/p&gt;
&lt;p&gt;&amp;lt;Unix编程艺术&amp;gt; 这本书我有中文版和英文版。先买了英文版看看不懂，于是买了中文版看 。除非你的英文水平接近有native speaker的水平并且词汇量超大，至少在一万以上吧。 否则还是看中文版吧。中文版译得很不错。英文版哥看得非常吃力。5。哥的词汇量接近一万 对自己的英文水平看技术类书还是很自信的，但是写这本书的作者是一位极具个性，极具 争议的unix hacker，行文风格尽显不羁个性。同样这本书也是争议颇多。支持的奉为圣经 ，反对的嘲笑作者见识短浅。&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Advanced Bash programming Guide&amp;rdquo;  讲编写bash脚本的。看的网上的电子版。太多内容了，基本上bash的特性面面惧到。很多内容看了就忘了。&lt;/p&gt;
&lt;p&gt;&amp;lt;鸟哥的私房菜 基础篇&amp;gt;据说是中文书里算入门的好书了。网上的口啤不错。个人感觉讲的 内容非常之浅，不过确实是本入门的好书。但不觉得有收藏价值。这套书还有服务器部分，没有看过。没兴趣也不需要看. &lt;/p&gt;
&lt;p&gt;正在看 Richard Stevens 的另一本bible，“Unix network Programming” Volumn I 3 rd Edition。 看完了一半。一定要在寒假结束前看完。和apue一样，虽然最新版都是由新 的作者在原来的基础上更改的，但仍然保持了Richard Stevens的行文风格用语简练不花哨 ，详细细致易懂的风格。 明年争取啃下 &amp;ldquo;Understanding Linux Kernel&amp;rdquo;. 计划选择性看部分&amp;quot;Essential Linux Device Drivers&amp;quot;. 顺便提一下Richard Steven写的另一套久负盛名的书Tcp/ip详解，共三卷。简单的过了一下第一卷。没有认真看。&lt;/p&gt;</description>
    </item>
    <item>
      <title>听了林学民教授的一个学术报告</title>
      <link>https://ykyi.net/?p=316/</link>
      <pubDate>Fri, 23 Dec 2011 15:42:04 +0000</pubDate>
      <guid>https://ykyi.net/?p=316/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;strong&gt;&amp;nbsp;Graph-based&amp;nbsp;Structure&amp;nbsp;Search&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    林学民教授是数据库理论方面的专家。今天的学术报告，林教授给我们简单介绍了他的研究团队在海量数据检索方面的研究成果。
  &lt;/p&gt;
  &lt;p&gt;
    在快带发展的互联网社会，越来越多的应用需要检索快速地检索基于图结构的海量数据。比如近两三年兴起的，我们非常熟悉的社交网络。对于图的结构化检索是一个&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;NPC&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;问题。海量的数据规模使得问题变得非常的棘手。我搜索了一些资料也没搞清楚什么叫&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;NPC&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;问题。我简单地理解，是当问题的规模变得越来越大时，就不能确定是否能在确定的时间内求出解。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    林教授先简单地提到对图的研究方向大致分&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Mining&amp;nbsp;Graphs,&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Quering&amp;nbsp;Graphs&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Mining&amp;nbsp;Graphs&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;方面有&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Frequent&amp;nbsp;Patterns,&amp;nbsp;structure&amp;nbsp;Similarityies,&amp;nbsp;clustering,&amp;nbsp;Ranking,&amp;nbsp;classification&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Prof.&amp;nbsp;Lin&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的团队主要做了&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Structure&amp;nbsp;Similarities&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;方面的一些研究。对于&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Querying&amp;nbsp;Graphs&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，又大致分为&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Readibility,&amp;nbsp;Connectivity&amp;nbsp;between&amp;nbsp;two&amp;nbsp;nodes,&amp;nbsp;substructure&amp;nbsp;search,&amp;nbsp;shortest&amp;nbsp;paths,&amp;nbsp;strings&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Prof.&amp;nbsp;Lin&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;话：对于&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;shortest&amp;nbsp;path&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，理论上求解很&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;simple&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，但是应用到大量数据的时候，就要做很多工作。比如要做非常高效的索引。对于&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;strings&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，一个很长的&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;text&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;可以看成一个长&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。比于现在的&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;internet&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;搜索引擎，要解决区分互联网上太多冗余数据的问题，就属于这方面的研究。我知道搜索引擎是鼓励原创的，会给原创的页面比较高的&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;page&amp;nbsp;rank&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。针对这点，&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;black&amp;nbsp;hat&amp;nbsp;SEO&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就会搞伪原创，怎样让搜索引擎快速区分出真正的原创内容呢？应该也属于这方面的课题吧。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    林教授开始讲他的科研团队的第一个贡献。这个&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;contribution&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;是解决了关于图与图之间包含的问题。问题描述为：给出一个&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Data&amp;nbsp;Graph&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和一个&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Query&amp;nbsp;Graph&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，要在一个规模非常大的&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Data&amp;nbsp;Graph&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;里面找到这个&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Query&amp;nbsp;Graph&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。林教授介绍了这个过程中的&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Filtering&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Verification&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;算法简要思路。对于不懂学术的我，这部分真是相当地难以理解啊！！！设&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;D&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;是要处理的图。&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;First&amp;nbsp;index&amp;nbsp;a&amp;nbsp;set&amp;nbsp;F&amp;nbsp;of&amp;nbsp;features&amp;nbsp;from&amp;nbsp;D&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。对于任意&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;属于&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;F,&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;求&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的超图。索引的算法思路是。如果&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;q&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;是一个&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;frequent&amp;nbsp;subgraph,&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;则&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;1.&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;如果&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;q&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;已经被索引，则返回&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;q&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的超图。&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;2.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;如果&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;q&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;是一个超图，次&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;q&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;被索引了，不需要给次&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;q&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的超图做&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;verification&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。如果&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;q&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;不是一个&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;frequent&amp;nbsp;subgraph&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的情况下，验证受制于&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;sigmal|D|&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。林教授认为这个求解过程的主要开销在&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;verification&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;阶段。他们的团队就是把这个&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;cost&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;显著降了一下，而且思路非常地&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;clear&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;simple&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。他总结了三条经验：&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;1.&amp;nbsp;Access&amp;nbsp;infrequent&amp;nbsp;labels&amp;nbsp;as&amp;nbsp;early&amp;nbsp;as&amp;nbsp;possible.&amp;nbsp;2.&amp;nbsp;Retain&amp;nbsp;connectivity&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;3.&amp;nbsp;Effectively&amp;nbsp;use&amp;nbsp;degree&amp;nbsp;information.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    The&amp;nbsp;second&amp;nbsp;contribution&amp;nbsp;of&amp;nbsp;Prof.&amp;nbsp;Lin&amp;nbsp;is&amp;nbsp;to&amp;nbsp;put&amp;nbsp;the&amp;nbsp;the&amp;nbsp;theoretic&amp;nbsp;algorithm&amp;nbsp;into&amp;nbsp;practice.&lt;span style=&#34;font-family: 宋体;&#34;&gt;有两个问题，一个是&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;query&amp;nbsp;graph&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;被&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;data&amp;nbsp;graph&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;包含&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;(contained)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，另一个是&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;query&amp;nbsp;graph&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;包含了&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;data&amp;nbsp;graph.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;林教授的团队的最结成果比已经发表了论文的另一个科研团队的成果的速度要快了一个数量级。&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Prof.&amp;nbsp;Lin&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的语气显得有些遗憾，他们的思路是正确的，实现的效率也很高，但是时间上慢了小小。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&amp;nbsp;zausiu&#39;s blog
  &lt;/p&gt;
  &lt;p&gt;
    发言队段，研究这个方向的甘同学问了非常专业的问题，我不懂啊！还有一位信科院的研一同学问到了留学的问题，&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;Prof.&amp;nbsp;Lin&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;说他要最&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;top&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的学生，非常地&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;talented&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，非常地&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;diligent,&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;非常地&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;good&amp;nbsp;at&amp;nbsp;algorithm&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，还要有非常好的&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;practical&amp;nbsp;ability&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。朝红阳教授向林教授打听有没有做图象&lt;/span&gt;&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;search&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;方面的大牛。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    学术报告好难啊！我想听工程类的报告。但都是&lt;span style=&#34;font-family: &#39;Times New Roman&#39;;&#34;&gt;academic&amp;nbsp;report&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;啊！&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    //////////////////
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;Topic: &lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Graph-based Structure Search
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;Speaker:&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Prof. Xuemin Lin
  &lt;/p&gt;
  &lt;p&gt;
    School of Computer Science and Enmgineering,University of New South Wales
  &lt;/p&gt;
  &lt;p&gt;
    and
  &lt;/p&gt;
  &lt;p&gt;
    School of Software ,Eastern China Normal University
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;Abstract:&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Recent years have witnessed an emergence of graph-based applications that strongly demand efficient processing of graph-based queries and searches.
  &lt;/p&gt;
  &lt;p&gt;
    In many real applications such as chem- and&amp;nbsp; bio-informatics, road neworks, social networks, etc.,&amp;nbsp; efficiently and effectively conducting structure search on graphs is a key.
  &lt;/p&gt;
  &lt;p&gt;
    The problem of structure search on graphs and its variants are NP-complete. The presence of a large number of graphs makes the problem computationally more intractable.
  &lt;/p&gt;
  &lt;p&gt;
    In this talk, I will introduce recent techniques in graph structure search with the focus on our recent work published in SIGMOD, VLDB, ICDE, etc. My talk will cover the problems of substructure search, superstructure search, and substructure similarity search.
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;Brief Bio:&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    林学民，新南威尔士大学大学计算机科学及工程学院教授，数据库研究实验室主任。自2009年4月起，在华东师范大学担任兼职教授，2010年入选国家第四批千人计划学者，2011年6月起受聘于华东师范大学软件学院千人学者。生于上海市，1984年毕业于复旦大学数学系，1992年在昆士兰大学获得博士学位。长期从事数据库理论、算法与技术研究，包括空间数据、不确定数据、流数据、图数据等领域。近年来在数据库领域顶级国际学术会议及顶级杂志上共发表了70余篇学术论文；累计在数据库和算法领域重要的国际学术会议和国际学术期刊发表并录用了170余篇论文，其中10篇国际会议优秀论文，包括ICDE&#39;07上的优秀学生论文奖 (best student paper award) ICDE&#39;10上的优秀论文(one of the best papers) , 及SIGMOD&#39;11 上的优秀论文(one of the best papers)。他目前的研究兴趣是海量数据的处理，包括图数据、时空数据、字符串数据、不确定数据等。学民先后在4th Australasian Theory Symposium (CATS&#39;98), 6th International Computing and Combintorics Conference (COCOON2000), 6th Asia Pacific Web Conference (APweb04), the joint conference of 9th Asia Web Conference and 8th Web-Age Information Management Conference (APweb/WAIM2007), 和 19th and 20th Australasian Database Conference (ADC08, ADC09) 担任会议程序委员会主席，在14th International Conference on Database Systems for Advanced Applications (DASFAA09) 上担任大会主席。目前他是ACM TODS的编委。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;Presided by&amp;nbsp; &lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Prof. Jianlin Feng
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;Date and Venue&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Dec 21, 2011(Wed.) 14：00-15：00
  &lt;/p&gt;
  &lt;p&gt;
    Lecture Theater A101, School of Software, Sun Yat-sen University
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>冬大过年！无痛终结2011年.展望2012</title>
      <link>https://ykyi.net/?p=319/</link>
      <pubDate>Thu, 22 Dec 2011 16:56:13 +0000</pubDate>
      <guid>https://ykyi.net/?p=319/</guid>
      <description>&lt;div&gt;
  写在冬至日，总结2011展望2012。冬大过年是广东的俗语。无痛终结是因为人心态早已看得化(开)。
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
  首先：在无比苦逼的11年里，最大的贡献就是返校读书了。基本上确定可以了结本科毕业时被取消学位的心愿。
&lt;/div&gt;
&lt;div&gt;
  其次工作上没有什么好说的。在东莞光大集团工作了半年，不能说辛苦也不算闲。工作上没学到什么东东，没明显地进步。在此谢谢赵经理了，如果我有赵经理的硬件水平我就笑哈哈哈哈。以识了几位有意思的同事。
&lt;/div&gt;
&lt;div&gt;
  感情上则一如既往地Fail, Fail, Fail 。。。完全木有信心了。哥爱无力了。到了年尾心态竟变得更无所谓，该怎样就怎样吧。只是让家人操心了，对不起啊，尽力了啊。奶奶，对不起啊。也想让你开心的。哎！想起过年回家要去那么多亲戚拜年，555，拜托你们不要问不要问吖。
&lt;/div&gt;
&lt;div&gt;
  最后讲讲返校后的生活。在中大的生活第一学期课程非常多，非常忙。我还有我的plan要投入很多时间。时间无论如何不够用！同学关系远没本科时紧密。可能我的心态跟刚毕业的后生仔们相差甚远吧。写到这里，想起今年国庆时去了其它地方没有参加强强和敏的婚礼。唉！什么时候去江苏再给我机会补偿好吗。我做人是越来越失败了，完全是不分好坏敌我的混乱！
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
  2012年是世界的最后一年。可恶的地球人，觉悟吧！
&lt;/div&gt;
&lt;div&gt;
  以前每年年尾都会许好多愿望。结果第二年能实现的却渺渺无几。反正都2012了，哥的愿望就务实一点好吧。维护世界和平的任务还是不要勉强啦！
&lt;/div&gt;
&lt;div&gt;
  明年必须在寒假结束前看完Unix网络编程.
&lt;/div&gt;
&lt;div&gt;
  &lt;div&gt;
    &lt;div&gt;
      通过六月的BEC高级考试。
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
  全年选择性的读完Essential Linux Device Drivers和Understanding linux Kernel.
&lt;/div&gt;
&lt;div&gt;
  上半年看paper，形成写论文的思路。下半年动手写论文。
&lt;/div&gt;
&lt;div&gt;
  下半年拿到offer。银行？民航？其它国企？还是互联网公司抑或其它什么公司？&amp;#8230;
&lt;/div&gt;
&lt;div&gt;
  感情的事务不设定目标。苦逼的技术宅男果断必然无解！
&lt;/div&gt;</description>
    </item>
    <item>
      <title>Unix 网络编程 第十章 SCTP Client/Server Example</title>
      <link>https://ykyi.net/?p=313/</link>
      <pubDate>Mon, 19 Dec 2011 11:25:57 +0000</pubDate>
      <guid>https://ykyi.net/?p=313/</guid>
      <description>&lt;p&gt;这一章的内容还是满少的。也就是给出一个SCTP的简单例子。所以也没有太多需要做笔记的。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;什么是 head-of-line blocking.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Head-of-line blocking occurs when a TCP segment is lost and a subsequent TCP segment arrives out of order. That subsequent segment is held until the first TCP segment is retransmitted and arrives at the receiver.&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;&lt;strong&gt;怎么更改SCTP连接的stream的数量。&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;SCTP连接的streams的数量是在association的握手之前协商好的。对于FreeBSD的KAME实现，SCTP的outbound streams默认为10。这个值可以用setsocket函数更改。与SCTP_INITMSG scoket option相关，设置struct sctp_initmsg结构体。&lt;/p&gt;
&lt;p&gt;也可以用sendmsg函数发送ancillary数据来到达同样的目标。但发送ancillary data只对one-to-many形式的sctp socket有效。&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;&lt;strong&gt;怎么结束一个SCTP连接。&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;可以设置sctp_sndrcvinfo结构的sinfo_flags值的MSG_EOF flag来关闭一个sctp连接gracefully. This flag forces an association to shut down after the message being sent is acknowledged.&lt;/p&gt;
&lt;p&gt;还可以给sinfo_flags设置 MSG_ABORT。这样就会立即发送一个ABORT给peer端。任何还没来得及发送出的数据会被丢弃。&lt;/p&gt;</description>
    </item>
    <item>
      <title>sicily 2014. Dairy Queen 解题报告</title>
      <link>https://ykyi.net/?p=310/</link>
      <pubDate>Sat, 17 Dec 2011 12:05:10 +0000</pubDate>
      <guid>https://ykyi.net/?p=310/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    Sun Yat-sen University ACM 2014. Dairy Queen
  &lt;/p&gt;
  &lt;p&gt;
    1.&amp;nbsp;原题中文大意&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;;&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    给出一个在&amp;nbsp;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;[1,&amp;nbsp;300]&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;之间的数字&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;N&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。然后给出一个集合，这个集合中有&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;C&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;个数字，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;C&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;[1,&amp;nbsp;8]&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;之间。该集合中的每个数字在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;[1,&amp;nbsp;200]&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;之间。问如何用这个集合中的数字组合（数字可以重复使用），使它们的总和等于&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;N&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    2.&amp;nbsp;&lt;span style=&#34;font-family: 宋体;&#34;&gt;解这种题毫不犹豫地想到用动态规划。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    3.&amp;nbsp;&lt;span style=&#34;font-family: 宋体;&#34;&gt;设一个数组&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ways[301];&amp;nbsp;ways[n]&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;表示有多少种方法可以组合成和&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;n&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。假设集合中只一个数字&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;x&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。那么问题就非常简单，只能取&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;n&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;个该数字，和的集合为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;{x,&amp;nbsp;2x,&amp;nbsp;3x}&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，即&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ways[x]=1&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ways[2x]=1,&amp;nbsp;ways[3x]=1&amp;nbsp;&amp;#8230;.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。如果集合中有&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;m&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;数字，假设我们已经求得了用这&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;m&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;个数字的组合可以得到的和的数目存到了&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ways&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;数组里。即对于&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;m&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;个数字，已求得&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ways[1]&amp;nbsp;=&amp;nbsp;?,&amp;nbsp;ways[2]&amp;nbsp;=&amp;nbsp;?,&amp;nbsp;ways[3]&amp;nbsp;=&amp;nbsp;?&amp;nbsp;&amp;#8230;..&amp;nbsp;Ways[300]&amp;nbsp;=&amp;nbsp;?&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&amp;nbsp;那么在此基础上，再加多一个数字，即&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;m+1&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;个数字的情况会是如何呢。设新加入的这个数字的值是&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;p&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，则应该是&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ways[q]&amp;nbsp;+=&amp;nbsp;ways[q-p]&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。（&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;q&amp;nbsp;&gt;&amp;nbsp;p&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;）&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    4.&amp;nbsp;程序注释清单.
  &lt;/p&gt;
  &lt;pre class=&#34;brush:cpp&#34;&gt;#include &amp;lt;string.h&amp;gt;

#include &amp;lt;stdlib.h&amp;gt;

#include &amp;lt;stdio.h&amp;gt;



int main(int argc, char* argv[])

{

int N, C, coin;  // N为题意中的N，C即题意中的C. coin作临时变量用，不解释，可见下面的代码。

int ways[301] = { 0 };  // 见第三部分的分析。

ways[0] = 1;  // 没有实际意义。为了方便计算.



scanf(&#34;%d %d&#34;, &amp;N, &amp;C);

for ( int i = 0; i &amp;lt; C; i++)

{

scanf(&#34;%d&#34;, &amp;coin);

for ( int j = coin; j &amp;lt;= N; j++ )

{

ways[j] += ways[j-coin];  // 见第3部分的分析.

}

}

printf(&#34;%d\n&#34;, ways[N]);



return 0;

}&lt;/pre&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
  5.时间复杂度，空间复杂度分析。
&lt;/p&gt;
&lt;p&gt;
  空间复杂度是确定的常数。时间复杂度是&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;o(n).&amp;nbsp;n&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;为有多少种面值的硬币。&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
  &lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; zausiu&#39;s blog
&lt;/p&gt;
&lt;p&gt;
  原题：
&lt;/p&gt;
&lt;h1&gt;
  Description
&lt;/h1&gt;
&lt;p&gt;
  Bessie, always in need of an income, has decided to leverage her dairy skills by taking a part-time job at the local Dairy Queen restaurant. She is running a special cash register (since she has hooves instead of fingers and thus requires special accommodation). Her job is making change for customers as they make a purchase.
&lt;/p&gt;
&lt;p&gt;
  As she was counting out 83 cents in change, she wondered: &#34;How many ways can I count out 83 cents? I can use three quarters and eight pennies, seven dimes and three pennies, 83 pennies&amp;#8230; there must be a zillion ways!&#34;
&lt;/p&gt;
&lt;p&gt;
  How many different ways can one make change for N (1 &amp;le; N &amp;le; 300) cents using coins from a set of C (1 &amp;le; C &amp;le; 8) coins of supplied values C_i (1 &amp;le; C_i &amp;le; 200)? &#34;Different&#34; means differing counts of coins.
&lt;/p&gt;
&lt;p&gt;
  Thus, 8 cents can be made, in American currency, with 1 five-cent piece + 3 one-cent pieces and also with 8 one-cent pieces. Using 3 one-cent pieces + 1 five-cent piece is the same as 1 five-cent piece + 3 one-cent pieces, so one can create eight cents in just two different ways. Note that some coin systems are poor at making change and result in an answer of &#39;0&#39;.
&lt;/p&gt;
&lt;p&gt;
  Coin values in the input file are listed in descending order from largest to smallest. All coin values will be distinct.
&lt;/p&gt;
&lt;h1&gt;
  Input
&lt;/h1&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
  Line 1: Two space-separated integers: N and C&lt;br /&gt; Lines 2..C+1: Line i+1 contains a single integer: C_i
&lt;/p&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;h1&gt;
  Output
&lt;/h1&gt;
&lt;p&gt;
  Line 1: A single line with a single integer that is the number of ways to create N cents of change using the supplied coins. The answer is guaranteed to fit into a signed 32-bit int
&lt;/p&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;h1&gt;
  Sample Input
&lt;/h1&gt;
&lt;pre&gt;83 5
50
25
10
5
1&lt;/pre&gt;
&lt;h1&gt;
  Sample Output
&lt;/h1&gt;
&lt;pre&gt;159&lt;/pre&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
  copyright ykyi.net
&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>Unix网络编程.第九章笔记</title>
      <link>https://ykyi.net/?p=307/</link>
      <pubDate>Sat, 17 Dec 2011 08:58:14 +0000</pubDate>
      <guid>https://ykyi.net/?p=307/</guid>
      <description>&lt;p&gt;# TCP 协议在1981年标准化，而SCTP协议则是在2000年由IETF组织标准化。IETF： Internet Engineering Task Force 互联网工程任务组成立于1985年。&lt;/p&gt;
&lt;p&gt;# SCTP支持两种类型的socket. one to one(为了方便现有的tcp程序迁移到sctp) 和 one to many.&lt;/p&gt;
&lt;p&gt;# sctp的sctp_bindx可以绑定多个地址，并且可以动态增删。但动态增删不影响已经存在的associations.不过各个unix分支不一定支持这个特性。&lt;/p&gt;
&lt;p&gt;# sctp_getpaddrs和sctp_getladdrs分别是getpeername和gethostname的sctp版。They are designed with the concept of a multihoming aware transport protocol.&lt;/p&gt;
&lt;p&gt;# sctp传输的报文是有边界的。sctp在传输层支持传输超大的message.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Is your biometric data safe</title>
      <link>https://ykyi.net/?p=304/</link>
      <pubDate>Fri, 16 Dec 2011 16:31:09 +0000</pubDate>
      <guid>https://ykyi.net/?p=304/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    Kot&lt;span style=&#34;font-family: 宋体;&#34;&gt;教授的这个讲座在网页上写的标题是：&lt;/span&gt;IEEE&amp;nbsp;Distinguished&amp;nbsp;Lecture&amp;nbsp;Talk。多么气质不凡的&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Distinguished&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;啊！！！作为一个小工程硕，实在有受宠若惊之感。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    讲座的大概讲的&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Kot&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;教授提出了如何构建一个新颖的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(novel)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;系统来保证&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Biometric&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;信息在服务端的安全。即使这部分信息泄露出去，攻击者也不能够利用它。首先什么是&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;BIOMETRIC&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;呢？你的指纹，你的面部，你的头发&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;#8230;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;都属于&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Biometric&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。其实&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Biometric&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;对于大家都不会陌生，指纹考勤系统实在是相当之普遍啊。而且科幻或者犯罪电影里还有虹膜校验。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Kot&lt;span style=&#34;font-family: 宋体;&#34;&gt;教授提出&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Biometric&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的验证系统的不安全的方面，如果被泄露出去，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Biometric&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;信息不像普通密码一样容易被更换，一但被伪造这样就会比传统的验证方法更加麻烦。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Prof.&amp;nbsp;Kot&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;简单地&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;walk&amp;nbsp;through&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;了几个保护&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Biometric&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的解决方案，并说明&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Biometric&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;信息是可以被利用被伪造的。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    PPT&lt;span style=&#34;font-family: 宋体;&#34;&gt;中多次提到&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;M&lt;/span&gt;inutiae&lt;span style=&#34;font-family: 宋体;&#34;&gt;的概念，一直没听明白啊！貌似是从原始的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Biometric&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;信息中提取出部分信息而作为用来验证的数据。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Professor&amp;nbsp;Kot&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;论证常见的基于指纹的验证系统的弊端。论证中非常多的&amp;ldquo;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;valley&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;&amp;rdquo;，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&#34;ridge&#34;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，比较变换前后的差异。不明白啊，不明白！大概的结论是目前的技术可以做到从&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Minutiae&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;中&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;reconstruct&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;到原始的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;original&amp;nbsp;fingerprint&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。后来想这时候论证的是为了支撑其后&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Prof.&amp;nbsp;Kot&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;提出的新的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;novel&amp;nbsp;solution.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Kot&lt;span style=&#34;font-family: 宋体;&#34;&gt;提出的解决方案是在采集指纹信息时需要采集用户的两个不同的手指，然后综合这两个手指的信息计算出一个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Minutiae&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。这个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Minutiae&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;与从采集单个手指得到的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Minutiae&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;几乎没有差别。因为这个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Minutiae&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;记载的是两个不同手指的信息，而且每个手指仅仅只记部分信息。这样的话，即使攻击者盗取了这个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Minutiae&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，它就无法原始到原始的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;fingerprint&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。按我自己的理解，攻击者应该也不清楚它还原得到的指纹其实并不存在，因为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Minutiae&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;是两个指纹的信息合成的而且与由单个指纹得到的几乎一样，攻击者无法分辨。攻击者应该会沾沾自喜&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;reconstruct&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;到了被误导的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;original&amp;nbsp;finger&amp;nbsp;print&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Kot&lt;span style=&#34;font-family: 宋体;&#34;&gt;还指出在他提出的这个解决方案中可以嵌入信息记到&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Minutiae&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;里面。在后面的提问阶段。有同学问到这个解决方案可以存入多少信息。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Kot&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;补充目前可以存一千多个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Bit&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;位信息，足够存下重要的身份认证数据了。按我自已的理解，能存多少信息应该是可以根据需要调大和缩小的呀。比如把图形转成矢量图形后，就可以不失真的放大，于是就会有更多存储空间了。不确定是不是这样。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    提问阶段&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Kot&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;指出这个设计没有使用&lt;/span&gt;token或者key&lt;span style=&#34;font-family: 宋体;&#34;&gt;因此会运行的非常迅速。而如果采用复杂的加解密算法，则会有非常大的计算开销。运行速度对于一些嵌入式的电子系统是至关重要的。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    有同学提问提到做&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Face&amp;nbsp;Recognition&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，问&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Kot&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;教授有什么看法。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Kot&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;认为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Face&amp;nbsp;Recognition&amp;nbsp;is&amp;nbsp;very&amp;nbsp;difficult,&amp;nbsp;very&amp;nbsp;very&amp;nbsp;difficult,&amp;nbsp;few&amp;nbsp;advancement&amp;nbsp;has&amp;nbsp;been&amp;nbsp;achieved&amp;nbsp;nowadays.&amp;nbsp;It&#39;s&amp;nbsp;a&amp;nbsp;very&amp;nbsp;tough&amp;nbsp;problem.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    At&amp;nbsp;last,&amp;nbsp;as&amp;nbsp;a&amp;nbsp;conclusion&amp;nbsp;for&amp;nbsp;this&amp;nbsp;report,&amp;nbsp;I&amp;nbsp;must&amp;nbsp;show&amp;nbsp;my&amp;nbsp;great&amp;nbsp;respect&amp;nbsp;to&amp;nbsp;Alex&amp;nbsp;Kot.&amp;nbsp;He&amp;nbsp;is&amp;nbsp;a&amp;nbsp;great&amp;nbsp;scientist.
  &lt;/p&gt;
  &lt;p&gt;
    /////////////////
  &lt;/p&gt;
  &lt;p align=&#34;center&#34;&gt;
    &lt;strong&gt;IEEE Distinguished Lecture Talk&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;Title&lt;/strong&gt;&lt;strong&gt;：&lt;/strong&gt;&lt;strong&gt;Is your biometric data safe?&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;Speaker&lt;/strong&gt;&lt;strong&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;：&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;Prof. Alex C Kot, &lt;/strong&gt;&lt;strong&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;新加坡南洋理工大学教授、&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;IEEE Fellow&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;时&lt;/strong&gt;&lt;strong&gt;&amp;nbsp; &lt;/strong&gt;&lt;strong&gt;间：&lt;/strong&gt;&lt;strong&gt; &amp;nbsp;12月&lt;strong&gt;16&lt;/strong&gt;&lt;strong&gt;日&lt;/strong&gt;（本周五）下午&lt;/strong&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;strong&gt;：&lt;/strong&gt;&lt;strong&gt;00&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;地&lt;/strong&gt;&lt;strong&gt;&amp;nbsp; &lt;/strong&gt;&lt;strong&gt;点：&lt;/strong&gt;&lt;strong&gt;&amp;nbsp; &lt;/strong&gt;&lt;strong&gt;信息科技学院大楼二楼207&lt;/strong&gt;&lt;strong&gt;讲学厅&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;主持人：&lt;/strong&gt;&lt;strong&gt; &amp;nbsp;&lt;/strong&gt;&lt;strong&gt;黄继武 &lt;/strong&gt;教授
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;主办单位：信息科学与技术学院、&lt;/strong&gt;&lt;strong&gt;IEEE Signal Processing Society Guangzhou Chapter, IEEE Circuits and Systems Society Guangzhou Chapter&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-family: 宋体;&#34;&gt;&amp;nbsp;&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;Abstract&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;Nowadays, biometrics is widely used in authentication systems. In general, biometrics needs to be stored in a database for subsequent authentication. However, templates stored in the database are at the risk of being stolen or modified. Once the template is stolen, it is difficult to be replaced like passwords and the private user information associated with the stolen template would also be exposed. Thus, biometrics templates should be stored in the database such that both the security of the template and the privacy of the user are not compromised under various attacks.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-family: 宋体; font-size: small;&#34;&gt;&amp;nbsp;&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;&amp;nbsp;We first propose a fingerprint authentication system for the privacy protection of the fingerprint template stored in a database. The considered fingerprint data is a binary thinned fingerprint image, which will be embedded with some private user information without causing obvious abnormality in the enrollment phase. In the authentication phase, these hidden user data can be extracted from the stored template for verifying the authenticity of the person who provides the query fingerprint. A novel data hiding scheme is proposed for the thinned fingerprint template. Compared with using existing binary image data hiding techniques, the proposed method causes the least abnormality for a thinned fingerprint without compromising the performance of the fingerprint identification.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-family: 宋体; font-size: small;&#34;&gt;&amp;nbsp;&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;The minutiae is another type of data stored in a fingerprint template. We investigate to what extreme a reconstructed fingerprint can be similar to the original fingerprint. A new scheme is proposed to reconstruct a full fingerprint image from the minutiae points.&amp;nbsp; Experimental results show that the successful match rate between our reconstructed fingerprint and the original fingerprint is over 99% at FAR=10&lt;sup&gt;-4&lt;/sup&gt;. When matched against the different impressions of the original fingerprint, our reconstructed fingerprint has over 86% successful match rate at FAR=10&lt;sup&gt;-4&lt;/sup&gt;. We consider the privacy issues of the fingerprint reconstruction. The analysis shows that our proposed technique is useful for protecting the fingerprint ridge frequency.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-family: 宋体; font-size: small;&#34;&gt;&amp;nbsp;&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;&amp;nbsp;As a reconstructed fingerprint can be so similar to the original fingerprint, it is also very important to protect the privacy of the minutiae template stored in a database. We propose a novel system for protecting the privacy of the fingerprint minutiae without using a token or key. In the enrollment, two fingerprints are captured from two different fingers of the same person. A combined minutiae template containing only a partial minutiae feature of each of the two fingerprints will be generated and stored in a database. In the authentication, the user needs to provide two query fingerprints from the same two fingers which are used in the enrollment. By storing the combined minutiae template, the complete minutiae feature of a single fingerprint will not be compromised when the database is stolen. Furthermore, because of the similarity in topology, it is also difficult for the attacker to distinguish our template from the minutiae of an original fingerprint. The experimental results show that our system can achieve a very low error rate.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;Biography&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;Dr Kot has been with the Nanyang Technological University, Singapore since 1991. He headed the Division of Information Engineering at the School of Electrical and Electronic Engineering for eight years until 2005. The Division&lt;span style=&#34;font-family: 宋体;&#34;&gt;&amp;rsquo;&lt;/span&gt;s research focuses are on signal processing for image, video, speech and audio. He started serving as Vice-Dean (Research) for the School of EEE in 2005 and became Associate Dean for the College of Engineering in 2008. He is currently a Professor at the School of EEE and Associate Dean for the College of Engineering. He has published extensively with over 200 technical papers and 3 patents in the areas of signal processing for communication, biometrics recognition, data-hiding, authentication and media forensics.&amp;nbsp; &lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-family: 宋体; font-size: small;&#34;&gt;&amp;nbsp;&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;Dr. Kot served as Associate Editor for the IEEE Trans. on Signal Processing, IEEE Trans. on Multimedia, IEEE Trans. on Circuits and Systems for Video Technology; and IEEE Trans. on Circuits and Systems Part II as well as Part I. He also served as Guest Editor for the Special Issues for the IEEE Trans/ on CSVT and JASP. He is currently Associate Editor for the IEEE Trans. on Information, Forensics and Security, IEEE Trans. on Image Processing and IEEE Signal Processing Letter. He is also Editor for the EURASIP Journal of Advanced Signal Processing, the IEEE Signal Processing Magazine and the IEEE Journal of the Special Topics in Signal Processing. He is an Editorial Board member of the Journal of Fundamental and Theory in Signal Processing. He serves in the IEEE CAS Visual Signal Processing and Communication, the IEEE SPS Image and Video Multi-dimensional Signal Processing and IEEE SPS Information Forensic and Security technical committees. He has served the IEEE Society in various capacities such as the General Co-Chair for the 2004 IEEE International Conference on Image Processing (ICIP) and Chair of the worldwide SPS Chapter Chairs and the Distinguished Lecturer program. He serves as IEEE Fellow Evaluation Committee. He received the Best Teacher of the Year Award and is a co-author for several Best Paper Awards including ICPR, WIFS and IWDW. He was the IEEE Distinguished Lecturer in 2005 and 2006 and is a Fellow of IEEE and IES. &lt;/span&gt;
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>Distributed Framework for Iterative Computations on Massive Datasets</title>
      <link>https://ykyi.net/?p=300/</link>
      <pubDate>Fri, 16 Dec 2011 16:14:26 +0000</pubDate>
      <guid>https://ykyi.net/?p=300/</guid>
      <description>&lt;div&gt;
  I&amp;nbsp;must&amp;nbsp;confess&amp;nbsp;I&#39;ve&amp;nbsp;only&amp;nbsp;got&amp;nbsp;a&amp;nbsp;few&amp;nbsp;words&amp;nbsp;and&amp;nbsp;a&amp;nbsp;vague&amp;nbsp;skeleton&amp;nbsp;of&amp;nbsp;what&amp;nbsp;the&amp;nbsp;Professer&amp;nbsp;Lixin&amp;nbsp;Gao&amp;nbsp;said&amp;nbsp;due&amp;nbsp;to&amp;nbsp;the&amp;nbsp;language&amp;nbsp;barrier,&amp;nbsp;during&amp;nbsp;the&amp;nbsp;whole&amp;nbsp;speech&amp;nbsp;Ms&amp;nbsp;Gao&amp;nbsp;spoke&amp;nbsp;English,&amp;nbsp;and&amp;nbsp;the&amp;nbsp;topic&amp;nbsp;is&amp;nbsp;so&amp;nbsp;pedantic&amp;nbsp;which&amp;nbsp;is&amp;nbsp;full&amp;nbsp;of&amp;nbsp;the&amp;nbsp;complicated&amp;nbsp;mathematic&amp;nbsp;formulation.Personally&lt;span style=&#34;font-family: 宋体;&#34;&gt;，我未有涉及过海量数据并行计算以至云计算相关的任何技术，基本上对于海量数据的所有技术都让我觉得非常地&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;cutting-edge&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。带着学习开拓眼界拓展知识面的良好愿望参加了&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Ms.&amp;nbsp;Gao&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的学术讲座。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Ms.&amp;nbsp;Gao&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;讲&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;PPT&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;时全是英文啊。我努力地听，努力地听！！！适当地记些笔记。其实还是很喜欢听英语的。&lt;/span&gt;&amp;nbsp;&lt;/p&gt; 
  &lt;p&gt;
    讲座先列举了一些大型互联网公司的数据显示集群计算的规模。比如谷歌在数据中心有一百万台服务器！！！&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Holy&amp;nbsp;gosh&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;1,000,000&amp;nbsp;servers&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;！！！&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    然后谈到了很多大规模数据的计算对时间的要求非常地严格。于是谈到了目前流行的算法：&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;MapReduce&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;MapReduce是&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;google&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;提倡的&lt;/span&gt;一种编程模型，用于大规模数据集（大于&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;1TB&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;）的并行运算。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;ldquo;Map&amp;rdquo;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;ldquo;Reduce&amp;rdquo;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，和他们的主要思想，都是从函数式编程语言里&lt;/span&gt;继承来的，还有从矢量编程语言里借来的特性。他极大地方便了编程人员在不会分布式并行&amp;nbsp;编程的情况下，将自己的程序运行在分布式系统上。我自己的理解是：map&lt;span style=&#34;font-family: 宋体;&#34;&gt;索引整个海量数据，生成&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;key-value&amp;nbsp;pair&amp;nbsp;which&amp;nbsp;is&amp;nbsp;used&amp;nbsp;to&amp;nbsp;facilitate&amp;nbsp;the&amp;nbsp;quick&amp;nbsp;query&amp;nbsp;and&amp;nbsp;computing&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。而&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;reduce&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;则是用来分析和统筹基于键值对的中间计算结果，使中间结果迅速向最终的正确结果收敛。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Ms.&amp;nbsp;Gao&amp;nbsp;&lt;span style=&#34;font-family: 宋体;&#34;&gt;提出&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;MapReduce&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;虽然是工业界非常&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;popular&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的解决方案，但是不可以以迭代的方式计算。而&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Ms.&amp;nbsp;Gao&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;所做的工作即是使&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;MapReduce&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;支持迭代的功能。（&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;A&amp;nbsp;framework&amp;nbsp;that&amp;nbsp;support&amp;nbsp;iterative&amp;nbsp;computing&amp;nbsp;in&amp;nbsp;the&amp;nbsp;cloud.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;）从事情一般规律的哲学高度看待这个问题，对于规模相当大或者最终结果是相当不明确的问题，似乎都可以用到&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&#39;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;迭代&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&#39;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的思想。例如，迭代的软件开发模式则是当今互联网应用的主要开发模式。每一次迭代都使产品向理想中最&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;perfect&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的状态接近。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Ms.&amp;nbsp;Gao&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;用迭代的思想处理海量数据应该也是同样的道理罢！&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Ms.&amp;nbsp;Gao&lt;span style=&#34;font-family: 宋体;&#34;&gt;的解释说改进后支持迭代的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;iMapReduce&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;可以使&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;map&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;后的数据支撑&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;reduce,reduce&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的数据亦转而支撑&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;map&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，形成一个迭代反复的过程，其中在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;map&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;阶段加入&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;static&amp;nbsp;data&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。较之原始的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;MapReduce&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，新的算法使得&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;static&amp;nbsp;data&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的规模显著地减少。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Ms.&amp;nbsp;Gao&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;展示了几个图表证明改进后增加了迭代功能的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;MapReduce(&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;称之为&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;iMapReduce&amp;nbsp;)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的速度优于原始的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;MapReduce.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;图表中有展示用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;iMapReduce&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;计算&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;PageRank&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的值。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;PageRank&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;？是不是判断网站权重的那个东东啊？哥的网站&lt;/span&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;http://ykyi.net&lt;/span&gt;&lt;/a&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;PageRank&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;才&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;啊！！！才&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;啊&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;~~&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;用什么算法可以算成&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;啊！&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    PPT&lt;span style=&#34;font-family: 宋体;&#34;&gt;转到计算图的指定两点最短路径的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Dijkstra&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;算法。泪流满面，终于有一个我懂的算法了啊！&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Ms.&amp;nbsp;Gao&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;说先找到两个结点间的最短路径，于是赋于这个最短路径经过的结点最高的权重，其它的路径就赋于相对低的权重。提出了&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;PriorityQueue&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的数据结构。把权重引入到&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;iMapReduce&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;算法，称之为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;pMapReduce&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;算法。引入权重后的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;pMapReduce&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;算法比&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;iMapReduce&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;算法的速度更快。生活中我们做事情也要优先处理最重要的事情，道理是一样的啊！世间万事万物，无论多么复杂，抽象出来的一般规律其实都是相当地一致。易经中说：形而下者谓之器，形而上者谓之道！&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Oops,&amp;nbsp;The&amp;nbsp;ancient&amp;nbsp;Tao&amp;nbsp;philosophy&amp;nbsp;is&amp;nbsp;f&lt;/span&gt;ull&amp;nbsp;Of&amp;nbsp;Wisdom.
  &lt;/p&gt;
  &lt;p&gt;
    最后阶段，再次展示了一个图表，&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Ms.&amp;nbsp;Gao&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;完成的建立在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Apache&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Hadoop&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;上的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;pMapReduce&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;要明显的优于原始的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Hadoop&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。并且也优先其它多种解决方案，其它的名字我都没听过啊！在提问阶段，尽管温武少老师积极鼓励同学提问但没有同学提出问题，大概大家都不懂吧！朝红阳老师和另一位研究海量数据的老师谈了一点点。他们提到&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;iterative&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的算法在他们的实际应用中效果并不是太明显，不如&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;memory-based&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的解决方案。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Ms.&amp;nbsp;Gao&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;调出一张图表，解释说某种&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;memory-based&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的解决方案没有迭代的算法快。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    作为众多打酱油的同学中的一员，我最后的心得体会是：学术真是太高深了啊！我还是做工程吧！！！车，我有得拣咩？
  &lt;/p&gt;
  &lt;p&gt;
    /////////////////////////
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;Topic &lt;/strong&gt;
  &lt;/p&gt;
  &lt;div&gt;
    Distributed Framework for Iterative Computations on Massive Datasets
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;strong&gt;Speaker&lt;/strong&gt;
  &lt;/div&gt;
  &lt;div&gt;
    Prof. Lixin Gao
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;strong&gt;Abstract&lt;/strong&gt;
  &lt;/div&gt;
  &lt;div&gt;
    Iterative algorithms are pervasive in many applications such as search engine algorithms,machine learning, and recommendation systems. These applications typically involve a dataset of massive scale. Fast iterative computations of the massive datasets are essential for these applications. This is particular important for on-line query such as keyword based search query. In this talk, we present an overview of MapReduce framework, and propose two frameworks, iMapReduce and pMapReduce, that enable fast iterative computations. By providing the support of iterative computations and prioritized execution, we can ensure faster convergence of the iterative process. Both iMapReduce and pMapReduce preserve the MapReduce distributed computing framework and is particularly efficient for online queries such as top-k queries. We implement iMapReduce and pMapReduce based on Apache Hadoop and evaluate its performance. Our evaluation results show that pMapReduce can reduce the computation time by two orders of magnitude comparing to that achieved with MapReduce. At the end of the talk, I will provide an overview of on-going projects in my research group.
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;strong&gt;Bio&lt;/strong&gt;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;strong&gt;&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; alt=&#34;&#34; height=&#34;289&#34; src=&#34;http://ss.sysu.edu.cn/informationsystem/articlefiles/image001%2830%29.jpg&#34; width=&#34;228&#34; /&gt;&lt;/strong&gt;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;div&gt;
      Lixin Gao is a professor of Electrical and Computer Engineering at the University of Massachusetts at Amherst. She received her Ph.D. degree in computer science from the University of Massachusetts at Amherst in 1996. Her research interests include social networks, and Internet routing, network virtualization and cloud computing. Between May 1999 and January 2000, she was a visiting researcher at AT&amp;T Research Labs and DIMACS. She was an Alfred P. Sloan Fellow between 2003-2005 and received an NSF CAREER Award in 1999. She won the best paper award from IEEE INFOCOM 2010 and her paper in ACM Cloud Computing 2011 was honored with &amp;ldquo;Paper of Distinction&amp;rdquo;. She received the Chancellor&amp;rsquo;s Award for Outstanding Accomplishment in Research and Creative Activity in 2010, and is a fellow of IEEE.
    &lt;/div&gt;&lt;/p&gt;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;p&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/p&amp;gt;

&amp;lt;div&amp;gt;
  &amp;lt;strong&amp;gt;Date and Venue&amp;lt;/strong&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  Dec.16（Friday）13:30pm-14:30pm
&amp;lt;/div&amp;gt;

&amp;lt;div&amp;gt;
  Lecture Theater A101, School of Software, Sun Yat-sen University
&amp;lt;/div&amp;gt;&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>Unix网络编程.第七章笔记</title>
      <link>https://ykyi.net/?p=296/</link>
      <pubDate>Thu, 15 Dec 2011 06:33:56 +0000</pubDate>
      <guid>https://ykyi.net/?p=296/</guid>
      <description>&lt;div&gt;
  1.&amp;nbsp;有一个&amp;nbsp;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Generic&amp;nbsp;Socket&amp;nbsp;Option&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;：&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SO_BROADCAST&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;用来开启是否充许广播。&lt;/span&gt;2.&amp;nbsp;仅有&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;TCP&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;支持&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SO_DEBUG&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Kernel&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;把详细的发送包的接收包信息存在一个环路&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;buffer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;里。可以用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;trpt&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;查看它。&lt;/span&gt;3.&amp;nbsp;SO_ERROR&lt;span style=&#34;font-family: 宋体;&#34;&gt;套接字选项只能被取得，不能被设置。如果进程阻塞在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;select&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;调用里，不论是读还是写，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;select&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;都会返回&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;conditions&amp;nbsp;set&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。如果进程使用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;signal-driven&amp;nbsp;I/O&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，则&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SIGIO&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;信号会被发到这个进程或者它所在的进程组。进程用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;getsockopt&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;得到&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;so_error&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;后，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;so_error&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就会被重置为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;0.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;如果&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;so_error&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;不为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，此时调用&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;read&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;或者&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;write&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就会立即返回&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;-1&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;errno&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;被置为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;so_error&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的值。&lt;/span&gt;&lt;/p&gt; 
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    4.&amp;nbsp;SO_KEEPALIVE&lt;span style=&#34;font-family: 宋体;&#34;&gt;在一个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;tcp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;连接没有任何收发达两个小时时会发一个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;prob&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;给对方。两个钟喔。好长的时间啊！！！&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Richard&amp;nbsp;Stevens&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;认为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SO_KEEPALIVE&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;应该改叫&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;make-dead&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。大多&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Unix&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;kernel&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;把这个两小时时长存为一个系统级的变量。这意味着如果你用某种方法改变了这个时长，会影响这个操作系统的所有&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;socket.Richard&amp;nbsp;Stevens&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;认为想把这个时长改短的想法是错误理解了这个选项的意义。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    5.&amp;nbsp;SO_LINGER&lt;span style=&#34;font-family: 宋体;&#34;&gt;仅仅适用于面向连接的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;socket&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，比如&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;TCP&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SCTP&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，因此不适用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;UDP&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Struct&amp;nbsp;linger{
  &lt;/p&gt;
  &lt;p&gt;
    int&amp;nbsp;l_onofff;
  &lt;/p&gt;
  &lt;p&gt;
    int&amp;nbsp;l_linger;
  &lt;/p&gt;
  &lt;p&gt;
    };
  &lt;/p&gt;
  &lt;p&gt;
    L_onoff&lt;span style=&#34;font-family: 宋体;&#34;&gt;为零是，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;behavior&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就是默认情况：&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;立即返回，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;kernel&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;继续发送缓冲区内未发送的数据。当&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;l_onoff&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;不为零，而&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;l_linger&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;TCP&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;协议则会立即终止连接，发送&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;RST&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;给&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;peer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;端，这样做避免了&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;TCP&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;TIME_WAIT&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;状态，这样的坏处是&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;:&amp;nbsp;leaves&amp;nbsp;open&amp;nbsp;the&amp;nbsp;possibility&amp;nbsp;of&amp;nbsp;another&amp;nbsp;incarnation&amp;nbsp;of&amp;nbsp;this&amp;nbsp;connection&amp;nbsp;being&amp;nbsp;created&amp;nbsp;within&amp;nbsp;2MSL&amp;nbsp;seconds&amp;nbsp;and&amp;nbsp;having&amp;nbsp;old&amp;nbsp;duplicate&amp;nbsp;segments&amp;nbsp;from&amp;nbsp;the&amp;nbsp;just-terminated&amp;nbsp;connection&amp;nbsp;being&amp;nbsp;incorrectly&amp;nbsp;delivered&amp;nbsp;to&amp;nbsp;the&amp;nbsp;new&amp;nbsp;incarnation.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;对于&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SCTP,&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;也会发送一个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ABORT&amp;nbsp;chunk&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;给&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;peer.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;第三种情况：如果&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;l_onoff&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;为真，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;l_linger&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;不为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;0.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;则&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;不会立即返回，会最多等待指定的时长，在这段时间里&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;kernel&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;发送缓冲区内的数据给&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;peer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。如果在这段时间内发送完则&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;返回&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;0.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;如果没有发送完毕，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就会返回&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;EWOULDBLOCK&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;send&amp;nbsp;buffer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;里的数据会被丢弃。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    6.&amp;nbsp;MSL:&amp;nbsp;maximum&amp;nbsp;segment&amp;nbsp;lifetime.
  &lt;/p&gt;
  &lt;p&gt;
    7.&amp;nbsp;因此&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;默认情况下立即返回，即使用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SO_LINGER&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;设置等待时间也在理论上存在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;先于发送缓冲区的数据被&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;peer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;端&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;acknowleded&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的情况。因此一个更好的解决方案是用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;shutdown&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;系统调用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;with&amp;nbsp;a&amp;nbsp;second&amp;nbsp;argument&amp;nbsp;of&amp;nbsp;SHUT_WR&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。在调用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;shutdown&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;后，用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;read&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;调用直到&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;read&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;返回&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，即收到&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;peer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;端的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;FIN&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    8.&amp;nbsp;UDP&lt;span style=&#34;font-family: 宋体;&#34;&gt;没有&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;congestion&amp;nbsp;control&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，如果发得太快，不仅仅&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;peer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;端来不及收。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;A&amp;nbsp;fast&amp;nbsp;sender&amp;nbsp;can&amp;nbsp;overwhelm&amp;nbsp;its&amp;nbsp;own&amp;nbsp;network&amp;nbsp;interface,&amp;nbsp;causing&amp;nbsp;datagrams&amp;nbsp;to&amp;nbsp;be&amp;nbsp;discarded&amp;nbsp;by&amp;nbsp;the&amp;nbsp;sender&amp;nbsp;itself.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    9.&amp;nbsp;因为&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;tcp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;在三次握手阶段的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SYN&amp;nbsp;segment&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;里交换窗口大小&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(windows&amp;nbsp;scale)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。所以&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;tcp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的接收缓冲大小必须在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;shank&amp;nbsp;hands&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;之前就设置好。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Connected&amp;nbsp;socket&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;从&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;listening&amp;nbsp;socket&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;继承这个选项。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    10.&amp;nbsp;TCP&lt;span style=&#34;font-family: 宋体;&#34;&gt;的套接字缓冲区大小至少需要是&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;倍&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;MSS&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的大小。&lt;/span&gt;这里指的套接字缓冲，如果是针对单向的传输，比如单向传一个文件，指的是发送方的发送缓冲和接收方的接收缓冲。如果是双向的传输，则指的是双方的接收和发送缓冲。为什么&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;tcp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;套接字的缓冲区需要至少&amp;nbsp;&amp;nbsp;&amp;nbsp;是&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;倍&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;MSS&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的大小呢？&lt;/span&gt;这是因为&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;tcp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的快恢复&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(fast&amp;nbsp;recovery)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;算法。快恢复算法定义：如果接收端连续收到三个同样的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ACK&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，就认为有&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;packet&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;丢失了。而接收端在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;segment&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;丢失后，每收到新的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;segment&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就不停地重发一个重复的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ack&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;给&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;sender&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。如果窗口大小小于&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;segments,&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就不会有三个重复的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ACK,&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;所以快恢复算法就没办法工作了。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    11.&amp;nbsp;What&amp;nbsp;is&amp;nbsp;bandwidth-delay&amp;nbsp;product.
  &lt;/p&gt;
  &lt;p&gt;
    A:&amp;nbsp;The&amp;nbsp;capacity&amp;nbsp;of&amp;nbsp;the&amp;nbsp;pipe&amp;nbsp;is&amp;nbsp;called&amp;nbsp;the&amp;nbsp;bandwidth-delay&amp;nbsp;product&amp;nbsp;and&amp;nbsp;we&amp;nbsp;calculate&amp;nbsp;this&amp;nbsp;by&amp;nbsp;multiplying&amp;nbsp;the&amp;nbsp;bandwidth(in&amp;nbsp;bits/sec)&amp;nbsp;times&amp;nbsp;the&amp;nbsp;RTT(in&amp;nbsp;seconds),&amp;nbsp;converting&amp;nbsp;the&amp;nbsp;result&amp;nbsp;from&amp;nbsp;bits&amp;nbsp;to&amp;nbsp;bytes.&amp;nbsp;&lt;span style=&#34;font-family: 宋体;&#34;&gt;即网速乘上&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;RTT.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    12.&amp;nbsp;UDP&lt;span style=&#34;font-family: 宋体;&#34;&gt;没有&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;send&amp;nbsp;buffer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，但有一个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;send&amp;nbsp;buffer&amp;nbsp;size.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;只要&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;socket&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;buffer&amp;nbsp;size&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;大于&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;LO_WATER&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，就永远是可写的。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    13.&amp;nbsp;SO_REUSEADDR&lt;span style=&#34;font-family: 宋体;&#34;&gt;有四种用途。好难写。见&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Unix&amp;nbsp;Network&amp;nbsp;Programming&amp;nbsp;Section&amp;nbsp;7.5&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;影印版第&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;211&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;页啦。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    14.&amp;nbsp;It&#39;s&amp;nbsp;Ok&amp;nbsp;for&amp;nbsp;the&amp;nbsp;MSS&amp;nbsp;to&amp;nbsp;be&amp;nbsp;different&amp;nbsp;in&amp;nbsp;each&amp;nbsp;direction.
  &lt;/p&gt;
  &lt;p&gt;
    15.&amp;nbsp;Nagle&lt;span style=&#34;font-family: 宋体;&#34;&gt;算法是为了减少&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;small&amp;nbsp;package&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的数量.&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;The&amp;nbsp;algorithm&amp;nbsp;states&amp;nbsp;that&amp;nbsp;if&amp;nbsp;a&amp;nbsp;given&amp;nbsp;connection&amp;nbsp;has&amp;nbsp;outstanding&amp;nbsp;data,&amp;nbsp;then&amp;nbsp;no&amp;nbsp;small&amp;nbsp;packets&amp;nbsp;will&amp;nbsp;be&amp;nbsp;sent&amp;nbsp;on&amp;nbsp;the&amp;nbsp;connection&amp;nbsp;in&amp;nbsp;response&amp;nbsp;to&amp;nbsp;a&amp;nbsp;user&amp;nbsp;write&amp;nbsp;operation&amp;nbsp;until&amp;nbsp;the&amp;nbsp;existing&amp;nbsp;data&amp;nbsp;is&amp;nbsp;acknowledged.&amp;nbsp;Small&amp;nbsp;package&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;指的是任何比&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;MSS&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;小的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;package.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    16.&amp;nbsp;Delayed&amp;nbsp;ACK&amp;nbsp;algorithm:&amp;nbsp;This&amp;nbsp;algorithm&amp;nbsp;causes&amp;nbsp;TCP&amp;nbsp;to&amp;nbsp;not&amp;nbsp;send&amp;nbsp;an&amp;nbsp;ACK&amp;nbsp;immediately&amp;nbsp;when&amp;nbsp;it&amp;nbsp;receives&amp;nbsp;data;&amp;nbsp;instead,&amp;nbsp;TCP&amp;nbsp;will&amp;nbsp;wait&amp;nbsp;some&amp;nbsp;small&amp;nbsp;amount&amp;nbsp;of&amp;nbsp;time&amp;nbsp;(typically&amp;nbsp;50-200ms)and&amp;nbsp;only&amp;nbsp;then&amp;nbsp;send&amp;nbsp;the&amp;nbsp;ACK.
  &lt;/p&gt;
  &lt;p&gt;
    17.&amp;nbsp;SCTP&lt;span style=&#34;font-family: 宋体;&#34;&gt;有一个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SCTP_AUTOCLOSE&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;套接字选项。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;This&amp;nbsp;option&amp;nbsp;allows&amp;nbsp;us&amp;nbsp;to&amp;nbsp;fetch&amp;nbsp;or&amp;nbsp;set&amp;nbsp;the&amp;nbsp;autoclose&amp;nbsp;time&amp;nbsp;for&amp;nbsp;an&amp;nbsp;SCTP&amp;nbsp;endpoint.&amp;nbsp;The&amp;nbsp;autoclose&amp;nbsp;time&amp;nbsp;is&amp;nbsp;the&amp;nbsp;number&amp;nbsp;of&amp;nbsp;seconds&amp;nbsp;an&amp;nbsp;SCTP&amp;nbsp;association&amp;nbsp;will&amp;nbsp;remain&amp;nbsp;open&amp;nbsp;when&amp;nbsp;idle.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;即&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SCTP&amp;nbsp;association&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;能够保持空闲状态的最长时间。超时就会被关闭。&lt;/span&gt;
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>人类中心主义未必导致环境的破坏.自然辩证法作业</title>
      <link>https://ykyi.net/?p=266/</link>
      <pubDate>Thu, 15 Dec 2011 02:46:01 +0000</pubDate>
      <guid>https://ykyi.net/?p=266/</guid>
      <description>&lt;p&gt;人类中心主义是一种价值尺度。它主张把人类的利益作为价值原点和道德评价的依据，有且只有人类才是价值判断的主体。作为这个星球上唯一具备高级的情感，复杂的逻辑思维，有复杂的语言系统等等一般生物所不具备的特征的生物。人类明显区别于其它生物种类。人类要生存与发展，不断实现人类价值的提升突破，当然要利用我们生存的环境中的其它生物和自然物。&lt;/p&gt;
&lt;p&gt;有一种观点认为：人类中心主义将会导致环境的破坏。这种观点实际上并没有真正理解什么是人类中心主义。人类中心主义最重要最核心的一点，它把是否符合人类的利益作为是非评价的标准。按照这样的价值尺度，又依据破坏环境的行为将最终损坏人类的利益，那么，破坏坏境的行为显然就不是人类中心主义所主张的！恰恰相反，人类中心主义为了维护人类的利益，就要毫不含糊地，旗帜鲜明地支持保护环境。&lt;/p&gt;
&lt;p&gt;那么为什么会有那么多人把人类中心主义与环境保护对立起来呢？我想，是因为这些人并未真正理解人类中心主义的中心思想。一个重要的原因是一部分人想当然的把人类中心与环境保护对立起来。另一个重要的原因还在于很多伪人类中心主义者为了短期的眼前利益，为了一时一刻一朝一夕的短期发展，不惜牺牲环境。伪人类中心主义者也自称是人类中心主义者，实际上他们的所作所为与真正的人类中心主义者背道而驰。这些自我标榜的人类中心主义者并不是少数，他们在社会上为人类主心主义造成了相当的负面影响，于是影响了公众对人类中心主义的看法。&lt;/p&gt;
&lt;p&gt;作为结论，为了从根本上长远地使我们生活的环境有符合人类的利益，有利于人类的生存与发展。我们在判断一件事是否符合人类中心主义的价值尺度时，不能仅仅着眼于眼前和局部利益，而是要站在更高更远的位置着眼于大局，着眼于长期发展。这样，就能同伪人类中心主义者划清界限。&lt;/p&gt;
&lt;p&gt;就人类中心主义的现实意义来讲。我国在过去半个多世纪的发展，尤其是近三十年来的发展只是片面的追求短期的GDP指标，忽略了对环境的保护。这样的粗放型发展模式已经难以为继。在目前的中国社会中，因为忽视环境保护而造成的负面影响已经越来越明显，越来越频繁的表现出来。如频繁的自然灾害，如最近媒体集中关注的北京空气质量问题。这样的发展模式最终损害了人类的利益，实际上是不符人类中心主义主张的。&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;  zausiu’s blog&lt;/p&gt;
&lt;p&gt;新千年伊始胡温政府提出的科学发展观就是为了解决上文提到的偏差。其实际效果却不能说”成效显著”。对于如此宠大的一个十亿人口的大国，环境问题极端重要，每个人都必须意识到掠夺式地破坏坏境最终会损害社会大众的共同利益，也会损害自已的利益。&lt;/p&gt;</description>
    </item>
    <item>
      <title>中大sicily 1426. Phone List 解题报告</title>
      <link>https://ykyi.net/?p=280/</link>
      <pubDate>Sun, 11 Dec 2011 15:50:04 +0000</pubDate>
      <guid>https://ykyi.net/?p=280/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;div&gt;
    1.原题中文大意;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    给出一组数字，最多一万个，判断这组数字中是否存在一个数字是其它一个数字的前缀。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    2.算法思想及解题用到的主要数据结构;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    每读入一个数字字符串，则把该数字串从高位到低位分解成一个个数字字符。然后开始以最高位数字为树的根，第二个数字为根的子孙结点，第三个数字为第二个数字的子孙结点。如果碰到最后一个数字，如果这组数字符合要求的话则最后一个数字字符一定是叶子结点。不断的加入新的数字字符串到树中，如果在加入的过程中使以前的叶子结点变成了非叶子结点，或者新加入的数字字符串的最后一个数字在树中不是一个叶子结点，则报告这组数字字符串不符合要求。反之，则符合要求。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    3.逐步求精算法描述（含过程及变量说明）;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    每个结点记下关键信息,一个数字字符。再加上一个指向其它信息的指针. 这个指针指向一个node_data_t结构。结构体中放置了一个tag标签，记字是不是一个数字字符串的最后一个数字；以及一个指向STL的set容器，容器中放置了所有子孙结点。如下代码描述。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    struct node_t
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    {
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    char _ch;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    node_data_t* _data;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    };
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    struct node_data_t
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    {
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    set&lt;node_t, node_comp&gt; &amp;nbsp;_nodes;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    bool _terminal;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    };
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    剩下的逻辑便是分析数字字符串，把每个字符拆出加入树中。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    4.程序注释清单
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;pre class=&#34;brush:cpp&#34;&gt;#include &amp;lt;set&amp;gt;
&lt;p&gt;#include &amp;lt;algorithm&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;cstring&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;cstdlib&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;cstdio&amp;gt;&lt;/p&gt;
&lt;p&gt;using namespace std;&lt;/p&gt;
&lt;p&gt;struct node_comp;&lt;/p&gt;
&lt;p&gt;struct node_data_t;&lt;/p&gt;
&lt;p&gt;struct node_t&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;char _ch;&lt;/p&gt;
&lt;p&gt;node_data_t* _data;&lt;/p&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;struct node_comp  // 给STL的set容器的排序算子。&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;bool operator()(const node_t&amp;amp; left, const node_t&amp;amp; right)const&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;return left._ch &amp;lt; right._ch;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;};
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; zausiu&#39;s blog
struct node_data_t&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;set&amp;lt;node_t, node_comp&amp;gt;  _nodes;&lt;/p&gt;
&lt;p&gt;bool _terminal;  // 标记是不是一个电话号码的终点字符了。&lt;/p&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;typedef set&amp;lt;node_t, node_comp&amp;gt; nodes_set;&lt;/p&gt;
&lt;p&gt;nodes_set top_nodes;&lt;/p&gt;
&lt;p&gt;// 如果已经可以判断电话号码不满足要求就返回false.&lt;/p&gt;
&lt;p&gt;// 递归调用该函数。&lt;/p&gt;
&lt;p&gt;bool odyssey(nodes_set&amp;amp; nodes, const char* num)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;if ( 0 == *num )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;return true;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;//&lt;/p&gt;
&lt;p&gt;node_t node;&lt;/p&gt;
&lt;p&gt;node._ch = *num;&lt;/p&gt;
&lt;p&gt;node._data = new node_data_t;&lt;/p&gt;
&lt;p&gt;node._data-&amp;gt;_terminal = !num[1];&lt;/p&gt;
&lt;p&gt;pair&amp;lt;nodes_set::iterator, bool&amp;gt; retval = nodes.insert(node);&lt;/p&gt;
&lt;p&gt;if ( retval.second )  // 还没有这个数字的结点.新插入的.&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;bool b;&lt;/p&gt;
&lt;p&gt;b = odyssey(retval.first-&amp;gt;_data-&amp;gt;_nodes, num+1);&lt;/p&gt;
&lt;p&gt;return b;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;else  // 已经存在&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;delete node._data;&lt;/p&gt;
&lt;p&gt;// 并且已经是之前一个数字串的最后一个数字字符.或者现在这个字符是最后一个.&lt;/p&gt;
&lt;p&gt;if ( retval.first-&amp;gt;_data-&amp;gt;_terminal || !num[1] )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;return false;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;else if ( !num[1] )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;retval.first-&amp;gt;_data-&amp;gt;_terminal = true;&lt;/p&gt;
&lt;p&gt;return true;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;else&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;retval.first-&amp;gt;_data-&amp;gt;_terminal = false;&lt;/p&gt;
&lt;p&gt;bool b;&lt;/p&gt;
&lt;p&gt;b = odyssey(retval.first-&amp;gt;_data-&amp;gt;_nodes, num+1); // 递归&lt;/p&gt;
&lt;p&gt;return b;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// 释放内存.&lt;/p&gt;
&lt;p&gt;void free_mem(nodes_set&amp;amp; nodes)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;for ( nodes_set::const_iterator ite = nodes.begin();&lt;/p&gt;
&lt;p&gt;ite != nodes.end();&lt;/p&gt;
&lt;p&gt;++ite )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;free_mem(ite-&amp;gt;_data-&amp;gt;_nodes);&lt;/p&gt;
&lt;p&gt;delete ite-&amp;gt;_data;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;nodes.clear();&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;int main(int argc, char* argv[])&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;int case_count;   // 有多少个case&lt;/p&gt;
&lt;p&gt;int phone_num_count;    // 多少个电话霖巴&lt;/p&gt;
&lt;p&gt;char phone_num_str[11];   // 存电话霖巴&lt;/p&gt;
&lt;p&gt;bool successed;  // 一组数字字符串是否符合要求&lt;/p&gt;
&lt;p&gt;scanf(&amp;quot;%d&amp;quot;, &amp;amp;case_count);&lt;/p&gt;
&lt;p&gt;for ( int i = 0; i &amp;lt; case_count; i++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;scanf(&amp;quot;%d&amp;quot;, &amp;amp;phone_num_count);&lt;/p&gt;
&lt;p&gt;successed = true;&lt;/p&gt;
&lt;p&gt;for ( int j = 0; j &amp;lt; phone_num_count; j++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;scanf(&amp;quot;%s&amp;quot;, phone_num_str);&lt;/p&gt;
&lt;p&gt;if ( successed )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;successed = odyssey(top_nodes, phone_num_str);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;if ( successed )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;printf(&amp;ldquo;YES\n&amp;rdquo;);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;else&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;printf(&amp;ldquo;NO\n&amp;rdquo;);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;free_mem(top_nodes);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;return 0;&lt;/p&gt;
&lt;p&gt;}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  5.测试数据
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  用简单的脚本帮助生成测试数据.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  #!/bin/bash
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  INDEX=0
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  if [ -e $1 ];then
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  COUNT=200
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  else
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  COUNT=$1
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  fi
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  while [ $INDEX -lt $COUNT ];do
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  let &#34;INDEX=$INDEX+1&#34;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  echo $RANDOM
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  done
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  6.对时间复杂度，空间复杂度方面的分析.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  本算法的时间复杂度的空间复杂度一般都介于O(logN)和O(N)之间。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  //////////////// 原题 &amp;nbsp;//////////////
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  1426. Phone List
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Description
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Given a list of phone numbers, determine if it is consistent in the sense that no number is the pre?x of another. Let&amp;rsquo;s say the phone catalogue listed these numbers:
&lt;/div&gt;
&lt;div&gt;
  ? Emergency 911
&lt;/div&gt;
&lt;div&gt;
  ? Alice 97 625 999
&lt;/div&gt;
&lt;div&gt;
  ? Bob 91 12 54 26
&lt;/div&gt;
&lt;div&gt;
  In this case, it&amp;rsquo;s not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the ?rst three digits of Bob&amp;rsquo;s phone number. So this list would not be consistent.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Input
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  The ?rst line of input gives a single integer, 1 &amp;le; t &amp;le; 40, the number of test cases. Each test case starts with n, the number of phone numbers, on a separate line, 1 &amp;le; n &amp;le; 10000. Then follows n lines with one unique phone number on each line. A phone number is a sequence of at most ten digits.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Output
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  For each test case, output &amp;ldquo;YES&amp;rdquo; if the list is consistent, or &amp;ldquo;NO&amp;rdquo; otherwise.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Sample Input
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  2
&lt;/div&gt;
&lt;div&gt;
  3
&lt;/div&gt;
&lt;div&gt;
  911
&lt;/div&gt;
&lt;div&gt;
  97625999
&lt;/div&gt;
&lt;div&gt;
  91125426
&lt;/div&gt;
&lt;div&gt;
  5
&lt;/div&gt;
&lt;div&gt;
  113
&lt;/div&gt;
&lt;div&gt;
  12340
&lt;/div&gt;
&lt;div&gt;
  123440
&lt;/div&gt;
&lt;div&gt;
  12345
&lt;/div&gt;
&lt;div&gt;
  98346
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Sample Output
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  NO
&lt;/div&gt;
&lt;div&gt;
  YES
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>Unix网络编程.第五，六章笔记.</title>
      <link>https://ykyi.net/?p=284/</link>
      <pubDate>Sat, 10 Dec 2011 13:56:00 +0000</pubDate>
      <guid>https://ykyi.net/?p=284/</guid>
      <description>&lt;p&gt;# Unix世界里经常看到的 pst  是 pseudo terminal 的意思啊。&lt;/p&gt;
&lt;p&gt;# ps -t pts/6 -o pid,ppid,tty,stat,args,wchan&lt;/p&gt;
&lt;p&gt;ps 命令的进程状态。 S表示进程在睡眠，I表示进程在等待输入，O表示进程在等待输出。当进程在S状态时，wlan指示了更详细的状态信息。&lt;/p&gt;
&lt;p&gt;# SIGSTOP 和 SIGKILL 两个posix信号不可以被caught.&lt;/p&gt;
&lt;p&gt;# 缺省情况下，Unix的信号是不排在队列中的。这意味着多个相同signal到达的时候如果没有来得及处理，就只会记下一个signal.如果需要稳定的信号支持，就要使用RealTime Posix接口。&lt;/p&gt;
&lt;p&gt;# init 进程的PID是 1.&lt;/p&gt;
&lt;p&gt;# 可以用sigprocmask函数block和unblock信号。This let us protect a critical region of code by preventing certain signals from being caught while that region of code is executing.&lt;/p&gt;
&lt;p&gt;# 对于 Unix System V 和 Unix98, the child of a process does not become a zombie if the process sets the disposition of SIGCHLD to SIG_IGN. unfortunately, tis works only under System V &amp;amp; Unix98. Posix明确指票这个行为是未定义的。The portable way to handle zombies is to catch SIGCHILD &amp;amp; call wait or waitpid.&lt;/p&gt;</description>
    </item>
    <item>
      <title>使用Necessitas在Android平台上运行Qt程序失败</title>
      <link>https://ykyi.net/?p=274/</link>
      <pubDate>Fri, 09 Dec 2011 12:31:21 +0000</pubDate>
      <guid>https://ykyi.net/?p=274/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    &lt;strong&gt;什么是&amp;nbsp;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Necessitas?&lt;/span&gt;&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Necessitas&lt;span style=&#34;font-family: 宋体;&#34;&gt;是&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Qt&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Android&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;操作系统上的一个移植，同时提供了&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Qt&amp;nbsp;Creator&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;与&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Android&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的集成。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Necessitas&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;计划为你提供了&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Android&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;平台下的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Qt,&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;以及一个一流的平易近人的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;IDE&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，方便你在安卓平台下管理，开发，部署，运行&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;调试你的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Qt&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;应用。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;什么是&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Minstro?&lt;/span&gt;&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;a href=&#34;http://sourceforge.net/p/necessitas/home/necessitas/&#34;&gt;Necessitas&lt;/a&gt;也是&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Ministro&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的官网。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Ministro&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;LGPL&amp;nbsp;Qt&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;共享库提供了一个系统范围的下载器&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(downloader)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和安装器&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(installer)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。你可以在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Andorid&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;软体市场&lt;/span&gt;&lt;a href=&#34;https://market.android.com/details?id=eu.licentia.necessitas.ministro&#34;&gt;获得&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Ministro&lt;/span&gt;&lt;/a&gt;。
  &lt;/p&gt;
  &lt;p&gt;
    如何安装Necessitas&amp;nbsp;SDK&lt;span style=&#34;font-family: 宋体;&#34;&gt;开发包&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;?&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    相当地&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;easy&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;啊！&lt;/span&gt;&lt;a href=&#34;http://sourceforge.net/projects/necessitas/files/&#34;&gt;http://sourceforge.net/projects/necessitas/files/&lt;/a&gt;&amp;nbsp;下载&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;sdk&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;开发包。有&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;linux,&amp;nbsp;win,&amp;nbsp;mac&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;三个平台下的。安装过程傻瓜式&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;next&amp;nbsp;next&amp;nbsp;next&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。哥尝试在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Linux&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;下安装出错了。安装程序没有加载起来。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    zausiu@potassium:/tmp$&amp;nbsp;./necessitas-0.3-online-sdk-installer-linux&amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    ./necessitas-0.3-online-sdk-installer-linux:&amp;nbsp;error&amp;nbsp;while&amp;nbsp;loading&amp;nbsp;shared&amp;nbsp;libraries:&amp;nbsp;libgobject-2.0.so.0:&amp;nbsp;cannot&amp;nbsp;open&amp;nbsp;shared&amp;nbsp;object&amp;nbsp;file:&amp;nbsp;No&amp;nbsp;such&amp;nbsp;file&amp;nbsp;or&amp;nbsp;directory
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    我先尝试在&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;deibian&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;安装&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;linux&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;版本。结果安装文件启动时加载&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;libglobject.so&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;失败了！但是明明在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;/lib&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;目录下啊！解决不了，唔知点解！就只好在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;win7&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;下安装了&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;windows&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;版本。注意要勾选上装&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ant&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，如果你的系统里之前没有安装&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ant&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的话。装好&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ant&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;后还要把&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ant&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的路径添加入环境变量里。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    如何安装&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Android&amp;nbsp;SDK&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;开发包？&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    去官网下载了然后安装。简单地令人发指！！！哥不能讲怎么安装它，免得说我侮辱你的智慧。
  &lt;/p&gt;
  &lt;p&gt;
    &lt;a href=&#34;http://developer.android.com/sdk/index.html&#34;&gt;http://developer.android.com/sdk/index.html&lt;/a&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;strong&gt;开始开发&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    运行在安卓上的Qt&lt;span style=&#34;font-family: 宋体;&#34;&gt;程序被编译成共享对象&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(shared&amp;nbsp;objects)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。一个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Java&amp;nbsp;Launcher&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，已经集成在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;necessitas&amp;nbsp;sdk&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;里，会加载这个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;shared&amp;nbsp;objects&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。当然，对于应用开发者，这个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Java&amp;nbsp;Launcher&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;是完全透明的。要注意的是，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Qt&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;包含了很多互相引用的库，只有&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Android&amp;nbsp;V1.6&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;以上才支持这个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;functionality&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    哈。最最重要的。尝试第一个将被部署到&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;android&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;上的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Qt&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;应用。用安装好的&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Necessitas&amp;nbsp;Qt&amp;nbsp;Creator&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;创建了一个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;GUI&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;程序。运行。。。运行。报错了！！！哭啊。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;color: #800080;&#34;&gt;ma-make:&amp;nbsp;***&amp;nbsp;[install_target]&amp;nbsp;Error&amp;nbsp;2&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;color: #800080;&#34;&gt;The&amp;nbsp;process&amp;nbsp;&#34;D:\necessitas\QtCreator\bin\ma-make.exe&#34;&amp;nbsp;exited&amp;nbsp;with&amp;nbsp;code&amp;nbsp;2.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;color: #800080;&#34;&gt;Error&amp;nbsp;while&amp;nbsp;building&amp;nbsp;project&amp;nbsp;4android&amp;nbsp;(target:&amp;nbsp;Android)&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;color: #800080;&#34;&gt;When&amp;nbsp;executing&amp;nbsp;build&amp;nbsp;step&amp;nbsp;&#39;Copy&amp;nbsp;application&amp;nbsp;data&#39;&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    用&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&#34;&lt;/span&gt;When&amp;nbsp;executing&amp;nbsp;build&amp;nbsp;step&amp;nbsp;&#39;Copy&amp;nbsp;application&amp;nbsp;data&#39;&#34;google&lt;span style=&#34;font-family: 宋体;&#34;&gt;了一下。木有得到有价值的信息。不知道如何解决啊。哈&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;~~&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;那就不管了！！！&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    copyright ykyi.net
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>linux的soname，链接库的问题.</title>
      <link>https://ykyi.net/?p=269/</link>
      <pubDate>Thu, 08 Dec 2011 09:36:54 +0000</pubDate>
      <guid>https://ykyi.net/?p=269/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;第一次看到soname是读&amp;lt;程序员的自我修养.第一册:链接库&amp;gt;看来的。顺便说一下，这本书确实是本好书吖，国内出的难得技术好书。后来在公司的项目中把它从windows平台下移植到linux下，写makefile时用到过。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;再后来又忘记了。今天再次看到soname的时候就有点记不起来了。又只好搜索了一些资料看。趁热打铁把学会的东西记下来。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;linux为尝试解决动态链接库版本冲突的问题(windows平台下称之为DLL HELL)，引入了soname进制。linux的动态链接库的扩展名约定为.so 即shared object的缩写。下面的makefile语句来自于哥今年上半年写的makefile文件:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;span style=&#34;color: rgb(0, 0, 255); &#34;&gt;VERSION_NUM := 1.0.0&lt;/span&gt;&lt;br /&gt; soname = lib$(dirname).so.$(firstword $(subst ., ,$(VERSION_NUM)))&lt;br /&gt; LINKFLAGS := -shared -Wl,-soname,$(soname) -L. -lpthread -lrt -lpentagon -lcross_platform&lt;br /&gt; 其中的变量$(soname)会被替换为eibcomm.so.1。再看看LINKFLAGS变量指定的几个选项. -shared 表示要生成一个shared object，即动态共享库. -pthread -lrt -lpentagon -lcross_platform 是要链接其它几个库，thread和linux的posix线程库,rt是一个和实时系统相关的库它提供了高精度的时间函数。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;比较奇怪的是 -Wl,-soname,$(soname) 它们之前用逗号分开，而不是用空格分开。实际上这几个东东会被gcc传给ld(linux下的链接器)作为链接器的参数。gcc规定的写法就是这样的。指定的soname会被链接器写入到最终生成的elf文件中(linux下的可执行文件格式)。要查看elf文件的段布局什么的，可以用readelf工具。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;最终生成的文件将命名为 libname.so.x.y.z 的形式。soname是libname.so.x的格式(也不尽然，这只是一个convetion,并非在语法或机制上强行要求)。接着把生成的so文件拷贝到/usr/lib 或者 /lib，这两个文件夹是系统用来放置动态链接库的地方。debian下没有把/usr/local/lib作为默认的动态链接库文件夹.可以通过改/etc/ld.so.conf 文件把更多的路径加入。再运行 ldconfig,更新cache中的库文件信息。为什么要用cache呢，有人就问了！因为library实在太多了咯，cache就被引用了。cache是个好东西啊！！！&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;这个时候依赖 libname.so.x 的文件就可以找到这个library并加载起来了。但是编译程序时还是找不到呢.编译程序时通常会写 -lname 这个时候会先找 libname.so 再找 libname.a 文件，结果找不到。link就会抱怨没有找到这个库文件。为了让编译通过，于是你就用 ln -sf libname.so libname.so.x.y.z (这个是realname,版本号部分可能只有x.y两个部分) 建一个软链接！搞定！&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>关于听陈光荣教授《混沌的故事》讲座的心得报告</title>
      <link>https://ykyi.net/?p=260/</link>
      <pubDate>Tue, 06 Dec 2011 14:15:29 +0000</pubDate>
      <guid>https://ykyi.net/?p=260/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
        在听你陈老师(陈光荣教授，见文章未尾的介绍)的报告之前没有听说过“混沌数学”的概念。阅读了网络上的一些资料以后，有了大致的认识。早在初中生的年代，有在数学科普杂志上看到过“模糊数学”的概念。我想，&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;#8220;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;混沌数学&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;#8220;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;应该就是&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;#8220;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;模糊数学&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;#8220;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;近乎罢。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    陈老师的讲座重点在浅显介绍&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;#8220;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;混沌数学&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;#8220;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，并没有涉及太多混沌理论的学术内容。报告从牛顿时期的三大定律讲起，当时的的科学界普高认为世界是一个确定的机械系统。到科学家彭家莱在研究天体运动的三体问题时提出了定性分析的研究方向，这是&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;#8220;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;混沌&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;#8220;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的启蒙思想。陈老师讲三维空间有四种状态：发散，收敛，周期振荡，第四种即“混沌”。数学家&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Stephen Smale&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;提出了“马蹄理论”又是“混沌数学”领域的一重要理论。我粗略地把“马蹄理论”理解成一个马蹄形状被压缩，拉伸，对折变换，不断重复这一过程，就变成了“&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;chaos&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;”。华人数学家李天岩发表了论文“&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Period Three Implies Chaos&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;”标志着“离散混沌数学理论的诞生”。这个理论被称为“李&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;约克理论”。它的核心部分是“区间中存在不可数个初始点，函数从这些点出发的迭代点序列既不是周期的，又不趋向于任何周期轨道。序列的这种特殊状态是混沌的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(chaotic)&lt;/span&gt;”。“混沌理论”这个概念在大陆由北京大学的朱照宣教授引入。
  &lt;/p&gt;
  &lt;p&gt;
    陈老师在讲混沌理论的历史发展的故事中穿插了小故事给听众解释混沌理论。陈老师举了一个足球场的例子。一个四周用铁丝网封闭的足球场，一群小孩子在足球场内踢足球。这个足球飞向什么位置是不可预测的。这就近似一个“混沌系统”。我自己的理解，在每一个时间点如果可以知道小孩踢球的位置和力量大小以及风速等等物理量，就可以预测出皮球的运动方向啊。唔，我想得岂不是跟拉普拉斯的理论一样了啊&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;#8212;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;机械决定论！！！要被自然辩证法老法鄙视的啊！为了不违反自然辩证法的原则。你要想修补我的想法。这应该是一个视角的问题。如果能得到各种影响物理量的精确值固然可以测出皮球的运动方向，但对于一个非常复杂的系统，要得到所以物理量的精确值是不可能的，于是“混沌”就同来了。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;#8220;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;混沌&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&amp;#8220;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，真是好高深的理论啊！！！&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    陈老师在结束部分讲了“混沌理论”在天体物理学中的应用。&lt;a href=&#34;http://www.princeton.edu/main/news/&#34;&gt;Princeton&lt;/a&gt; University &lt;span style=&#34;font-family: 宋体;&#34;&gt;的 &lt;/span&gt;Peter Goldreich 认为认为太阳系行星的共振是混沌的；混沌决定了太阳系行星的形成，导致地球上的某些“生物种类灭绝” 甚至某些天体的“物质消亡” ，让天体的“牛顿时钟” 最终趋于混沌。幻灯片播放的太阳系&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(Solar System)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的图片相当地漂亮啊。最新的混沌理论认为太阳系起始于混沌状态，在两亿年内又将进入混沌。由微小的扰动会引发巨大无比的突变，行星的轨道最终都趋向于混沌。天体物理学是相当的难懂，看着这些美丽神秘的宇宙深处的图片，我觉得我所具备的物理知识不足以理解宇宙中的神秘星体。从哲学的大尺度高度，任务事情都是出生，发展，高潮，最终走向毁灭。大规模有序的运动里会在局部，某些子过程中蕴含无序的过程。看似无序的过程也必有运动的规律。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Actually&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，我不能理解，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Chaotic Solar System&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;是个什么样的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;system&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-family: 宋体;&#34;&gt;&lt;a href=&#34;http://ykyi.net/&#34;&gt;http://ykyi.net&lt;/a&gt; zausiu&amp;#8217;s blog&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    提问阶段，有人问到了计算机的问题，陈老师总结为计算机不可能产生理论上真正随机的数据。这跟我的知识是一致的，计算机只能产生伪随机数。与是又想到之前看&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Linux&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;内核的书，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Linux&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;内核里有一个什么什么池的东东，这个东东用来搜集所有随机发生的事件&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;如电流噪声，键盘中断等等用它来贡献随机数。咦，这不就能产生真正随机的数字了吗？马上又想到，这是一个看问题的尺度的问题。把时间尺度放小到内核能收集到的两次随机事件之间，这个间隔内产生的随机数依然是通过公式计算到的可预测的数字。果然还是伪随机数。又想到之间的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;PPT&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;中有讲陈老师用电路可以产生真正的“混沌信号”。那么把这路电路引入到计算机体系中，不就可以产生真正的随机数了吗？唔！那就不对了呀。那只可能是：“混沌”和“随机”并不是完全相等的概念。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    讲座结束后。我跟同学讨论了未来“生物计算机”的猜想。应用哲学思想的否定之否定规律。信号从过去的“模拟信号”发展到现在占统治地位的“离散信号”，必定在以后又会发展到更高层次的“模拟信号”，近似生物电神经系统的通讯发式，将完全超越现在的二进制的冯诺依曼体系的计算机。生物电的模拟信号能携带更丰富的信息，并且能够描述真正“混沌”的“模糊”状态。而现在的二进制计算机只能用精确的离散数字近似描述模糊的东西。这样的计算机有什么现实意义呢！至少就能产生真正的随机数了。肯定有意义非凡的现实意义啊。科学学术是先不负责现实意义的，那是工程师们的任务。
  &lt;/p&gt;
  &lt;p&gt;
    /////////////////
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;讲座题目：混沌的故事&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;演讲人：陈关荣教授，香港城市大学&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;演讲时间：&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;12&lt;/span&gt;月&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;5&lt;/span&gt;日上午&lt;span style=&#34;font-family: Times New Roman;&#34;&gt; 10:00-11:30&lt;/span&gt;&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;演讲地点：中山大学东校区信息学院楼&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;  207&lt;/span&gt;室&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;演讲摘要：许多人都听说过，南美洲的一只蝴蝶轻轻地扇动一下翅膀可能会在美国德克萨斯州引发一场龙卷风。这一通俗解释作为“混沌”的代名词经历了人们认识和建立科学意义上的混沌理论的漫长历程，理解到“蝴蝶效应”是混沌的一个基本特征。本讲座以故事的形式向理工科师生介绍混沌的基本概念和混沌理论的发展历史。报告力求通俗生动而不失严谨清晰。内容并不要求听众具有混沌知识，因而也欢迎其他有兴趣的非理工科师生参加。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;演讲人简介&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;陈关荣教授&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;1981&lt;/span&gt;年获中山大学计算数学硕士学位，是中大校友。他于&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;1987&lt;/span&gt;年获美国&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Texas A&amp;M &lt;/span&gt;大学应用数学博士学位，其后在莱斯大学和休斯顿大学任教。自&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;2000&lt;/span&gt;年起，他接受香港城市大学讲座教授职位工作至今，在该校成立了“混沌与复杂网络”学术研究中心并担任中心主任。他长期从事非线性科学研究，自&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;1981&lt;/span&gt;年以来，发表了多篇&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SCI&lt;/span&gt;杂志论文和出版了多部研究专著，他引次数达一万六千多次，&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SCI h&lt;/span&gt;指数为&lt;span style=&#34;font-family: Times New Roman;&#34;&gt; 62&lt;/span&gt;，被&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ISI&lt;/span&gt;评定为工程学高引用率研究人员。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-family: Times New Roman; font-size: small;&#34;&gt; &lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;span style=&#34;font-size: small;&#34;&gt;陈关荣教授现任&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;IEEE&lt;/span&gt;《电路与系统》杂志（&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;IEEE Circuits and Systems Magazine&lt;/span&gt;）主编和国际《分岔与混沌》杂志（&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;International Journal of Bifurcation and Chaos&lt;/span&gt;）主编，曾经担任过许多国际学术会议主席和组织者、曾任&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;IEEE&lt;/span&gt;电路与系统学会非线性电路与系统技术委员会主席。他是&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;IEEE Fellow&lt;/span&gt;（自&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;1996&lt;/span&gt;年），曾获&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;4 &lt;/span&gt;次&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SCI&lt;/span&gt;最佳杂志论文奖，&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;2008&lt;/span&gt;年获国家自然科学二等奖（第一完成人），&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;2010&lt;/span&gt;年获何梁何利科学与技术进步奖，&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;2011&lt;/span&gt;年获俄罗斯圣彼得堡国立大学授予荣誉博士学位和俄罗斯欧拉基金会颁发欧拉金质奖章。他是中山大学等国内外多所大学的荣誉或客座教授，并曾多次应邀到过&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;30&lt;/span&gt;多个国家讲学。&lt;/span&gt;
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>sicily 1022 Poor contestant Prob 解题报告。</title>
      <link>https://ykyi.net/?p=256/</link>
      <pubDate>Mon, 05 Dec 2011 13:27:27 +0000</pubDate>
      <guid>https://ykyi.net/?p=256/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;div&gt;
    &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;解 &amp;nbsp;题 &amp;nbsp;报 &amp;nbsp;告
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    1 1022 Poor contestant Prob原题中文大意;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    对于大约十万条数据：如果共奇数条数据则找到最中间那条记录。如果有偶数条记录则忽略。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    2 算法思想及解题用到的主要数据结构;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    因为数据的规模比较大。如果给十万条记录排序的话显然会超时。考虑到题目只需要找到最中间那条。易想到把数据平分成两部分，第一部分的数据全部大于第二部分的数据。创建两个堆结构。第一部分的较大数据建大小顶堆，第二部分的较小数据建成大顶堆。在插入数据的过程中，动态维护这两个堆，使小顶堆的元素数等于大顶堆的元素数或者小顶堆的元素比大顶堆的元素多一。本题用性线表来存储堆。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    3 详细解题思路;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    因为最终需要输出一个字符串。为了节省拷贝字符串的开销，把字符串存到一个字符串池中，而每个堆中的元素只维护这个字符串池的索引号。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    初始时，小顶堆和大顶堆的大小都是0。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    1. 当输入第一条数据时，把这条数据放入小顶堆中。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    2. 当输入更多数据时：
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    2.1 如果小顶堆和大顶堆的元素个数一样多。为保证添加新数据后，我们需要的最中间的数据在小顶堆的上部。又分两种情况处理：
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    2.1.1 如果待加入数据大于或等于大顶堆的堆顶元素。则把这个待加入数据加入小顶堆。调整小顶堆.
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    2.1.2 如果待加入数据小于大顶堆的堆顶元素.则把大顶堆的堆顶元素弹出添加到小顶堆，调整这两个堆。之后，把待加入数据加入大顶堆。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    2.2 如果小顶堆和大顶堆的元素个数不一样多。因为前面的约定，那么必定是小顶堆的元素个数比大顶堆的元素个数多一个。仍然分两种情况：
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    2.2.1 如果待加入数据大于小顶堆的堆顶元素。则把待加入数据加入小顶堆并调整，调整后把小顶堆的堆顶弹出加入大顶堆并调整。小顶堆在弹出堆顶元素后再调整一次。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    2.2.1 如果待加入数据不大于小顶堆的堆顶元素。则把该数据加入大顶堆，调整大顶堆。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    输入结束时直接取小顶堆的堆顶元素即要求的解。根据元素中的字符串索引可以拿到需要打印的字符串，本题中即那位poor contestant。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    4 逐步求精算法描述（含过程及变量说明）;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;pre class=&#34;brush:cpp&#34;&gt;int g_name_pool_index = 0;   // 名字池的当前索引号.
&lt;p&gt;char g_name_pool[100001][11];  // 用来存名字的字符串池.&lt;/p&gt;
&lt;p&gt;下面是堆相关的描述。&lt;/p&gt;
&lt;p&gt;struct heap_elem_t&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;// string _name;&lt;/p&gt;
&lt;p&gt;int _name_index;  // 名字的索引&lt;/p&gt;
&lt;p&gt;int _solved_count;  // 原题意中表示解决了多少个问题.用这个数量比较堆元素的大小。&lt;/p&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;// STL 用的堆算法的比较算子.&lt;/p&gt;
&lt;p&gt;struct heap_elem_less_comparator&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;bool operator()(const heap_elem_t&amp;amp; left,  const heap_elem_t&amp;amp; right)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;return left._solved_count &amp;lt; right._solved_count;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;// STL 用的堆算法的比较算子.&lt;/p&gt;
&lt;p&gt;struct heap_elem_larger_comparator&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;bool operator()(const heap_elem_t&amp;amp; left,  const heap_elem_t&amp;amp; right)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;return left._solved_count &amp;gt; right._solved_count;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;heap_elem_less_comparator less_comp;&lt;/p&gt;
&lt;p&gt;heap_elem_larger_comparator larger_comp;&lt;/p&gt;
&lt;p&gt;// 从下往而上调整堆。用到了STL的堆调整算法。堆元素存在线性表中，但不用第一个元素。因为之前的版本用自己写的堆调整算法为了计算坐标方便就不用第一个元素。&lt;/p&gt;
&lt;p&gt;inline void adjust_heap_up(heap_elem_t heap[], int tail_pos, bool inc)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;if ( inc )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;push_heap(heap+1, heap+tail_pos+1, larger_comp);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;else&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;push_heap(heap+1, heap+tail_pos+1, less_comp);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// 把堆顶元素弹出.并调整余下的元素仍然是一个堆。也用了STL的算法.&lt;/p&gt;
&lt;p&gt;inline void popup_the_top(heap_elem_t heap[], int tail_pos, bool inc)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;if ( inc )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;pop_heap(heap+1, heap+tail_pos+1, larger_comp);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;else&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;pop_heap(heap+1, heap+tail_pos+1, less_comp);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// 下面是自已写的堆调整算法。有从上而下的调整，也有从下而上的调整。&lt;/p&gt;
&lt;p&gt;/** 调整堆.从下往下调整.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;@param heap 堆的首地址.用顺序表存放堆.但不用下标为0的元素.这个元素可用来作临时存储.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;@param summit_pos 堆顶的位置.summit_pos &amp;gt; 0&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;@param tail_pos 最后一个元素的位置.tail_pos &amp;gt; 0&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;@param inc 是否建小顶堆.如果false则大顶堆.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;*/&lt;/p&gt;
&lt;p&gt;void adjust_heap_top2bottom(heap_elem_t heap[], int summit_pos, int tail_pos, bool inc)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;int i;&lt;/p&gt;
&lt;p&gt;heap[0] = heap[summit_pos];  // 存下堆顶的元素先.&lt;/p&gt;
&lt;p&gt;for ( i = 2 * summit_pos; i &amp;lt;= tail_pos; i *= 2 )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;if ( inc )  // 调整小顶堆&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;if ( i &amp;lt; tail_pos &amp;amp;&amp;amp; heap[i]._solved_count &amp;gt; heap[i+1]._solved_count )&lt;/p&gt;
&lt;p&gt;i++;&lt;/p&gt;
&lt;p&gt;if ( ! (heap[0]._solved_count &amp;gt; heap[i]._solved_count) )&lt;/p&gt;
&lt;p&gt;break;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;else  // 调整大顶堆&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;if ( i &amp;lt; tail_pos &amp;amp;&amp;amp; heap[i]._solved_count &amp;lt; heap[i+1]._solved_count )&lt;/p&gt;
&lt;p&gt;i++;&lt;/p&gt;
&lt;p&gt;if ( ! (heap[0]._solved_count &amp;lt; heap[i]._solved_count) )&lt;/p&gt;
&lt;p&gt;break;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;heap[summit_pos] = heap[i];&lt;/p&gt;
&lt;p&gt;summit_pos = i;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;heap[summit_pos] = heap[0];&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;/** 调整堆.从下往上调整.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;@param heap 堆的首地址.用顺序表存放堆.但不用下标为0的元素.这个元素可用来作临时存储.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;@param tail_pos 最后一个元素的位置.tail_pos &amp;gt; 0&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;@param inc 是否建小顶堆.如果false则大顶堆.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;*/&lt;/p&gt;
&lt;p&gt;void adjust_heap_bottom2top(heap_elem_t heap[], int tail_pos, bool inc)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;int i;&lt;/p&gt;
&lt;p&gt;heap[0] = heap[tail_pos];&lt;/p&gt;
&lt;p&gt;for ( i = tail_pos; i &amp;gt; 1; i /= 2 )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;int parent_pos = i / 2;&lt;/p&gt;
&lt;p&gt;if ( inc )  // 调整小顶堆&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;if ( heap[parent_pos]._solved_count &amp;gt; heap[0]._solved_count )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;heap[i] = heap[parent_pos];&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;else&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;break;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;else  // 调整大顶堆&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;if ( heap[parent_pos]._solved_count &amp;lt; heap[0]._solved_count )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;heap[i] = heap[parent_pos];&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;else&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;break;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;heap[i] = heap[0];&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;5 程序注释清单（重要过程的说明）;&lt;/p&gt;
&lt;p&gt;// poor_guy.cpp : Defines the entry point for the console application.
//&lt;/p&gt;
&lt;p&gt;#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;&lt;/p&gt;
&lt;p&gt;using namespace std;&lt;/p&gt;
&lt;p&gt;template&amp;lt;typename T&amp;gt; class my_vector
{
public:
my_vector(T* addr)
{
m_ary = addr;
m_ava_idx = 0;
}
~my_vector()
{
//  delete []m_ary;
}&lt;/p&gt;
&lt;p&gt;T&amp;amp; operator[](int index)
{
return m_ary[index];
}&lt;/p&gt;
&lt;p&gt;void push_back(const T&amp;amp; v)
{
m_ary[m_ava_idx++] = v;
}&lt;/p&gt;
&lt;p&gt;void resize(int size)
{
m_ava_idx = size;
}&lt;/p&gt;
&lt;p&gt;void shrink(int dec)
{
m_ava_idx -= dec;
}&lt;/p&gt;
&lt;p&gt;int size()
{
return m_ava_idx;
}
private:
T*   m_ary;
int  m_ava_idx;
};&lt;/p&gt;
&lt;p&gt;// 堆的结点定义
int g_name_pool_index = 0;
char g_name_pool[100001][11];&lt;/p&gt;
&lt;p&gt;struct heap_elem_t
{
// string _name;
int _name_index;
int _solved_count;
};&lt;/p&gt;
&lt;p&gt;heap_elem_t g_heap_elems0[50002];
heap_elem_t g_heap_elems1[50002];&lt;/p&gt;
&lt;p&gt;struct heap_elem_less_comparator
{
bool operator()(const heap_elem_t&amp;amp; left,  const heap_elem_t&amp;amp; right)
{
return left._solved_count &amp;lt; right._solved_count;
}
};&lt;/p&gt;
&lt;p&gt;struct heap_elem_larger_comparator
{
bool operator()(const heap_elem_t&amp;amp; left,  const heap_elem_t&amp;amp; right)
{
return left._solved_count &amp;gt; right._solved_count;
}
};&lt;/p&gt;
&lt;p&gt;heap_elem_less_comparator less_comp;
heap_elem_larger_comparator larger_comp;&lt;/p&gt;
&lt;p&gt;/&lt;em&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;strong&gt;&lt;em&gt;/
/&lt;/em&gt; inc 为真时调整为小顶堆，为false时调整为大顶堆。                      &lt;em&gt;/
/&lt;/em&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;/
inline void adjust_heap_up(heap_elem_t heap[], int tail_pos, bool inc)
{
if ( inc )
{
push_heap(heap+1, heap+tail_pos+1, larger_comp);
}
else
{
push_heap(heap+1, heap+tail_pos+1, less_comp);
}
}&lt;/p&gt;
&lt;p&gt;inline void popup_the_top(heap_elem_t heap[], int tail_pos, bool inc)
{
if ( inc )
{
pop_heap(heap+1, heap+tail_pos+1, larger_comp);
}
else
{
pop_heap(heap+1, heap+tail_pos+1, less_comp);
}
}&lt;/p&gt;
&lt;p&gt;int main(int argc, char* argv[])
{
const int BUFF_LEN = 64;
char buff[BUFF_LEN];
int case_count;  // 记有多少个case;
int contestant_count;
my_vector&amp;lt;heap_elem_t&amp;gt; littletop_heap(g_heap_elems0);
my_vector&amp;lt;heap_elem_t&amp;gt; bigtop_heap(g_heap_elems1);
heap_elem_t contestant;
string name;
// vector&amp;lt;string&amp;gt; output_vec;&lt;/p&gt;
&lt;p&gt;scanf(&amp;quot;%d&amp;quot;, &amp;amp;case_count);
for ( int i = 0; i &amp;lt; case_count; i++ )
{
littletop_heap.resize(1);  // 为了方便计算.下标0的位置不存堆的元素.
bigtop_heap.resize(1);
g_name_pool_index = 0;
contestant_count = 0;&lt;/p&gt;
&lt;p&gt;while(true)
{
scanf(&amp;quot;%s&amp;quot;, buff);&lt;/p&gt;
&lt;p&gt;int little_heap_count = littletop_heap.size() - 1;
int big_heap_count = bigtop_heap.size() - 1;&lt;/p&gt;
&lt;p&gt;if ( buff[0] == &#39;Q&#39; )  // 查询. Querry
{
if ( little_heap_count == big_heap_count || 0 == contestant_count )
{
printf(&amp;ldquo;No one!\n&amp;rdquo;);
//output_vec.push_back(&amp;ldquo;No one!\n&amp;rdquo;);
}
else
{
printf(&amp;quot;%s\n&amp;quot;, g_name_pool[littletop_heap[1]._name_index]);
//output_vec.push_back(g_name_pool[littletop_heap[1]._name_index]);
//output_vec.push_back(&amp;quot;\n&amp;quot;);
}
}
else if ( buff[0] == &#39;E&#39; )  // 结束.
{
if ( little_heap_count == big_heap_count || 0 == contestant_count )
{
printf(&amp;ldquo;Happy BG meeting!!\n&amp;rdquo;);
//output_vec.push_back(&amp;ldquo;Happy BG meeting!!\n&amp;rdquo;);
}
else
{
printf(&amp;quot;%s%s&amp;quot;,g_name_pool[littletop_heap[1]._name_index], &amp;quot; is so poor.\n&amp;quot;);
//output_vec.push_back(g_name_pool[littletop_heap[1]._name_index]);
//output_vec.push_back(&amp;quot; is so poor.\n&amp;quot;);
}&lt;/p&gt;
&lt;p&gt;break;
}
else if( buff[0] == &#39;A&#39; )// 加入参赛者数据.
{
contestant_count ++;&lt;/p&gt;
&lt;p&gt;scanf(&amp;quot;%s&amp;quot;, g_name_pool[g_name_pool_index]);
contestant._name_index = g_name_pool_index;
g_name_pool_index++;
scanf(&amp;quot;%d&amp;quot;, &amp;amp;contestant._solved_count);&lt;/p&gt;
&lt;p&gt;if ( 1 == contestant_count )  // 第一个参赛者数据.
{
littletop_heap.push_back(contestant);
}
else if ( little_heap_count == big_heap_count )  // 两个堆的元素相等.
{
// 新元素大于大顶堆的堆顶元素，所以插入小顶堆.
if ( contestant._solved_count &amp;gt;= bigtop_heap[1]._solved_count )
{
littletop_heap.push_back(contestant);
adjust_heap_up(&amp;amp;littletop_heap[0], littletop_heap.size()-1, true);
}
else
{
heap_elem_t top = bigtop_heap[1];
popup_the_top(&amp;amp;bigtop_heap[0], bigtop_heap.size()-1, false);
bigtop_heap.shrink(1);&lt;/p&gt;
&lt;p&gt;bigtop_heap.push_back(contestant);
adjust_heap_up(&amp;amp;bigtop_heap[0], bigtop_heap.size()-1, false);&lt;/p&gt;
&lt;p&gt;littletop_heap.push_back(top);
adjust_heap_up(&amp;amp;littletop_heap[0], littletop_heap.size()-1, true);
}
}
else  // 不等.只可能是小顶堆比大顶堆多1.
{
if ( contestant._solved_count &amp;gt; littletop_heap[1]._solved_count )
{
littletop_heap.push_back(contestant);
adjust_heap_up(&amp;amp;littletop_heap[0], littletop_heap.size()-1, true);&lt;/p&gt;
&lt;p&gt;heap_elem_t top = littletop_heap[1];
popup_the_top(&amp;amp;littletop_heap[0], littletop_heap.size()-1, true);
littletop_heap.shrink(1);&lt;/p&gt;
&lt;p&gt;bigtop_heap.push_back(top);
adjust_heap_up(&amp;amp;bigtop_heap[0], bigtop_heap.size()-1, false);
}
else
{
bigtop_heap.push_back(contestant);
adjust_heap_up(&amp;amp;bigtop_heap[0], bigtop_heap.size()-1, false);
}
}
}
}&lt;/p&gt;
&lt;p&gt;if ( i + 1 &amp;lt; case_count )
{
printf(&amp;quot;\n&amp;quot;);
//output_vec.push_back(&amp;quot;\n&amp;quot;);
}
}&lt;/p&gt;
&lt;p&gt;//for ( int i = 0; i &amp;lt; output_vec.size(); i++ )
//{
// cout &amp;lt;&amp;lt; output_vec[i];
//}&lt;/p&gt;
&lt;p&gt;return 0;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  //////// 上面的代码在中山大学ACM网站 www.soj.me 上通过.目前的成绩是第14名.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Rank &amp;nbsp;14 &amp;nbsp; &amp;nbsp;2011-12-07 10:00:19 &amp;nbsp; &amp;nbsp;0.18 sec &amp;nbsp; &amp;nbsp;2160 KB &amp;nbsp; &amp;nbsp;6971 Bytes &amp;nbsp; &amp;nbsp; C++ &amp;nbsp; zausiu
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  注意上面的代码绝不能用C++的标准IO cin cout 做输入输出.如果用C++的IO流会造成超时。我为了调这个超时问题调了整整一天！死活想不到是因为C++ IO的问题.童鞋，一定要用 scanf 和 printf 啊。面对十万级的IO，尤其是在做ACM题，cin cout 是魔鬼。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  原因是：
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  More should be noted about I/O operations in C++. Due to their complex underlying implementation &amp;nbsp;models, cin and cout are comparatively slower than scanf and printf. The difference in performance is shown by many experiences to be more significant if the program is compiled by G++. Therefore if a problem has huge input, using cin and cout will possibly lead to Time Limit Exceed.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  6 测试数据;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  用一个简单的BASH脚本来创建测试用例。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &lt;pre class=&#34;brush:other&#34;&gt;#! /bin/bash
&lt;p&gt;INDEX=1&lt;/p&gt;
&lt;p&gt;SHRESHOLD=100000   // 建十万条数据.&lt;/p&gt;
&lt;p&gt;while [ $INDEX -lt $SHRESHOLD ]&lt;/p&gt;
&lt;p&gt;do&lt;/p&gt;
&lt;p&gt;echo &amp;ldquo;ADD name$INDEX $RANDOM&amp;rdquo;&lt;/p&gt;
&lt;p&gt;let &amp;ldquo;INDEX=$INDEX+1&amp;rdquo;&lt;/p&gt;
&lt;p&gt;done&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  7 对时间复杂度，空间复杂度方面的分析.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  时间复杂度是O(log n), 空间复杂度是 O(n).
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  附原题：
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  1022. Poor contestant Prob
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Description
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  As everybody known, &amp;ldquo;BG meeting&amp;rdquo; is very very popular in the ACM training team of ZSU.
&lt;/div&gt;
&lt;div&gt;
  After each online contest, they will go out for &amp;ldquo;smoking&amp;rdquo;. Who will be the poor ones that have to BG the others? Of course, the half who solve less problems.
&lt;/div&gt;
&lt;div&gt;
  The rule runs well when the number of the contestants is even. But if the number is odd, it is impossible to divide them into two equal parts. It gives a dilemma to the BG meeting committee. After a careful discussion with Mr. Guo, a new rule emerged: if the number of the contestant is odd, the committee will first sort the contestants according to the number of problems they solved, and then they will pick out the middle one. This poor boy or girl will have no chance to attend the BG meeting.
&lt;/div&gt;
&lt;div&gt;
  Strange rule, isn`t it?
&lt;/div&gt;
&lt;div&gt;
  As the number of the contestants is becoming more and more large, the committee need to write a program which will pick out the poor one efficiently.
&lt;/div&gt;
&lt;div&gt;
  Note that: Every contestant solves different number of problems. The total number of the contestants will not exceed 10^5.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Input
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  There are several cases in the input. The first line of the input will be an integer M, the number of the cases.
&lt;/div&gt;
&lt;div&gt;
  Each case is consisted of a list of commands. There are 3 types of commands.
&lt;/div&gt;
&lt;div&gt;
  1. Add xxx n : add a record to the data base, where xxx is the name of the contestant, which is only consisted of at most 10 letters or digits, n is the number of problems he/she solved. (Each name will appear in Add commands only once).
&lt;/div&gt;
&lt;div&gt;
  2.Query :
&lt;/div&gt;
&lt;div&gt;
  3.End :End of the case.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Output
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  1.For the Query command: If the current number of contestants is odd, the program should output the poor contestant&amp;rsquo;s name currently even if there is only one contestants, otherwise, just out put &amp;ldquo;No one!&amp;rdquo; (without quotes).
&lt;/div&gt;
&lt;div&gt;
  2.For the End command:
&lt;/div&gt;
&lt;div&gt;
  If the total number of contestants in the data base is even, you should out put &amp;ldquo;Happy BG meeting!!&amp;rdquo;(without quotes),otherwise, you should out put the &amp;ldquo;xxx is so poor. &amp;rdquo;(without quotes) where xxx is the name of the poor one.
&lt;/div&gt;
&lt;div&gt;
  3.Each case should be separated by a blank line.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Sample Input
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  2
&lt;/div&gt;
&lt;div&gt;
  Add Magicpig 100
&lt;/div&gt;
&lt;div&gt;
  Add Radium 600
&lt;/div&gt;
&lt;div&gt;
  Add Kingfkong 300
&lt;/div&gt;
&lt;div&gt;
  Add Dynamic 700
&lt;/div&gt;
&lt;div&gt;
  Query
&lt;/div&gt;
&lt;div&gt;
  Add Axing 400
&lt;/div&gt;
&lt;div&gt;
  Query
&lt;/div&gt;
&lt;div&gt;
  Add Inkfish 1000
&lt;/div&gt;
&lt;div&gt;
  Add Carp 800
&lt;/div&gt;
&lt;div&gt;
  End
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Add Radium 100
&lt;/div&gt;
&lt;div&gt;
  Add Magicpig 200
&lt;/div&gt;
&lt;div&gt;
  End
&lt;/div&gt;
&lt;div&gt;
  Sample Output
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  No one!
&lt;/div&gt;
&lt;div&gt;
  Axing
&lt;/div&gt;
&lt;div&gt;
  Radium is so poor.
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Happy BG meeting!!
&lt;/div&gt;
&lt;div&gt;
  Problem Source
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  ZSUACM Team Member
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>熬夜完成 sicily1153 马周游解题报告。困死哥了.</title>
      <link>https://ykyi.net/?p=252/</link>
      <pubDate>Tue, 29 Nov 2011 18:11:20 +0000</pubDate>
      <guid>https://ykyi.net/?p=252/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    &lt;span style=&#34;line-height: 1.6em;&#34;&gt;唉！！！ 上次交作业写错题目了，做了简单的马周游 sicily 1152。补上新的,应该是sicily 1153.为了解决规模太大的问题。加上了优化算法。&lt;/span&gt;
  &lt;/p&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    中大ACM实验题。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    （1）原题中文大意
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    中国象棋的马按照象棋的规则在8 x 8 的棋盘上跑64步跑完所有的格子。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    （2）算法思想及解题用到的主要数据结构
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    从每一个点往下走第二步，会有几点有效的行走位置。 把当前位置记在栈里面，以深度优先的方式进入下一个有效位置。如果下一个有效位置在之前已经走过，则从栈顶弹出上一位置，恢复到调出的位置后尝试未走过的有效位置。利用函数调用时会压栈的特别，用函数递归调用即可解决问题。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    软之简单的马周游，8 x 8 棋盘的规模非常大。需要在可选下一步中找到最接近正确路线的点。求该点的办法是把所以的可选点先找出，再给这些可选点按权重排序，从最优的解依次向次优，次次优&amp;#8230;..的点试探。重点在权重的算法。这里的权重的计算法则是指一个点的下一次可走的点的个数。
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    主要的数据结构有：
  &lt;/div&gt;
  &lt;div&gt;
    &amp;nbsp;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;pre class=&#34;brush:cpp&#34;&gt;// elocution数组在初始化后会记下每个有效位置的下一步有哪些可走位
&lt;p&gt;// 置.elocution[x][0]用下标0记个数。最多8个有效可走位置。&lt;/p&gt;
&lt;p&gt;char elocution[ELEM_COUNT][9];&lt;/p&gt;
&lt;p&gt;// stamps数组记每个点是否已经走过了。0表示没走过，1表示走过了。&lt;/p&gt;
&lt;p&gt;char stamps[ELEM_COUNT];&lt;/p&gt;
&lt;p&gt;// track数组记路径的顺序。&lt;/p&gt;
&lt;p&gt;char track[ELEM_COUNT];&lt;/p&gt;
&lt;p&gt;通过结合stamps数组和elocution数组可以算出下一步的每个点的权重。&lt;/p&gt;
&lt;p&gt;（3）详细解题思路&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;先初始化一张表。这张表记下了棋盘上所有的30个位置的下一步可走的有效位置.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;写一个一般的递归调用自己的函数，表示马在走第几步时到了哪个位置，然后求出余下的所有可走位置。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;余下的所有位置按照上文提到的权重排序。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对于排序后的可选点数组，按顺序依次用递归函数尝试。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;递归函数有三个退出条件。1.下一个要尝试的点已经走过了，2.试完了所有的可选下一步无解。3.走到了最后一步，即得解！&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;（4）算法描述&lt;/p&gt;
&lt;p&gt;初如化上文提到的elocution数组，清空stamps和tracks.从起点开始调用递归函数。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;  zausiu&#39;s blog.&lt;/p&gt;
&lt;p&gt;（5）程序注释清单&lt;/p&gt;
&lt;p&gt;#include &amp;lt;iostream&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;cstring&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;cstdlib&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;vector&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;csetjmp&amp;gt;&lt;/p&gt;
&lt;p&gt;//#include &amp;lt;cassert&amp;gt;&lt;/p&gt;
&lt;p&gt;using namespace std;&lt;/p&gt;
&lt;p&gt;#define  ROW_NUM     8&lt;/p&gt;
&lt;p&gt;#define  COLUMN_NUM  8&lt;/p&gt;
&lt;p&gt;#define  ELEM_COUNT ROW_NUM * COLUMN_NUM&lt;/p&gt;
&lt;p&gt;jmp_buf jmpbuffer;  // 很深的函数递归调用时用longjmp快速退出.&lt;/p&gt;
&lt;p&gt;// elocution数组在初始化后会记下每个有效位置的下一步有哪些可走位&lt;/p&gt;
&lt;p&gt;// 置.elocution[x][0]用下标0记个数。最多8个有效可走位置。&lt;/p&gt;
&lt;p&gt;char elocution[ELEM_COUNT][9];&lt;/p&gt;
&lt;p&gt;// stamps数组记每个点是否已经走过了。0表示没走过，1表示走过了。&lt;/p&gt;
&lt;p&gt;char stamps[ELEM_COUNT];&lt;/p&gt;
&lt;p&gt;struct coordinate  // 二维坐标&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;char _x;  // start from zero.&lt;/p&gt;
&lt;p&gt;char _y;&lt;/p&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;// 作标转序号&lt;/p&gt;
&lt;p&gt;char coordinate2serial_num(coordinate co)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;char num = co._x * COLUMN_NUM + co._y + 1;&lt;/p&gt;
&lt;p&gt;return num;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// 序号转坐标&lt;/p&gt;
&lt;p&gt;coordinate serial_num2coordinate(char sn)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;coordinate co;&lt;/p&gt;
&lt;p&gt;co._x = (sn - 1) / COLUMN_NUM;&lt;/p&gt;
&lt;p&gt;co._y = sn - co._x * COLUMN_NUM - 1;&lt;/p&gt;
&lt;p&gt;return co;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// ((x:1;y:-2),(x:2;y:-1),(x:2;y:1),(x:1;y:2) (x:-1;y:2),(x:-2;y:1),(x:-2;y:-1),(x:-1;y:-2));&lt;/p&gt;
&lt;p&gt;char increments[8][2] =&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;1, -2, 2, -1, 2, 1, 1, 2,&lt;/p&gt;
&lt;p&gt;-1, 2, -2, 1, -2, -1, -1, -2&lt;/p&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;void next_step(char pos, char steps[])  // 把位置在pos序号的点的每一个下一个可选位置记在数组中。&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;char valid_count = 0;&lt;/p&gt;
&lt;p&gt;coordinate co = serial_num2coordinate(pos);&lt;/p&gt;
&lt;p&gt;coordinate tmp;&lt;/p&gt;
&lt;p&gt;char serial_num;&lt;/p&gt;
&lt;p&gt;for ( int i = 0; i &amp;lt; 8; i++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;tmp._x = co._x + increments[i][0];&lt;/p&gt;
&lt;p&gt;tmp._y = co._y + increments[i][1];&lt;/p&gt;
&lt;p&gt;if ( tmp._x &amp;lt; 0 || tmp._x &amp;gt;= ROW_NUM || tmp._y &amp;lt; 0 || tmp._y &amp;gt;= COLUMN_NUM )  // 保证位置有效&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;continue;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;serial_num = coordinate2serial_num(tmp);&lt;/p&gt;
&lt;p&gt;if ( serial_num &amp;gt;= 1 &amp;amp;&amp;amp; serial_num &amp;lt;= ELEM_COUNT )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;valid_count++;&lt;/p&gt;
&lt;p&gt;steps[valid_count] = serial_num;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;else&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;cerr &amp;lt;&amp;lt; &amp;ldquo;Not expected to reach here.\n&amp;rdquo;;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;steps[0] = valid_count;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// 下面的逻辑以每个点的下一步可跳点的数目作为权重排序。&lt;/p&gt;
&lt;p&gt;struct pos_weight&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;char _pos;&lt;/p&gt;
&lt;p&gt;char _weight;&lt;/p&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;// 又是用递归。这里为了实现快速排序&lt;/p&gt;
&lt;p&gt;int partition(pos_weight poses[], int low, int high)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;pos_weight pivot = poses[low];&lt;/p&gt;
&lt;p&gt;while (low &amp;lt; high)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;while (low &amp;lt; high &amp;amp;&amp;amp; pivot._weight &amp;lt; poses[high]._weight)&lt;/p&gt;
&lt;p&gt;high&amp;ndash;;&lt;/p&gt;
&lt;p&gt;poses[low] = poses[high];&lt;/p&gt;
&lt;p&gt;while (low &amp;lt; high &amp;amp;&amp;amp; pivot._weight &amp;gt;= poses[low]._weight)&lt;/p&gt;
&lt;p&gt;low++;&lt;/p&gt;
&lt;p&gt;poses[high] = poses[low];&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;poses[low] = pivot;&lt;/p&gt;
&lt;p&gt;return low;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// 快速排序。&lt;/p&gt;
&lt;p&gt;void quick_sort_steps(pos_weight poses[], int low, int high)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;if ( low &amp;lt; high )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;int pivot_loc = partition(poses, low, high);&lt;/p&gt;
&lt;p&gt;quick_sort_steps(poses, low, pivot_loc-1);&lt;/p&gt;
&lt;p&gt;quick_sort_steps(poses, pivot_loc+1, high);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;void rearrage_steps(char poses[], int len) // poese里放置了下一个位置数组。Len是数组长度。&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;char weight, pos, next_step_count;&lt;/p&gt;
&lt;p&gt;vector&amp;lt;pos_weight&amp;gt; vec(len);&lt;/p&gt;
&lt;p&gt;for ( int i = 0; i &amp;lt; len; i++ ) // 计算权重.&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;weight = 0;&lt;/p&gt;
&lt;p&gt;pos = poses[i];&lt;/p&gt;
&lt;p&gt;next_step_count = elocution[pos-1][0];&lt;/p&gt;
&lt;p&gt;for ( int j = 0; j &amp;lt; next_step_count; j++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;char next_step_pos = elocution[pos-1][j+1];&lt;/p&gt;
&lt;p&gt;if ( 0 == stamps[next_step_pos-1] )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;weight++;  // 如果有一下一跳点没走过则权重加1.&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;vec[i]._pos = pos;&lt;/p&gt;
&lt;p&gt;vec[i]._weight = weight;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;quick_sort_steps(&amp;amp;vec[0], 0, len-1);  // 根据权重排序.&lt;/p&gt;
&lt;p&gt;for ( int i = 0; i &amp;lt; len; i++ ) // 把排序后的位置写回原始数组.&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;poses[i] = vec[i]._pos;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;void init_elocution()&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;memset(stamps, 0, sizeof(stamps));&lt;/p&gt;
&lt;p&gt;for ( int i = 1; i &amp;lt;= ELEM_COUNT; i++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;next_step(i, elocution[i-1]);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;char track[ELEM_COUNT];&lt;/p&gt;
&lt;p&gt;void run_horse(char start_pos, char step_count) // step_count [0 &amp;ndash; 64)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;// 如果已经经过这点就立即退出函数。&lt;/p&gt;
&lt;p&gt;if ( 1 == stamps[start_pos-1] )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;return;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;track[step_count] = start_pos;&lt;/p&gt;
&lt;p&gt;if ( step_count == COLUMN_NUM * ROW_NUM - 1 )  // 是不是最后一步。&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;for ( int i = 0; i &amp;lt; sizeof(track); i++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;cout &amp;lt;&amp;lt; (int)track[i];&lt;/p&gt;
&lt;p&gt;if ( i + 1 != sizeof(track) )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;cout &amp;lt;&amp;lt; &amp;quot; &amp;ldquo;;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;cout &amp;lt;&amp;lt; endl;&lt;/p&gt;
&lt;p&gt;longjmp(jmpbuffer, 0x1);&lt;/p&gt;
&lt;p&gt;return;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// 记下已经走了这一步。&lt;/p&gt;
&lt;p&gt;stamps[start_pos-1] = 1;   rearrage_steps(elocution[start_pos-1]+1, elocution[start_pos-1][0]);&lt;/p&gt;
&lt;p&gt;for ( int i = 0; i &amp;lt; elocution[start_pos-1][0]; i++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;run_horse(elocution[start_pos-1][i+1], step_count+1);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;stamps[start_pos-1] = 0;  // 试完了所有可走步.退出这个函数.重置这个位置为没有走过。&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;int main(int argc, char* argv[])&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;int pos;&lt;/p&gt;
&lt;p&gt;vector&amp;lt;int&amp;gt; vec;&lt;/p&gt;
&lt;p&gt;while(true)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;cin &amp;gt;&amp;gt; pos;&lt;/p&gt;
&lt;p&gt;if (pos==-1)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;break;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;vec.push_back(pos);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;for ( int i = 0; i &amp;lt; vec.size(); i++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;if(setjmp(jmpbuffer) == 0)  // 为了很深的递归函数快速回退到这里。&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;init_elocution();&lt;/p&gt;
&lt;p&gt;memset(track, 0, sizeof(track));&lt;/p&gt;
&lt;p&gt;memset(stamps, 0, sizeof(stamps));&lt;/p&gt;
&lt;p&gt;run_horse(vec[i], 0);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;return 0;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
  （6）该算法的时间复杂度是 O(8 ^ (m * n)) &amp;nbsp; m,n分别为棋盘的长和宽。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  /////////////////// 原题目如下:
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  1153. 马的周游问题
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Description
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  和题目C同样的任务，这里只是把棋盘扩大到标准的国际象棋。对这样一个8 * 8的棋盘用同样的方法编号如下：
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  1 &amp;nbsp; &amp;nbsp; 2 &amp;nbsp; &amp;nbsp; 3 &amp;nbsp; &amp;nbsp; &amp;nbsp; 4 &amp;nbsp; &amp;nbsp; 5 &amp;nbsp; &amp;nbsp; 6 &amp;nbsp; &amp;nbsp; &amp;nbsp; 7 &amp;nbsp; &amp;nbsp; 8
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  9 &amp;nbsp; &amp;nbsp; 10 &amp;nbsp; &amp;nbsp; &amp;nbsp; 11 &amp;nbsp; &amp;nbsp;12 &amp;nbsp; &amp;nbsp; &amp;nbsp; 13 &amp;nbsp; &amp;nbsp;14 &amp;nbsp; &amp;nbsp; &amp;nbsp; 15 &amp;nbsp; &amp;nbsp;16
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  17 &amp;nbsp; &amp;nbsp;18 &amp;nbsp; &amp;nbsp; &amp;nbsp; 19 &amp;nbsp; &amp;nbsp;20 &amp;nbsp; &amp;nbsp; &amp;nbsp; 21 &amp;nbsp; &amp;nbsp;22 &amp;nbsp; &amp;nbsp; &amp;nbsp; 23 &amp;nbsp; &amp;nbsp;24
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  25 &amp;nbsp; &amp;nbsp;26 &amp;nbsp; &amp;nbsp; &amp;nbsp; 27 &amp;nbsp; &amp;nbsp;28 &amp;nbsp; &amp;nbsp; &amp;nbsp; 29 &amp;nbsp; &amp;nbsp;30 &amp;nbsp; &amp;nbsp; &amp;nbsp; 31 &amp;nbsp; &amp;nbsp;32
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  33 &amp;nbsp; &amp;nbsp;34 &amp;nbsp; &amp;nbsp; &amp;nbsp; 35 &amp;nbsp; &amp;nbsp;36 &amp;nbsp; &amp;nbsp; &amp;nbsp; 37 &amp;nbsp; &amp;nbsp;38 &amp;nbsp; &amp;nbsp; &amp;nbsp; 39 &amp;nbsp; &amp;nbsp;40
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  41 &amp;nbsp; &amp;nbsp;42 &amp;nbsp; &amp;nbsp; &amp;nbsp; 43 &amp;nbsp; &amp;nbsp;44 &amp;nbsp; &amp;nbsp; &amp;nbsp; 45 &amp;nbsp; &amp;nbsp;46 &amp;nbsp; &amp;nbsp; &amp;nbsp; 47 &amp;nbsp; &amp;nbsp;48
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  49 &amp;nbsp; &amp;nbsp;50 &amp;nbsp; &amp;nbsp; &amp;nbsp; 51 &amp;nbsp; &amp;nbsp;52 &amp;nbsp; &amp;nbsp; &amp;nbsp; 53 &amp;nbsp; &amp;nbsp;54 &amp;nbsp; &amp;nbsp; &amp;nbsp; 55 &amp;nbsp; &amp;nbsp;56
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  57 &amp;nbsp; &amp;nbsp;58 &amp;nbsp; &amp;nbsp; &amp;nbsp; 59 &amp;nbsp; &amp;nbsp;60 &amp;nbsp; &amp;nbsp; &amp;nbsp; 61 &amp;nbsp; &amp;nbsp;62 &amp;nbsp; &amp;nbsp; &amp;nbsp; 63 &amp;nbsp; &amp;nbsp;64
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Input
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  输入有若干行。每行一个整数N(1&lt;=N&lt;=64)，表示马的起点。最后一行用-1表示结束，不用处理。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Output
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  对输入的每一个起点，求一条周游线路。对应地输出一行，有64个整数，从起点开始按顺序给出马每次经过的棋盘方格的编号。相邻的数字用一个空格分开。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  Sample Input
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  4
&lt;/div&gt;
&lt;div&gt;
  -1
&lt;/div&gt;
&lt;div&gt;
  Sample Output
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  注意：如果起点和输入给定的不同，重复多次经过同一方格或者有的方格没有被经过，都会被认为是错误的。
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
  &amp;nbsp;
&lt;/div&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>又是数组越界造成的bug.</title>
      <link>https://ykyi.net/?p=246/</link>
      <pubDate>Tue, 29 Nov 2011 15:19:10 +0000</pubDate>
      <guid>https://ykyi.net/?p=246/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    又一次遇到数组越界造成的奇怪的，难以调试的，诡异的&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;bug.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    前几天做&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ACM&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;题。&amp;lsquo;简单的马周游&amp;rsquo;。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    见&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;:&amp;nbsp;&lt;/span&gt;&lt;a href=&#34;../2011/11/acm-%E9%A9%AC%E5%91%A8%E6%B8%B8%E8%A7%A3%E9%A2%98%E6%8A%A5%E5%91%8A/&#34;&gt;http://ykyi.net/2011/11/acm-%E9%A9%AC%E5%91%A8%E6%B8%B8%E8%A7%A3%E9%A2%98%E6%8A%A5%E5%91%8A/&lt;/a&gt;
  &lt;/p&gt;
  &lt;p&gt;
    因为我的解法用了函数递归调用，函数求到最终解的栈的调用层次非常深。第一版用置一个全局变量的方式让这么深调用的函数快速依次退出。但我也知道还有另外一种解法就是用&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;C&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;语言的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;setjmp&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;longjmp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。用这两个函数可以快速退栈。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    今天晚上就想用&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;setjmp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;longjmp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;改写一下。本来以为是非常简单的事情。结果改完以的程序只能正确求解第一个请求，然后程序看起来就像是死了。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Debug&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;时发现程序似乎跑飞了。哎&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;脑子不灵光，发现程序跑飞竟然没有立即想到是数组越界把堆栈写坏了&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。因为我改动的代码非常少，只是用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;setjmp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;longjmp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;快速退出递归取代之前的稍微比较慢的做法。而其它的代码改动的非常之少。于是我当时分析错误的出发点就是比较两份代码的异同。比较来比较去，就只有退出方式不同而已。相当相当地困惑。费了很多时间都没有找到原因。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    实在搞不定了。冲了个热水澡，又回来看代码。还是没有发现这个改动在哪里引入了错误。不断反复地看代码，突然灵光一现看到写一个全局数组的语句，下标变量越界！越界！越界！！！啊&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;~~&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;惊喜！于是把数组下标的相关的代码纠正了，于是&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;setjmp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;版本的代码也运行正常啊。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    这次的经验是。操作数组的时候一定要一定要一定要非常非常非常之小心&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;~~&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;在调试程序发现程序跑飞的情况下马上要意识到是写坏了堆栈。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    另外还有一个疑问是第一版的代码也有写坏栈的问题为什么就一切正常呢。这就是&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;C/C++&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;程序数组危险的地方啊&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;~~&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;第一版本的代码退栈的方式和第二版不一样，于是这个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;bug&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就在第一版隐藏了起来。于是第二版出问题时我的思路集中在比较代码差异是如何引入问题的。&lt;strong&gt;而这个&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;bug&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;并不是新代码引入的，而是在旧代码隐藏起来的，第二代的新代码让触发了这个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;bug&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;&lt;/strong&gt;
  &lt;/p&gt;
  &lt;p&gt;
    总结下经验：
  &lt;/p&gt;
  &lt;p&gt;
    一定要一定要非常小心&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;C/C++&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的数组越界问题啊！！！操作很多数组时，有很多下标要计算时。千万要注意是从0还是从1开始计算下标。要根据约定多下诊断！！！及时发现隐藏的错误。越界写数组的bug有时发生，可能在引入的当时被隐藏，隐藏的很深很深。但越界读数组的bug隐藏得更深更深更深啊。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    copyright ykyi.net
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>中大ACM题.商人的宣传解题报告.</title>
      <link>https://ykyi.net/?p=243/</link>
      <pubDate>Sat, 26 Nov 2011 10:35:30 +0000</pubDate>
      <guid>https://ykyi.net/?p=243/</guid>
      <description>&lt;h1 id=&#34;description&#34;&gt;Description&lt;/h1&gt;
&lt;p&gt;Bruce是K国的商人，他在A州成立了自己的公司，这次他的公司生产出了一批性能很好的产品，准备宣传活动开始后的第L天到达B州进行新品拍卖，期间Bruce打算将产品拿到各个州去做推销宣传,以增加其影响力。&lt;/p&gt;
&lt;p&gt;K国有很多个州,每个州都与其他一些州相邻,但是K国对商人作宣传却有一些很奇怪的规定：&lt;br&gt;
1、 商人只能从某些州到达另外一些州，即连通路线是单向的，而且有些州可能是到达不了的。&lt;br&gt;
2、 商人不允许在同一个州连续宣传两天或以上，每天宣传完必须离开该州。&lt;br&gt;
3、 商人可以多次来到同一个州进行宣传。&lt;/p&gt;
&lt;p&gt;&amp;ldquo;我必须找出一条影响力最大的路线才行&amp;rdquo;，Bruce想，&amp;ldquo;但我首先必须知道到底有多少这种符合规定的宣传路线可供我选择。&amp;ldquo;现在Bruce把任务交给了你。并且出于考虑以后的需要，你还要帮他算出给出的两州之间的路线的总数。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h1 id=&#34;input&#34;&gt;Input&lt;/h1&gt;
&lt;p&gt;输入文件第一行包含三个整数n,m,L（1≤n,L≤100），分别表示K国的州数、连通路线的数量，以及多少天后必须到达B州。接下来有m行，每行一队整数x,y（1≤x,y≤n），表示商人能从x州到达y州。&lt;br&gt;
第m+2行为一个整数q（1≤q≤100），表示Bruce有q个询问。下面q行每行两个整数A,B（1≤A,B≤n），即A、B州的位置。&lt;/p&gt;
&lt;h1 id=&#34;output&#34;&gt;Output&lt;/h1&gt;
&lt;p&gt;输出文件包含q行，每行一个整数t，为所求的从A州到B州满足上述规定的路线总数。&lt;br&gt;
输入数据中的询问将保证答案t在长整数范围内，即t&amp;lt;2&lt;sup&gt;31&lt;/sup&gt;。&lt;/p&gt;
&lt;h1 id=&#34;sample-input&#34;&gt;Sample Input&lt;/h1&gt;
&lt;pre&gt;4 5 6
1 2
2 3
3 4
4 1
2 4
2
1 4
4 2&lt;/pre&gt;
&lt;h1 id=&#34;sample-output&#34;&gt;Sample Output&lt;/h1&gt;
&lt;pre&gt;2 1&lt;/pre&gt;
&lt;div&gt;
  &lt;p&gt;
    1.&amp;nbsp;原题中文大意.
  &lt;/p&gt;
  &lt;p&gt;
    商人的宣传即是一个有向图的问题。有一个有向图。该图的每条件权重一样，从图中任意一点a&lt;span style=&#34;font-family: 宋体;&#34;&gt;刚好通过&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;L&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;步到达另一点&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;有多少条路线。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    2.&amp;nbsp;算法思想及解题思路.
  &lt;/p&gt;
  &lt;p&gt;
    使用了动态规划算法。令&amp;nbsp;dp[num][dest]&amp;nbsp;&lt;span style=&#34;font-family: 宋体;&#34;&gt;表示从起点通过&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;num&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;条边到达终点共有多少种走法。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    先由已经知条件易得从起点通过一条它的邻接边到达它的所有邻接点共有一条路线。即&amp;nbsp;dp[1][&lt;span style=&#34;font-family: 宋体;&#34;&gt;邻接点&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;]&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;易求得。而&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;dp[x][y]&amp;nbsp;=&amp;nbsp;sum(&amp;nbsp;dp[x-1][&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;可以一条邻接边到达&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;y&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的点&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;]&amp;nbsp;)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    3.&amp;nbsp;主要数数据结构&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    主要数据结构为三个数组。这本个数组都不用下标为&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的元素。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    char&amp;nbsp;odgree[MAX_VERTICES_NUM+1];
  &lt;/p&gt;
  &lt;p&gt;
    下标为每个顶点的编号&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;表示每个顶点的出度&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;.&amp;nbsp;&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    int&amp;nbsp;routine[MAX_VERTICES_NUM+1][MAX_VERTICES_NUM+1];
  &lt;/p&gt;
  &lt;p&gt;
    &amp;lsquo;路由表&amp;rsquo;&amp;nbsp;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;routine[x][n]&amp;nbsp;=&amp;nbsp;y&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;表示从顶点&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;x&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;经它的第&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;n&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;条邻接边可以到达顶点&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;y.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    int&amp;nbsp;dp[MAX_VERTICES_NUM+1][MAX_VERTICES_NUM+1];
  &lt;/p&gt;
  &lt;p&gt;
    这个数组即第二节提到的&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;dp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;数组，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;dp[L][x]&amp;nbsp;=&amp;nbsp;num&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;从起点开始经&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;L&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;条边走到顶点&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;x&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;共有&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;num&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;种走法。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    4.&amp;nbsp;逐步求精算法描述（含过程及变量说明）&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;;&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    从已知条件初始化&amp;nbsp;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;odgree&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;routine&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;数组&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;.&lt;/span&gt;
  &lt;/p&gt;
  &lt;pre class=&#34;brush:cpp&#34;&gt;bzero(odgree, sizeof(odegree));

for(int x,y, i = 0; i &amp;lt; m; i++)

{

scanf(&#34;%d %d&#34;, &amp;x, &amp;y);

odgree[x]++;

routine[x][ odgree[x] ] = y;

}



下面的cal函数输入起点顶点和终点顶点，返回共有多少种走法。

int cal(char start, char dest)

{

memset(dp, 0, sizeof(dp));



for ( int i = 1; i &amp;lt;= odgree[start]; i++ )  // 遍历起点的每一条邻接边

{

dp[1][ routine[start][i] ]++;  //  初始时经过一邻接边到达别一点的走法有几种.



}



for ( int i = 2; i &amp;lt;= L; i++ )   // 一直走到第L步.

{

for ( int j = 1; j &amp;lt;= n; j++ )  // 遍历每一个顶点.

{

for ( int k = 1; k &amp;lt;= odgree[j]; k++ )  // 该顶点的第一条邻接边

{

// 上文提到的递推公式。

dp[i][ routine[j][k] ] += dp[i-1][j];

}

}

}



return dp[L][dest];  // 返回结果

}&lt;/pre&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
  5.&amp;nbsp;程序注释清单
&lt;/p&gt;
&lt;pre class=&#34;brush:cpp&#34;&gt;#include &amp;lt;cstdio&amp;gt;

#include &amp;lt;cstdlib&amp;gt;

#include &amp;lt;memory&amp;gt;

#include &amp;lt;cstring&amp;gt;

#include &amp;lt;vector&amp;gt;



using namespace std;



const int MAX_VERTICES_NUM = 100;  // 最多多少个顶点.

int n, m, L, q;  // 实际n个点、m条边，L 为期限.q为有多少个询问.

static char odgree[MAX_VERTICES_NUM+1];  // 记每个点的出度.不用下标为0的元素.

static int routine[MAX_VERTICES_NUM+1][MAX_VERTICES_NUM+1];  // table[x][y] 表示x点经它的第y条边可以去到哪个点.

static int dp[MAX_VERTICES_NUM+1][MAX_VERTICES_NUM+1];  // dp[x][y] 表示经x条边，可以从某点到 y 点.



int cal(char start, char dest)

{

memset(dp, 0, sizeof(dp));



for ( int i = 1; i &amp;lt;= odgree[start]; i++ )  // 遍历起点的每一条邻接边.

{

dp[1][ routine[start][i] ]++;  // 初始时经过一步到达别一点的走法.

}



for ( int i = 2; i &amp;lt;= L; i++ )   // 一直走到第 L 步.

{

for ( int j = 1; j &amp;lt;= n; j++ )  // 遍历每一个点.

{

for ( int k = 1; k &amp;lt;= odgree[j]; k++ )  // 该点的每一个邻接点.

{

dp[i][ routine[j][k] ] += dp[i-1][j];

}

}

}



return dp[L][dest];

}



int main(int argc, char* argv[])

{

while ( EOF != scanf(&#34;%d %d %d&#34;, &amp;n, &amp;m, &amp;L) )

{

memset(odgree, 0, sizeof(odgree));

for(int x,y, i = 0; i &amp;lt; m; i++)

{

scanf(&#34;%d %d&#34;, &amp;x, &amp;y);

odgree[x]++;

routine[x][ odgree[x] ] = y;

}



scanf(&#34;%d&#34;, &amp;q);

vector&amp;lt;int&amp;gt; results;

for ( int start,dest, i = 0; i &amp;lt; q; i++)

{

scanf(&#34;%d %d&#34;, &amp;start, &amp;dest);

results.push_back(cal(start, dest));

}

for ( int i = 0; i &amp;lt; results.size(); i++ )

{

printf(&#34;%d\n&#34;, results[i]);

}



}

return 0;

}
&lt;/pre&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
  6.&amp;nbsp;测试数据
&lt;/p&gt;
&lt;p&gt;
  4&amp;nbsp;5&amp;nbsp;6
&lt;/p&gt;
&lt;p&gt;
  1&amp;nbsp;2
&lt;/p&gt;
&lt;p&gt;
  2&amp;nbsp;3
&lt;/p&gt;
&lt;p&gt;
  3&amp;nbsp;4
&lt;/p&gt;
&lt;p&gt;
  4&amp;nbsp;1
&lt;/p&gt;
&lt;p&gt;
  2&amp;nbsp;4
&lt;/p&gt;
&lt;p&gt;
  5
&lt;/p&gt;
&lt;p&gt;
  1&amp;nbsp;4
&lt;/p&gt;
&lt;p&gt;
  4&amp;nbsp;2
&lt;/p&gt;
&lt;p&gt;
  2&amp;nbsp;1
&lt;/p&gt;
&lt;p&gt;
  1&amp;nbsp;3
&lt;/p&gt;
&lt;p&gt;
  3&amp;nbsp;4
&lt;/p&gt;
&lt;p&gt;
  2
&lt;/p&gt;
&lt;p&gt;
  1
&lt;/p&gt;
&lt;p&gt;
  2
&lt;/p&gt;
&lt;p&gt;
  1
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
  7.&amp;nbsp;对时间复杂度，空间复杂度方面的分析、估算及程序优化的分析和改进&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
  本解决方法的时间复杂度为O(L*n*n)&lt;span style=&#34;font-family: 宋体;&#34;&gt;，空间复杂度为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;O(n*n).&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
  用动态规划解此题的时间复杂度优于用邻接矩阵表示图然后用图的乘法解出。后者的时间复杂志为&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;O(L*n*n*n)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>initramfs 和 initrd 的区别</title>
      <link>https://ykyi.net/?p=236/</link>
      <pubDate>Fri, 25 Nov 2011 05:21:49 +0000</pubDate>
      <guid>https://ykyi.net/?p=236/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;Linux 2.6内核引入了一个新的feature叫做initramfs。与initrd相比,initramfs有几个好处。&lt;br /&gt; initrd模拟一个磁盘(这就是它的名字的由来，initramdisk或initrd)。模拟磁盘也就同时引入了Linux的块IO子系统的开销，比如缓存(caching)，而initramfs从根本上把cache也装载(mounted)成filesystem(因此叫做initramfs).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;Initramfs建立在page cahce之上，和page cache一样，会动态地自动增长和缩减尺寸来减入内存的使用量，而initrd做不到这点。&lt;br /&gt; 另外，不像initrd需要文件系统驱动(filesystem driver)的支持，比如EXT2 driver，如果你的initrd使用ext2。而initramfs则不需要文件系统的支持，initramfs的实现代码很简单，只是基于page cache的简单一层。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux的开机启动顺序</title>
      <link>https://ykyi.net/?p=228/</link>
      <pubDate>Fri, 25 Nov 2011 05:01:39 +0000</pubDate>
      <guid>https://ykyi.net/?p=228/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;对于x86机器的Linux的启动顺序，BIOS首先从启动设备载入MBR(Master Boot Record).存在MBR里的代码就去找分区表，从活动分区读入Linux的bootloader，最常用的像Grub,其它的有LILO,SYSLINUX。&lt;br /&gt; Bootloader把压缩格式的内核映象载入并把控制权交给内核映像。&lt;br /&gt; 内核映像自解压，启动内核！&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;x86处理器有两种工作模式。实模式和保护模式。在实模式，你只能够寻址1M内存。保护模式下，就复杂得多，可以作到使用处理器的很多高级特性比如分页。CPU必须从实模式转到保护模式是一个单行通道(one-way street)。你不能从保护模式退入实模式。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;内核第一阶段的内核初始化是在实模式中完成的。接下来从init/main.c 中定义的 start_kernel()函数进入你保护模式。start_kernel()先初始化CPU subsystem。接下来启动存储器和进程管理。然后启动外围总线和IO设备。启动序列的最后一个阶段便是init进程被启动。这个进程是所有的Linux进程的祖先。Init进程执行用户空间的脚本。这些脚本被用来启动必要的内核服务程序。Init最后spawn一个控制台给你。于是启动就完成了。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>ACM 马周游解题报告</title>
      <link>https://ykyi.net/?p=223/</link>
      <pubDate>Fri, 25 Nov 2011 04:33:50 +0000</pubDate>
      <guid>https://ykyi.net/?p=223/</guid>
      <description>&lt;div&gt;
  &lt;center&gt;
    &lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;&amp;lt;p&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/p&amp;gt;

&amp;lt;h3 style=&amp;quot;text-align: left; &amp;quot;&amp;gt;
  &amp;lt;span style=&amp;quot;font-size: 14px; &amp;quot;&amp;gt;简单的马周游问题&amp;lt;/span&amp;gt;
&amp;lt;/h3&amp;gt;

&amp;lt;p&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
  &amp;amp;nbsp;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
  &amp;lt;/center&amp;gt; &amp;lt;/div&amp;gt; 
  
  &amp;lt;p&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/p&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;Description&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;在一个5 * 6的棋盘中的某个位置有一只马，如果它走29步正好经过除起点外的其他位置各一次，这样一种走法则称马的周游路线，试设计一个算法，从给定的起点出发，找出它的一条周游路线。&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;为了便于表示一个棋盘，我们按照从上到下，从左到右对棋盘的方格编号，如下所示：&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;1 &amp;amp;nbsp; &amp;amp;nbsp; 2 &amp;amp;nbsp; &amp;amp;nbsp; 3 &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; 4 &amp;amp;nbsp; &amp;amp;nbsp; 5 &amp;amp;nbsp; &amp;amp;nbsp; 6&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;7 &amp;amp;nbsp; &amp;amp;nbsp; 8 &amp;amp;nbsp; &amp;amp;nbsp; 9 &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; 10 &amp;amp;nbsp; &amp;amp;nbsp;11 &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; 12&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;13 &amp;amp;nbsp; &amp;amp;nbsp;14 &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; 15 &amp;amp;nbsp; &amp;amp;nbsp;16 &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; 17 &amp;amp;nbsp; &amp;amp;nbsp;18&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;19 &amp;amp;nbsp; &amp;amp;nbsp;20 &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; 21 &amp;amp;nbsp; &amp;amp;nbsp;22 &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; 23 &amp;amp;nbsp; &amp;amp;nbsp;24&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;25 &amp;amp;nbsp; &amp;amp;nbsp;26 &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; 27 &amp;amp;nbsp; &amp;amp;nbsp;28 &amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp; 29 &amp;amp;nbsp; &amp;amp;nbsp;30&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;马的走法是&amp;amp;ldquo;日&amp;amp;rdquo;字形路线，例如当马在位置15的时候，它可以到达2、4、7、11、19、23、26和28。但是规定马是不能跳出棋盘外的，例如从位置1只能到达9和14。&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;Input&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;输入有若干行。每行一个整数N(1&amp;lt;=N&amp;lt;=30)，表示马的起点。最后一行用-1表示结束，不用处理。&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;Output&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;对输入的每一个起点，求一条周游线路。对应地输出一行，有30个整数，从起点开始按顺序给出马每次经过的棋盘方格的编号。相邻的数字用一个空格分开。&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;Sample Input&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;4&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;-1&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;Sample Output&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;注意：如果起点和输入给定的不同，重复多次经过同一方格或者有的方格没有被经过，都会被认为是错误的。&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;（1）原题中文大意&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;中国象棋的马按照象棋的规则在5 x 6 的棋盘上跑30步跑完所有的格子。&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;（2）算法思想及解题用到的主要数据结构&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;从每一个点往下走第二步，会有几点有效的行走位置。 把当前位置记在栈里面，以深度优先的方式进入下一个有效位置。如果下一个有效位置在之前已经走过，则从栈顶弹出上一位置，恢复到调出的位置后尝试未走过的有效位置。利用函数调用时会压栈的特别，用函数递归调用即可解决问题。&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;（3）详细解题思路&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;1. 先初始化一张表。这张表记下了棋盘上所有的30个位置的下一步可走的有效位置.&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;2. 写一个一般的递归调用自己的函数，表示马在走第几步时到了哪个位置，然后尝试走余下的所有可走位置。&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;3. 递归函数有两个退出条件。要么下一个要尝试的点已经走过了，要么走到了最后一步，即得解！&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;（4）逐步求精算法描述&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;用一个数组记下来经过的点。&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;span style=&amp;quot;font-size:14px;&amp;quot;&amp;gt;（5）程序注释清单&amp;lt;/span&amp;gt;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;amp;nbsp;
  &amp;lt;/div&amp;gt;
  
  &amp;lt;div&amp;gt;
    &amp;lt;pre class=&amp;quot;brush:cpp&amp;quot;&amp;gt;#include &amp;amp;lt;iostream&amp;amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#include &amp;lt;cstring&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;cstdlib&amp;gt;&lt;/p&gt;
&lt;p&gt;#include &amp;lt;vector&amp;gt;&lt;/p&gt;
&lt;p&gt;using namespace std;&lt;/p&gt;
&lt;p&gt;const static char row_num = 5;   // 5行&lt;/p&gt;
&lt;p&gt;const static char column_num = 6;  // 6列&lt;/p&gt;
&lt;p&gt;// 这个全局数组在初始化后会记下每30个有效位置的下一步可走位置.&lt;/p&gt;
&lt;p&gt;// elocution[x][0]记个数。最多8个有效可走位置。&lt;/p&gt;
&lt;p&gt;char elocution[30][9];&lt;/p&gt;
&lt;p&gt;struct coordinate  // 坐标.&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;char _x;  // start from zero.&lt;/p&gt;
&lt;p&gt;char _y;&lt;/p&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;// 坐标转序号的函数。&lt;/p&gt;
&lt;p&gt;char coordinate2serial_num(coordinate co)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;char num = co._x * column_num + co._y + 1;&lt;/p&gt;
&lt;p&gt;return num;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// 序号转坐标的函数。&lt;/p&gt;
&lt;p&gt;coordinate serial_num2coordinate(char sn)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;coordinate co;&lt;/p&gt;
&lt;p&gt;co._x = (sn - 1) / column_num;&lt;/p&gt;
&lt;p&gt;co._y = sn - co._x * column_num - 1;&lt;/p&gt;
&lt;p&gt;return co;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// 增量数组.&lt;/p&gt;
&lt;p&gt;char increments[8][2] =&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;1, -2, 2, -1, 2, 1, 1, 2,&lt;/p&gt;
&lt;p&gt;-1, 2, -2, 1, -2, -1, -1, -2&lt;/p&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;// 得用增量数组来计算每一个位置的下一步有效位置。记到steps里面.&lt;/p&gt;
&lt;p&gt;void next_step(char pos, char steps[])&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;char valid_count = 0;&lt;/p&gt;
&lt;p&gt;coordinate co = serial_num2coordinate(pos);&lt;/p&gt;
&lt;p&gt;coordinate tmp;&lt;/p&gt;
&lt;p&gt;char serial_num;&lt;/p&gt;
&lt;p&gt;for ( int i = 0; i &amp;lt; 8; i++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;tmp._x = co._x + increments[i][0];&lt;/p&gt;
&lt;p&gt;tmp._y = co._y + increments[i][1];&lt;/p&gt;
&lt;p&gt;if ( tmp._x &amp;lt; 0 || tmp._x &amp;gt; 4 || tmp._y &amp;lt; 0 || tmp._y &amp;gt; 5 )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;continue;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;serial_num = coordinate2serial_num(tmp);&lt;/p&gt;
&lt;p&gt;if ( serial_num &amp;gt;= 1 &amp;amp;&amp;amp; serial_num &amp;lt;= 30 )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;valid_count++;&lt;/p&gt;
&lt;p&gt;steps[valid_count] = serial_num;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;else&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;cerr &amp;lt;&amp;lt; &amp;ldquo;Not expected to reach here.\n&amp;rdquo;;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;steps[0] = valid_count;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// 初始化记载所有点的下一步可走点的全局表。&lt;/p&gt;
&lt;p&gt;void init_elocution()&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;for ( int i = 1; i &amp;lt;= 30; i++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;next_step(i, elocution[i-1]);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;char track[30];   // 记走过的路径.&lt;/p&gt;
&lt;p&gt;bool quit_run_horse;&lt;/p&gt;
&lt;p&gt;// 上文提高的递归函用函数.&lt;/p&gt;
&lt;p&gt;void run_horse(char start_pos, char step_count)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;if ( quit_run_horse ) // 用来快速退出深嵌套递归调用函数.&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;return;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;for ( int i = 0; i &amp;lt; step_count; i++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;// 已?经-经-过y这a点?了?.&lt;/p&gt;
&lt;p&gt;if ( track[i] == start_pos )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;return;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;track[step_count] = start_pos; // 记下新走过的位置&lt;/p&gt;
&lt;p&gt;if ( step_count == 29 )  // 最后一步则打印出结果。&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;for ( int i = 0; i &amp;lt; sizeof(track); i++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;cout &amp;lt;&amp;lt; (int)track[i];&lt;/p&gt;
&lt;p&gt;if ( i + 1 != sizeof(track) )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;cout &amp;lt;&amp;lt; &amp;quot; &amp;ldquo;;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;cout &amp;lt;&amp;lt; endl;&lt;/p&gt;
&lt;p&gt;quit_run_horse = true;&lt;/p&gt;
&lt;p&gt;return;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;for ( int i = 0; i &amp;lt; elocution[start_pos-1][0]; i++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;run_horse(elocution[start_pos-1][i+1], step_count+1);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;int main(int argc, char* argv[])&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;init_elocution();&lt;/p&gt;
&lt;p&gt;int pos;&lt;/p&gt;
&lt;p&gt;vector&amp;lt;int&amp;gt; vec;&lt;/p&gt;
&lt;p&gt;while(true)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;cin &amp;gt;&amp;gt; pos;&lt;/p&gt;
&lt;p&gt;if (pos==-1)&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;break;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;vec.push_back(pos);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;for ( int i = 0; i &amp;lt; vec.size(); i++ )&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;quit_run_horse = false;&lt;/p&gt;
&lt;p&gt;run_horse(vec[i], 0);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;return 0;&lt;/p&gt;
&lt;p&gt;}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>TIME is SO LIMITED</title>
      <link>https://ykyi.net/?p=219/</link>
      <pubDate>Mon, 14 Nov 2011 16:05:00 +0000</pubDate>
      <guid>https://ykyi.net/?p=219/</guid>
      <description>&lt;p&gt;TIME is SO LIMITED&lt;/p&gt;
&lt;p&gt;I never imaged my graduate shcool life would be so busy. I ever though I would have enough time to read as many books in which I was interesting as I can. Actually there are a whopping pile of courses and homework to take. I seldom have enough time to read the books I’m planning to read. Time is so limitted, how I wish the lord would give me double the time, 24 hours a day. I would feel nervous and guilty when I was doing something which I deemed as a waste of time. I want to finish reading some books before the beginning of the following term. In order to achieve this goal I must manage my time much more efficient. As an example, time schedule every day should be more tight to reduce time fragment which are harder to use and much easiser to be wasted inadvertently.&lt;br&gt;
God, give me more time ! I’m so busy.&lt;/p&gt;</description>
    </item>
    <item>
      <title>EMC易安信2011中山大学校园宣讲</title>
      <link>https://ykyi.net/?p=217/</link>
      <pubDate>Thu, 13 Oct 2011 15:10:40 +0000</pubDate>
      <guid>https://ykyi.net/?p=217/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    今天听了EMC易安信的招聘宣讲会。EMC是这颗星球上最领先的海量存储设备供应商哇！~不久前并购了vmware。年收益近200亿美，大概比电信巨头华为少五六十亿美金。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    可能宣传不力而且EMC的产品基本上面向企业级，不像其它巨头企业一样有吸引力，到场的人稀稀拉拉就二十几个。EMC高管就来了四个哇，而由大BOSS带队！！！中大的童鞋们太不给面子了~~
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    先是由EMC的老大讲了点公司的情况。这货94年tsinghua毕业，加州理工博士。哎哎哎哎。。哎哎哎~~~~
  &lt;/p&gt;
  &lt;p&gt;
    然后由EMC的一个技术总监做presentation。相当明显的一儒雅型帅哥啊~~人才！人才啊!!! 同自己一比较&amp;#8230;~~羡慕嫉妒恨！！！如果我这么优秀就好了。差太远了。上图.
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;img decoding=&#34;async&#34; src=&#34;http://b85.photo.store.qq.com/psb?/40ba6ef3-29ce-43f1-a784-3cf8d04442de/Wh6Aeqj3aXJCqfFL7d6sFAc6WQif45430vNF3v011tA!/b/YeyptDLQEAAAYlkMrTIqEQAA&#34; alt=&#34;图片&#34; /&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    最后环节，自由提问时。哥抢到了话筒。哥问大BOSS&amp;#8217;EMC在上海，北京，成都都有研发。几时来华南设研发中心吖。&amp;#8217;。结果令我相当地伤心啊，boss说两年内不会有这个打算。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;img decoding=&#34;async&#34; src=&#34;http://b85.photo.store.qq.com/psb?/40ba6ef3-29ce-43f1-a784-3cf8d04442de/r9ZjlFCf07Iqukjoyzira1kA7BOgPThliDTd9dpAk44!/b/YfOjsTIBEQAAYgQ8tjIWEQAA&#34; alt=&#34;图片&#34; /&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    拿Mic的是回答我提问的大BOSS哈。
  &lt;/p&gt;
  &lt;p&gt;
    另外。EMC每年20天带薪年假啊，不管新老员工。尼玛，20天带薪年假，我要疯掉啦！！！
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>knowledge gained from learning git.</title>
      <link>https://ykyi.net/?p=203/</link>
      <pubDate>Fri, 09 Sep 2011 10:34:25 +0000</pubDate>
      <guid>https://ykyi.net/?p=203/</guid>
      <description>&lt;p&gt;# If you inadvertently remove a file of your working copy. Don&amp;rsquo;t worry. Git are good at recovering old versions of files, such as:&lt;br&gt;
$git checkout HEAD — data&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;# show what the file looks like in a certain branch.&lt;br&gt;
$git show branch_name:file_name&lt;/p&gt;
&lt;p&gt;# In newer versions of Git, git diff –ours is a synonym for git diff HEAD, because it shows the differences between &amp;ldquo;our&amp;rdquo; version and the merged version. Similarly, git diff MERGE_HEAD can be written as git diff –theirs. You can use git diff –base to see the combined set of changes since the merge base, which would otherwise be rather awkwardly written as:&lt;br&gt;
git diff $(git merge-base HEAD MERGE_HEAD)&lt;/p&gt;</description>
    </item>
    <item>
      <title>Diff, Patch, and Friends(diff, patch和他们的相关工具)(第二篇)</title>
      <link>https://ykyi.net/?p=191/</link>
      <pubDate>Fri, 02 Sep 2011 05:16:30 +0000</pubDate>
      <guid>https://ykyi.net/?p=191/</guid>
      <description>&lt;p&gt;原文 &lt;a href=&#34;http://www.linuxjournal.com/article/1237&#34;&gt;http://www.linuxjournal.com/article/1237&lt;/a&gt;&lt;br&gt;
翻译: &lt;a href=&#34;https://www.ykyi.net&#34;&gt;www.ykyi.net&lt;/a&gt; zausiu&lt;br&gt;
&lt;a href=&#34;http://ykyi.net/2011/02/diff-patch-and-friendsdiff-patch%e5%92%8c%e4%bb%96%e4%bb%ac%e7%9a%84%e7%9b%b8%e5%85%b3%e5%b7%a5%e5%85%b7%e7%ac%ac%e4%b8%80%e7%af%87/&#34; title=&#34;接上篇&#34;&gt;接上篇&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Use the diff program to avoid eyestrain and insanity:&lt;br&gt;
使用diff程序来避免会令人发疯的肉眼查找。&lt;/p&gt;
&lt;p&gt;diff -u 1 2&lt;br&gt;
— 1 Sat Apr 20 22:11:53 1996&lt;br&gt;
+++ 2 Sat Apr 20 22:12:01 1996&lt;br&gt;
-1,9 +1,9&lt;br&gt;
Ecce Eduardus Ursus scalis nunc tump-tump-tump&lt;br&gt;
occipite gradus pulsante post Christophorum&lt;br&gt;
Robinum descendens. Est quod sciat unus et solus&lt;br&gt;
-modus gradibus desendendi, non nunquam autem&lt;br&gt;
+modus gradibus descendendi, nonnunquam autem&lt;br&gt;
sentit, etiam alterum modum exstare, dummodo&lt;br&gt;
-pulsationibus desinere et de no modo meditari&lt;br&gt;
+pulsationibus desinere et de eo modo meditari&lt;br&gt;
possit. Deinde censet alios modos non esse. En,&lt;br&gt;
nunc ipse in imo est, vobis ostentari paratus.&lt;br&gt;
Winnie ille Pu.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Syntax Highlight in DDD DDD的语法高亮</title>
      <link>https://ykyi.net/?p=198/</link>
      <pubDate>Wed, 24 Aug 2011 00:32:07 +0000</pubDate>
      <guid>https://ykyi.net/?p=198/</guid>
      <description>&lt;p&gt;这几天用DDD调试linux下的程序.发现DDD没有语法高亮~&lt;br&gt;
于是google了一下。悲剧地发现一个贴子:&lt;/p&gt;
&lt;p&gt;Hello!&lt;/p&gt;
&lt;p&gt;Is it possible to enable syntax highlighting in DDD?&lt;br&gt;
I searched through the Google and found this answer:&lt;br&gt;
可以在DDD里开启语法高亮吗？我用谷歌搜索后发现这个答案。&lt;/p&gt;
&lt;p&gt;Sorry, no, this isn’t possible.&lt;br&gt;
The biggest problem is that Motif’s text widget doesn’t&lt;br&gt;
support multiple colours, and would have to be replaced.&lt;br&gt;
That would be an enormous job.&lt;br&gt;
不好意思。没有！这不可能.&lt;br&gt;
最大的问题是Motif的文本控件不支持多彩显示，必须把motif替换掉.&lt;br&gt;
这不是一个普通的/简单的任务.&lt;/p&gt;
&lt;p&gt;/////////////////////&lt;br&gt;
悲剧啊！！！在黑白的Linux世界。………..&lt;/p&gt;
&lt;p&gt;Is it still impossible (post date is Thu, 10 Feb 2005)?&lt;br&gt;
Are there any workarounds/patches/forks?&lt;/p&gt;</description>
    </item>
    <item>
      <title>Diff, Patch, and Friends(diff, patch和他们的相关工具)(第一篇)</title>
      <link>https://ykyi.net/?p=188/</link>
      <pubDate>Sat, 12 Feb 2011 03:29:02 +0000</pubDate>
      <guid>https://ykyi.net/?p=188/</guid>
      <description>&lt;p&gt;原文 &lt;a href=&#34;http://www.linuxjournal.com/article/1237&#34;&gt;http://www.linuxjournal.com/article/1237&lt;/a&gt;&lt;br&gt;
翻译: ykyi.net&lt;/p&gt;
&lt;p&gt;“Kernel patches” may sound like magic, but the two tools used to create and apply patches are simple and easy to use—if they weren&amp;rsquo;t, some Linux developers would be too lazy to use them…&lt;br&gt;
&amp;ldquo;内核补丁&amp;quot;听起来相当之神奇，但是有两个用来创建补丁和应用补丁的工具却简单易用。如果它们很难用的话，一些Linux开发者才懒得用它们呢。&lt;/p&gt;
&lt;p&gt;Diff is designed to show you the differences between files, line by line. It is fundamentally simple to use, but takes a little practice. Don&amp;rsquo;t let the length of this article scare you; you can get some use out of diff by reading only the first page or two. The rest of the article is for those who aren&amp;rsquo;t satisfied with very basic uses.&lt;br&gt;
diff这个工具设计成可以向你展示文件之间行与行的区别。它使用起来是相当的简单，但需要一点练习才习。你千万不要让长长的介绍文档把你吓住。你可以先只读前一两页文档，这样你就可以使用diff来开展一些工作了。余下的diff介绍文档是写给那些对基本用法非常不满的奇异人士的。 &lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>摆明车马</title>
      <link>https://ykyi.net/?p=152/</link>
      <pubDate>Sun, 02 Jan 2011 01:32:09 +0000</pubDate>
      <guid>https://ykyi.net/?p=152/</guid>
      <description>&lt;p&gt;#俗语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语.粤语俗语&lt;br&gt;
摆明：清清楚楚地摆开，这里指明白讲清楚；&lt;br&gt;
车马：象棋棋子。&lt;br&gt;
意思是首先给给方明明白白讲清楚，以免日后误会发生争执。&lt;br&gt;
%例句：我都摆明车马同佢讲楚个咯，费用由对方负责。点解仲要我哋出钱呀？（我都明明白白跟他们说清楚了，费用由对方负责。为什么还要我们出钱呀？）&lt;/p&gt;</description>
    </item>
    <item>
      <title>白云山一担泥，眼阔肚窄</title>
      <link>https://ykyi.net/?p=149/</link>
      <pubDate>Thu, 23 Dec 2010 05:29:28 +0000</pubDate>
      <guid>https://ykyi.net/?p=149/</guid>
      <description>&lt;p&gt;#歇后语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语.粤语俗语&lt;br&gt;
白云山：位于广州市区北部，是个风景区；&lt;br&gt;
从白云山挑一担泥下山，人们以为轻松便装得很满，谁知路远担重，往往无法完成。比喻人对东西总想多要，但实际上吃不了或用不了，无力消受。&lt;br&gt;
%例句：你要得咁多，小心白云山一担泥，眼阔肚窄喔。（你要得那么多，小心消受不了啊。）&lt;/p&gt;</description>
    </item>
    <item>
      <title>白云山蟋蟀，得把声</title>
      <link>https://ykyi.net/?p=147/</link>
      <pubDate>Wed, 22 Dec 2010 02:42:49 +0000</pubDate>
      <guid>https://ykyi.net/?p=147/</guid>
      <description>&lt;p&gt;#歇后语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语.粤语俗语&lt;br&gt;
白云山：位于广州市区北部，是个风景区；&lt;br&gt;
得把声：只有声音，即只会叫而已。&lt;br&gt;
白云山被开发以前，蟋蟀很多。广州人常去捉蟋蟀。但白云山的蟋蟀虽然叫声洪亮，却不善于打斗。人们用来比喻人只会叫喊不会做事。&lt;br&gt;
%例句：你乜都唔做，成日嘈嘈闭，好似白云山蟋蟀，得把声咁啫。（你什么都不做，整天叫唤，就像一只白云山的蟋蟀那样，只会叫不会做事。）&lt;/p&gt;</description>
    </item>
    <item>
      <title>白糖炒苦瓜</title>
      <link>https://ykyi.net/?p=143/</link>
      <pubDate>Mon, 20 Dec 2010 09:50:14 +0000</pubDate>
      <guid>https://ykyi.net/?p=143/</guid>
      <description>&lt;p&gt;#俗语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语.粤语俗语&lt;br&gt;
白糖是甜的而苦瓜是苦的，两样东西放在一起炒，其味道又甜又苦，比喻同甘共苦。&lt;br&gt;
%例句：你哋两个十几年嚟好似白糖炒苦瓜咁，真係难得咯。（你们两个十几年来同甘共苦真难得啊！）&lt;/p&gt;</description>
    </item>
    <item>
      <title>白蚁蛀观音，自身难保</title>
      <link>https://ykyi.net/?p=141/</link>
      <pubDate>Mon, 20 Dec 2010 09:38:22 +0000</pubDate>
      <guid>https://ykyi.net/?p=141/</guid>
      <description>&lt;p&gt;#歇后语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语.粤语俗语&lt;br&gt;
木雕泥塑的观音菩萨被白蚁蛀烂了，自己也保不住自己，怎么能够去保佑别人的平安呢？相当于“泥菩萨过河，自身难保”。&lt;br&gt;
%例句：呢次我都白蚁蛀观音，自身难保咯，点有力量去帮你呢？（这次我都成了泥菩萨过河自身难保了，哪里有能力去帮你呢？）&lt;/p&gt;</description>
    </item>
    <item>
      <title>白露水，冇益人</title>
      <link>https://ykyi.net/?p=139/</link>
      <pubDate>Mon, 20 Dec 2010 09:34:14 +0000</pubDate>
      <guid>https://ykyi.net/?p=139/</guid>
      <description>&lt;p&gt;#歇后语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语.粤语俗语&lt;br&gt;
冇益：没有益处，无利于。&lt;br&gt;
白露节气，在九月七，八或九号之间，民间认为这时下雨涨水时对人和庄稼都不利。“冇益人”表示无益于他人，甚至冇损于他人。&lt;br&gt;
%例句：你做呢个工程只顾你自己。白露水，冇益人。（你做这个工程只顾你自己，损害了别人。）&lt;/p&gt;</description>
    </item>
    <item>
      <title>百足咁多爪</title>
      <link>https://ykyi.net/?p=137/</link>
      <pubDate>Sat, 18 Dec 2010 02:25:42 +0000</pubDate>
      <guid>https://ykyi.net/?p=137/</guid>
      <description>&lt;p&gt;#俗语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语.粤语俗语&lt;br&gt;
百足：指娱蚣。&lt;br&gt;
爪：动物的腿，脚。&lt;br&gt;
意思是像蜈蚣那么多脚。比喻一个人爱走动，一天到处乱走，别人很难找到他。&lt;br&gt;
%例句：佢百足咁多爪，去边度揾佢呀？（他有像蜈蚣那样那么多腿，到哪里去找他呢？）&lt;/p&gt;</description>
    </item>
    <item>
      <title>百年归老</title>
      <link>https://ykyi.net/?p=135/</link>
      <pubDate>Sat, 18 Dec 2010 02:22:42 +0000</pubDate>
      <guid>https://ykyi.net/?p=135/</guid>
      <description>&lt;p&gt;#俗语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语.粤语俗语&lt;br&gt;
百年归老&lt;br&gt;
婉辞。指人活到一百岁以后最终逝世了，相当于普通话“百岁之后”。&lt;br&gt;
%例句：等佢百年归老之后再讲啦。（等他百岁之后再说吧。）&lt;/p&gt;</description>
    </item>
    <item>
      <title>霸巷鸡乸</title>
      <link>https://ykyi.net/?p=133/</link>
      <pubDate>Fri, 17 Dec 2010 01:29:37 +0000</pubDate>
      <guid>https://ykyi.net/?p=133/</guid>
      <description>&lt;p&gt;#俗语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语&lt;br&gt;
霸巷鸡乸&lt;br&gt;
鸡乸： 母鸡。&lt;br&gt;
在街巷里称霸的母鸡。比喻霸道的人，在当地称王称霸。&lt;br&gt;
%例句：你唔好若佢啊，佢係霸巷鸡乸嚟架。（你别招惹他，他是本地的小霸王。）&lt;/p&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;乸字的五笔编码是 bxgu，普通话读 nǎ 粤语读 naa4&lt;/p&gt;</description>
    </item>
    <item>
      <title>百斤加一，有你唔多，冇你唔少</title>
      <link>https://ykyi.net/?p=128/</link>
      <pubDate>Fri, 17 Dec 2010 01:19:24 +0000</pubDate>
      <guid>https://ykyi.net/?p=128/</guid>
      <description>&lt;p&gt;#俗语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语.粤语俗语&lt;br&gt;
百斤加一，有你唔多，冇你唔少&lt;br&gt;
挑东西时候一百斤再加多一斤，不算增加太重，减少一斤也轻不了多少。意思是有你无你都无足轻重。&lt;br&gt;
%例句：你算乜嘢吖，百斤加一，有你唔多，冇你唔少。（你算什么呀，有你不算多，没你不算少。）&lt;/p&gt;</description>
    </item>
    <item>
      <title>把口唔修</title>
      <link>https://ykyi.net/?p=125/</link>
      <pubDate>Wed, 15 Dec 2010 03:53:27 +0000</pubDate>
      <guid>https://ykyi.net/?p=125/</guid>
      <description>&lt;p&gt;#俗语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语&lt;br&gt;
把口唔修&lt;br&gt;
修：修行，积德。&lt;br&gt;
%例句：佢把口唔修，成日得罪人。（他说话缺德，老是得罪人。）&lt;/p&gt;</description>
    </item>
    <item>
      <title>阿驼命，死都唔得掂</title>
      <link>https://ykyi.net/?p=120/</link>
      <pubDate>Wed, 15 Dec 2010 03:41:41 +0000</pubDate>
      <guid>https://ykyi.net/?p=120/</guid>
      <description>&lt;p&gt;#歇后语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语&lt;br&gt;
阿驼命，死都唔得掂&lt;br&gt;
掂：直，妥当。&lt;br&gt;
唔得掂：不能直，不得了。&lt;br&gt;
驼背的人死了身体还不能直。&lt;br&gt;
谐谑语，比喻遇到危难，毫无办法。&lt;br&gt;
%例句：你如果搞唔好，咁就阿驼命，死都唔掂咯。（你如果这都搞不掂，那就到死都搞不掂啦！）&lt;/p&gt;</description>
    </item>
    <item>
      <title>转:一些好听的粤语歌(新).至2010年</title>
      <link>https://ykyi.net/?p=117/</link>
      <pubDate>Sun, 12 Dec 2010 08:57:00 +0000</pubDate>
      <guid>https://ykyi.net/?p=117/</guid>
      <description>&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;超合金曲 – （超好听）–蒋雅文+李逸朗 《K歌是少不了的》&lt;br /&gt; 文字流泪 — 谢安琪+陈慧琳&lt;br /&gt; 钟嘉欣 – 爱得起 – 郑融 〈韦雄在里面唱的几句，声音还可以〉&lt;br /&gt; 女生宿舍 – 望星打卦 – toby solo&lt;br /&gt; 唯一的你（超好听） — hotcha&lt;br /&gt; 男人信什么（超好听）–卫兰vs J .W&lt;br /&gt; 眼红馆（超好听的粤语歌~） — BOY~Z&lt;br /&gt; 再见不是朋友 — 邓丽欣&lt;br /&gt; 恋爱令人心痛（超好听）–钟嘉欣vs韦雄&lt;br /&gt; 没有童话（超好听）–叶文辉&lt;br /&gt; 花吃了这女孩 — 傅颖&lt;br /&gt; 吸血新世纪–羽翘&lt;br /&gt; 如果可以待你好 — 麦浚龙&lt;br /&gt; 接吻鱼的伤悲– 林颐&lt;br /&gt; 感激遇到你 （超好听）– 胡杏儿vs黄宗泽&lt;br /&gt; 你瞒我瞒 （超好听）–陈柏宇&lt;br /&gt; I Will Be Loving You （超好听）– 陈柏宇&lt;br /&gt; 三位一体–方力申vs吴雨霏vs廖梦乐&lt;br /&gt; 钟无艳 （超好听）– 谢安琪&lt;br /&gt; 陈某 — 周柏豪&lt;br /&gt; get out(很喜欢的前奏） — 卫诗&lt;br /&gt; Where Did You Go（超好听） — 邓紫棋gem&lt;br /&gt; 後备情人 （超好听）– 区瑞强&lt;br /&gt; 玩玩具-（超好听） — e-kids&lt;br /&gt; 恋爱自由式–陈文媛vs萧正楠 &amp;lt;恋爱自由式主题曲&amp;gt;&lt;br /&gt; 浮夸 — 陈奕迅&lt;br /&gt; 眼睛不能没眼泪（超好听）– 古巨基&lt;br /&gt; 今天终于知道错 — 陈伟霆&lt;br /&gt; 我不要被你记住（超好听）–周柏豪&lt;br /&gt; All About U — 邓紫棋&lt;br /&gt; kong–侧田&lt;br /&gt; 幸运水晶 — 陈苑淇&lt;br /&gt; 爱不疚(溏心风暴之家好月圆） — 林峰&lt;br /&gt; 内疚 （超好听）– EO2&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>阿聋卖布，唔讲呢匹pat1(笔bat1)</title>
      <link>https://ykyi.net/?p=113/</link>
      <pubDate>Sun, 12 Dec 2010 02:13:42 +0000</pubDate>
      <guid>https://ykyi.net/?p=113/</guid>
      <description>&lt;p&gt;#歇后语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语&lt;br&gt;
阿聋卖布，唔讲呢匹(笔)&lt;br&gt;
阿聋： 聋子。&lt;br&gt;
唔讲： 不讲。&lt;br&gt;
呢匹：这一匹。&lt;br&gt;
聋子卖布，因听不到顾客说的话，不论这匹那匹都一个价。广州话“呢匹”与“呢笔”音近。匹pat1, 笔bat1。而“呢笔”意思是这一件（事）。“唔讲呢匹(笔)”即不说这事。比喻跟人说话时，不愿意谈论某一话题。&lt;br&gt;
%例句：得啦得啦，我哋阿聋卖布，唔讲呢匹（笔）。（行了行了，我们不讨论这个。）&lt;/p&gt;</description>
    </item>
    <item>
      <title>阿聋送殡，唔听佢支死人笛</title>
      <link>https://ykyi.net/?p=110/</link>
      <pubDate>Fri, 10 Dec 2010 02:29:57 +0000</pubDate>
      <guid>https://ykyi.net/?p=110/</guid>
      <description>&lt;p&gt;#歇后语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语&lt;br&gt;
阿聋送殡，唔听佢支死人笛&lt;br&gt;
阿聋： 聋子。&lt;br&gt;
聋子去送殡，听不到为死人吹奏哀乐的笛声。这里的“死人笛”是双关语，兼指为死人吹奏的笛声和讨厌的话语，讨厌的说教。“唔听你支死人笛”相当于普通话中的“不听你的那一套”的意思。&lt;br&gt;
%例句:你唔好讲咁多咯，大家好似阿聋送殡，唔听你支死人笛架。(你别那么多废话，大家都不愿意听你的那一套了。)&lt;/p&gt;</description>
    </item>
    <item>
      <title>阿崩咬狗虱，唔死有排慌</title>
      <link>https://ykyi.net/?p=108/</link>
      <pubDate>Wed, 08 Dec 2010 08:47:20 +0000</pubDate>
      <guid>https://ykyi.net/?p=108/</guid>
      <description>&lt;p&gt;#歇后语&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语&lt;br&gt;
阿崩咬狗虱，唔死有排慌&lt;br&gt;
阿崩： 人名。&lt;br&gt;
狗虱： 跳蚤。&lt;br&gt;
唔： 不。&lt;br&gt;
排：量词，阵，场；&lt;br&gt;
慌：惊慌。&lt;br&gt;
缺牙的人咬跳蚤，跳蚤虽然没有被咬死，也会被吓得不得了。形容人遇到惊险，侥幸不死也被吓得惊异不已。&lt;br&gt;
%例句: 碰到咁大嘅灾害，真系阿崩咬狗虱，唔死有排慌咯。（碰上这么大的灾害，死不了也吓到不行。）&lt;/p&gt;</description>
    </item>
    <item>
      <title>阿均卖大头鱼，好噏唔噏</title>
      <link>https://ykyi.net/?p=105/</link>
      <pubDate>Mon, 06 Dec 2010 02:28:27 +0000</pubDate>
      <guid>https://ykyi.net/?p=105/</guid>
      <description>&lt;p&gt;#俗语。&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语&lt;br&gt;
阿均卖大头鱼，好噏唔噏&lt;br&gt;
阿均： 人名。&lt;br&gt;
噏： 嘴巴嗡动，比喻说话。&lt;br&gt;
唔： 不。&lt;br&gt;
阿均卖大头鱼，有顾客看到他的鱼嘴巴不动，嫌鱼不新鲜不买。顾客离去后，鱼的嘴巴又动了，阿均气得骂鱼：“你好噏唔噏”，意思是嘴巴该动时不动，不该动时却动。人们用这话来责备人该说话的时候不说，而不该说的时候又说了。&lt;br&gt;
%例句: 喺贵宾面前，你讲话要注意，咪学阿均卖大头鱼，好噏唔噏。(在贵宾前面，说话要注意点，别不该说的乱说。)&lt;/p&gt;</description>
    </item>
    <item>
      <title>阿保阿胜</title>
      <link>https://ykyi.net/?p=100/</link>
      <pubDate>Sun, 05 Dec 2010 03:14:19 +0000</pubDate>
      <guid>https://ykyi.net/?p=100/</guid>
      <description>&lt;p&gt;#俗语。&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语&lt;br&gt;
阿保阿胜&lt;br&gt;
阿何阿胜 泛指任何一个人，随便哪个人，相当于“张三李四”, “tom, jack”。&lt;br&gt;
%例句: 呢啲工作阿保阿胜都做得啦(这些工作张三李四都可以做的。)&lt;/p&gt;</description>
    </item>
    <item>
      <title>阿波校灯，有着有唔着</title>
      <link>https://ykyi.net/?p=86/</link>
      <pubDate>Sat, 04 Dec 2010 02:35:37 +0000</pubDate>
      <guid>https://ykyi.net/?p=86/</guid>
      <description>&lt;p&gt;#歇后语。&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语&lt;br&gt;
阿波校灯，有着有唔着&lt;br&gt;
阿波：人名。&lt;br&gt;
校: 调整校正，安装。&lt;br&gt;
着: 点亮(灯火)。&lt;br&gt;
唔: 不。&lt;br&gt;
阿波安装电灯，由于技术不过关或者责任心不强，有的亮有的不亮。比喻人在某一事中有对的地方也有不对的地方。&lt;br&gt;
%例句: 呢件事你系阿波校灯，有着有唔着，唔能够乜都怪人哋。(这件事你有对的地方也有不对的地方，不能够全怪别人。)&lt;/p&gt;</description>
    </item>
    <item>
      <title>阿崩养狗，转性</title>
      <link>https://ykyi.net/?p=81/</link>
      <pubDate>Thu, 04 Nov 2010 16:06:24 +0000</pubDate>
      <guid>https://ykyi.net/?p=81/</guid>
      <description>&lt;p&gt;#歇后语。&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语&lt;br&gt;
阿崩养狗，转性&lt;br&gt;
阿崩：豁嘴或缺门牙的人。&lt;br&gt;
转性：性变性格，转变脾气。&lt;br&gt;
传说阿崩很讨厌跳蚤，但缺少门牙抓了跳蚤也难以把它咬死。狗身上很多跳蚤，照理阿崩是不应养狗的，现在居然养起狗来了，人们便认为他的性格变了。多用来比喻小孩由淘气变为懂事。&lt;br&gt;
%例句: 你个仔呢排好似阿崩养狗，转性咯噃(你的儿子近来似乎有点变得懂事了。)&lt;/p&gt;</description>
    </item>
    <item>
      <title>阿崩买火石，噭过先知</title>
      <link>https://ykyi.net/?p=75/</link>
      <pubDate>Wed, 03 Nov 2010 05:21:25 +0000</pubDate>
      <guid>https://ykyi.net/?p=75/</guid>
      <description>&lt;p&gt;#歇后语。&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语&lt;br&gt;
阿崩买火石，噭过先知&lt;br&gt;
阿崩：豁嘴或缺门牙的人。&lt;br&gt;
阿过: 碰撞过。&lt;br&gt;
先知: 才知道&lt;br&gt;
阿崩买火石要把火镰同火石互相碰撞一下，才知道这火石的优劣。比喻人们要经过互相较量，才知道谁强谁弱。&lt;br&gt;
%例句: 我话边个队赢都好难讲，唯有阿崩买火石，噭过先知啦。(我说哪一个队赢都很难讲，只有较量过才能知道。)&lt;/p&gt;</description>
    </item>
    <item>
      <title>阿崩叫狗，越叫越走</title>
      <link>https://ykyi.net/?p=72/</link>
      <pubDate>Tue, 02 Nov 2010 12:41:03 +0000</pubDate>
      <guid>https://ykyi.net/?p=72/</guid>
      <description>&lt;p&gt;#歇后语。&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语&lt;br&gt;
阿崩叫狗，越叫越走&lt;br&gt;
阿崩：豁嘴或缺门牙的人。&lt;br&gt;
走: 离去。&lt;br&gt;
缺了门牙的人叫狗，狗听不清主人叫它做什么，以为是赶它走。形容小孩不听人叫唤，叫他来反而离去。&lt;br&gt;
%例句: 佢哋唔知係唔係怕我，个个都系阿崩叫狗，越叫越走。(他们不知是不是怕我，个个都越叫越不愿意来。)&lt;/p&gt;</description>
    </item>
    <item>
      <title>fsockopen真好用,PHP的高级别网络函数！</title>
      <link>https://ykyi.net/?p=67/</link>
      <pubDate>Mon, 01 Nov 2010 16:42:36 +0000</pubDate>
      <guid>https://ykyi.net/?p=67/</guid>
      <description>&lt;p&gt;今天用&lt;a href=&#34;http://ykyi.net/?p=40&#34;&gt;Burp工具&lt;/a&gt;分析了一个网站的大致功能后打算写程序把该网站我感兴趣的内容全抓下来。&lt;br&gt;
一开始用java写了一小段，但哥对Java不熟悉哇，而且哥觉得Java的那么多流的类，如果仅仅操作文本文件，就显得封装的太厚了。又想，用C/C++写。虽然用C/C++写的最多代码，但事实上C/C++的字符串操作一想起来就嫌烦，而且正则式也烂得可以，数组不支持用字符串索引也真够麻烦，虽然可用C++的std::map容器。最后决定用PHP写…PHP真是太好用了~~~犹赞超强大的正则式，同perl的正则式有得一拼啊。如果换用标准C字符串函数和GNU的一个超难用的C正则式库，那要写死人啊~~~&lt;/p&gt;
&lt;p&gt;最开始的思维定势就是要先开一个socket(N多参数要填入), 省略bind(操作系统自已选一个本地端口绑定)，第二步 connect 到主机，第三步往 socket 里写东西… 虽然只几个简单函数，但要填的几个参数也真够难记的。嘿，偶像发现事实上PHP提供了high-level的socket函数 fsockopen()。哇，太方便了。&lt;/p&gt;
&lt;p&gt;fsockopen()&lt;br&gt;
returns a file pointer which may be used together with the other file functions (such as fgets(), fgetss(), fwrite(), fclose(), and feof())&lt;br&gt;
fsocketopen返回一个文件指针，然后就可以用常用的文件函数操作它啦！！！和操作文本一件一样~~~ 比 Java 的 java.io.socket 类还要方便~~虽然java也抽象的不错，但我就是嫌流对象封装太厚了。人生苦短，何必自找麻烦呢。&lt;br&gt;
用完以后用 fclose 把它fsockopen返回的文件指针关掉！&lt;/p&gt;
&lt;p&gt;看个例程:&lt;/p&gt;
&lt;?php&lt;br /&gt; $fp = fsockopen(&amp;#8220;udp://127.0.0.1&amp;#8221;, 13, $errno, $errstr);

  
if (!$fp) {  
echo &amp;#8220;ERROR: $errno &amp;#8211; $errstr  
\n&amp;#8221;;  
} else {  
fwrite($fp, &amp;#8220;\n&amp;#8221;);  
echo fread($fp, 26);  
fclose($fp);  
}  
?&gt;  
&lt;p&gt;上面的例程从本机的UDP时间服务器里读取当时的时间和日期。如果你本机开了标准的时间服务的话~~~&lt;/p&gt;</description>
    </item>
    <item>
      <title>阿崩吹箫，嘥声坏气</title>
      <link>https://ykyi.net/?p=60/</link>
      <pubDate>Mon, 01 Nov 2010 15:43:19 +0000</pubDate>
      <guid>https://ykyi.net/?p=60/</guid>
      <description>&lt;p&gt;#歇后语。&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt; 广州话俗语&lt;br&gt;
阿崩吹箫，嘥声坏气&lt;br&gt;
阿崩：豁嘴或缺门牙的人。&lt;br&gt;
嘥：浪费。&lt;br&gt;
缺门牙的人吹箫，又费气力又吹不好。形容说话没有结果，白费唇舌。&lt;br&gt;
%例句: 讲咁多佢一句都听唔入，真系阿崩吹箫，嘥声坏气咯。(说了那么多，他一句也没听进去，真是白说了。)&lt;/p&gt;</description>
    </item>
    <item>
      <title>tcpdump基础教程</title>
      <link>https://ykyi.net/?p=45/</link>
      <pubDate>Sun, 31 Oct 2010 05:34:49 +0000</pubDate>
      <guid>https://ykyi.net/?p=45/</guid>
      <description>&lt;p&gt;英文原文出自： &lt;a href=&#34;http://danielmiessler.com/study/tcpdump/&#34;&gt;A tcpdump Tutorial and Primer&lt;/a&gt;&lt;br&gt;
翻译: ykyi.net&lt;/p&gt;
&lt;p&gt;Tcpdump是信息安全专业人士最重要的一个网络分析工具。对这个工具有一个深入的理解对于每一个喜欢透彻理解tcp/ip协议栈的人来话都是必须的。但很多人选择一个更高级别的工级，比如Ethereal Wireshark，但是我认为这是一个错误！&lt;/p&gt;
&lt;p&gt;不应该机械的反复记忆概念而应该做到真正的理解，因为对tcp/ip协议簇保持清醒的认知非常的重要。如果对该协议簇能够完全精通，那你调试网络的能力则能比同行们高出几个档次。但是，要学精神tcp/ip协议簇，只有不够的实践剖析它们才能做到。&lt;/p&gt;
&lt;p&gt;当你使用某种工具来显示网络中的原始流量信息时，人类，而不是机器，就要承担起分析这些流量的重任了。用这种方法就可以不断地加深对tcp/ip的理解。并且，用这种学习方法的时候，我在任何可能的情况下都强烈主张使用tcpdump而不是其它工具。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;选项&lt;/strong&gt;&lt;br&gt;
下面将列出一些用例子的选项，这样可以在你使用这个工具时对你有很大的帮助。这些选项很容易淡忘或与其它类型的滤镜(Filter,笔者认为这里的滤镜实际上指的是其它网络工具)混淆。比如, ethereal。所以，希望这篇文章可以作为一个参考文档，我就是这样使用它的。&lt;/p&gt;
&lt;p&gt;首先，我要先介绍几个我认为很方便的tcpdump的选项。第一个是 -n, 这样的话域名就不会被解析了，而是用数字IP的形式显示地址(译者注: 同netstat的-n是一样的喔)。第二个是 -X, 这样就会同时把包的内容以ASCII码和十六制的形式显示。最后一个是 -S, 它个选项会显示绝对序号而不是相对序号。因为当包被隐藏起来的话，你也不会看到奇怪的序号。请谨记，tcpdump较之其它工具的优势之一就是可以与包(packets)手工交互。&lt;/p&gt;
&lt;p&gt;值得注意的是，tcpdump默认只会从packet中取出前96个字节。如果你想要多一些的话，那就需要需要把 -s xxxx 加上。这里的xxxx是你确切想要抓取的总字节数。如果我使用这个选项的话，我通常会把这个数字设定为1514而得到所有的数据。下面是一个简短的列表列出我经常使用的选项。&lt;/p&gt;
&lt;p&gt;-i any: 监听所有的介面。这样你就知道是不是有流量产生。&lt;br&gt;
-n: 不要解决主机名，以IP数字形式显示主机。&lt;br&gt;
-nn: 不要解析主机名或端口名字。&lt;/p&gt;
&lt;p&gt;-A: 以ASCII字符显示包的数据。&lt;br&gt;
-X: 同时以十六进制和ASCII字符显示包的数据。&lt;br&gt;
-XX: 同-X,但也会显示 Ethernet头部。&lt;br&gt;
-v, -vv, -vvv: 详细，更详细，再详细些！ 冗余输出得到的包信息。&lt;br&gt;
-c: 抓取 x 个包后就停下。&lt;br&gt;
-S: 打印绝对序号。&lt;br&gt;
-e: 同时得到Ethernet头部。&lt;br&gt;
-q: 显示少一点协议信息。&lt;br&gt;
-E: 用提供的密钥解密 IPSEC 流量。&lt;br&gt;
-s: 设置显示前多少个字节的包内容（snaplength）。&lt;/p&gt;
&lt;p&gt;tcpdump 4.0的snaplength的长度从68字节改成了96字节，这样你就可以看到多些内容了。但仍然看不到所有的内容，指定 -s 1514 得到包的所有内容。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;一些基本的应用&lt;/strong&gt;&lt;br&gt;
根据我要查看的不同流量，我使用不同的选项组合，如下:&lt;/p&gt;
&lt;p&gt;1.Basic communication // see the basics without many options&lt;br&gt;
tcpdump -nS&lt;/p&gt;</description>
    </item>
    <item>
      <title>Burp套件教程(Burp Suite)</title>
      <link>https://ykyi.net/?p=40/</link>
      <pubDate>Thu, 28 Oct 2010 17:01:40 +0000</pubDate>
      <guid>https://ykyi.net/?p=40/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://portswigger.net/burp/&#34;&gt;原文来自http://portswigger.net/burp/&lt;/a&gt;&lt;br&gt;
ykyi.net 翻译&lt;/p&gt;
&lt;p&gt;使用Burp套件(Burp Suite)&lt;br&gt;
当启动Burp Suite以后，Burp的代理服务器就在本地的loopback介面上的8080端口上开始运行啦！通过设定浏览器使用这个Burp代理服务器，所有的WEB流量就可以被截获，窥视，修改。默认设置下，对非媒体资源(non-media)的请求将被截获而且显示出来(默认的设置可以在Burp Proxy的OPTION选项里修改）。所有的穿过Burp代理服务器的WEB流量将被自动分析并添加到站点地图里，这样就可以知道访问过的网站的内容和功能了。对于Burp的收费Professional版，默认情况下，所有的请求还会自动被Burp Scanner分析从而确定易受攻击的部分。&lt;/p&gt;
&lt;p&gt;在你就要刻苦大干一场之前，你需要完美地定义出你的工作的Target Scope(Burp的术语名词，不译出)。最简单的办法就是先浏览目标网站，然后定位相关主机和目录，再使用context菜单项把URL们添加到Target Scope里。中央范围配置(Central Scope Configuration)可以用来配置各个Burp工具。&lt;/p&gt;
&lt;p&gt;当你浏览目录WEB网站或程序的时候，你就能对截获的请求和响应进行手工编辑，或者你也可以完全关闭拦截功能。在拦截功能被关闭的情况下，每一条请求和响应仍然被记在历史记录里，所有的WEB内容也会被添加到站点地图里。&lt;/p&gt;
&lt;p&gt;除了可以用代理修改拦截下面的讯息，你也可以把迅息发送到其它Burp工具。这样就可以完成各种各样的不同的功能，比如：&lt;/p&gt;
&lt;p&gt;》你可以通过把请求发给Repeater来手动调节对WEB程序的测试，也可以不断地重发每个请求。&lt;br&gt;
》对于Professional版，可以把请求发给Scanner，就可以完成主动和被动漏洞扫描。&lt;br&gt;
》你可以把请求发给Intruder，就可以发起一个用户自定义的自动测试来确定一些常见的漏洞。&lt;br&gt;
》如果你发现响应中有会话令牌或者其它本应该是不可预测的ID号，你就可以把这个响应发给Sequencer来测试这个令牌的随机性。&lt;br&gt;
》可以把请求或响应中被模糊化处理的数据发给Decoder来尝试自动解析出明文。&lt;br&gt;
》对于Professional版，你可以使用各种Engagement工具来提高你的工作效率。&lt;br&gt;
对于代理的历史记录，站点地图中的主机·目录·文件 以及Burp工具的任何显示请求和响应的地方 你都可以执行以上任何操作。&lt;/p&gt;
&lt;p&gt;中央日志功能(central logging function)记录下来每个Burp工具的所有的响应和请求。每个Burp工具都可以在单独的窗口中运行也可以在TAB WINDOW下运行。每个工具和整个套件的配置可以被保存下来重复使用。对于Professional版，你还可以保存每个工具的状态，这样你就可以随心所欲的重新载入之前保存的状态。&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>怎么学粤语</title>
      <link>https://ykyi.net/?p=24/</link>
      <pubDate>Mon, 25 Oct 2010 12:36:39 +0000</pubDate>
      <guid>https://ykyi.net/?p=24/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;经常有人问怎么才能学好粤语，也经常听到很多人说:听多D讲多D就识啦~ 其实不是这样的，最多只能说部分正确。下面以我的经验告诉你怎么学好粤语。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;我来广东之前也不会讲广东话，更要命的我还以为自己唱的几首粤语歌很准，现在回想真是太可怕了。07年到广州没有正式学，一年下来还是什么都不会，大部分听不懂。后来我去了珠海。因为有一次同几个Friend吃饭，其它人都讲白话(白话在广东省指粤语)，我不懂啊，觉得不好意思大家迁就我改讲普通话。于是我那次以后开始正式决心学粤语啦！！！事实上用了三个月就基本上能够沟通了，就有人第一次赞我&amp;rsquo;讲得唔错&amp;rsquo;啦。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;strong&gt;错误的学习方法:&lt;/strong&gt;&lt;br /&gt; 对于大多数人，特别是母语不是客家话，潮汕话，闽南话的年龄在十岁以上的朋友要想仅仅靠“听多点就自然会”几乎是不可能的！只有小孩子有只靠听就能学会语言的‘人类的特有能力’。遗憾的是你不是小孩子了，你的大脑收到声音讯号就在你已经会的语言里找发音相同或相近的，但普通话同粤语的发音相差太大了，粤语还有N多自已独有的词汇。有些词或句子，如果没有人指导你，你就是听一万遍，听十万遍，你也听不懂。到了广州生活工作了十年以上还只能听懂简单粤语的人大把大把就是这个原因。还有些人说找个人教教你就会了。很难！首先找个愿意花大把时间教你的人不容易，更致命的是他们不会教。他们只会不断的告诉你，错了，不对，唔正，点解你发音好怪！但他们不知道怎样才能教会你发正确读音。几个回合下来，你和你的老师全部都精神崩溃了。老师报怨教你不会，你报怨粤语太难。你的老师于是就安慰你了:听多D讲多D就识啦！于是你再过一个星期放弃了。即使是会客家话，潮汕话，闽南话的，这几种方言的发音系统同粤语很接近，也仅仅让你容易学习很多，但这部分人中很多发音也很不正，大把人不分前后鼻音, l 和 n。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;strong&gt;实践检验正确的学习方法:&lt;/strong&gt;&lt;br /&gt; 自我经验证明行之有效的学习方法包括四个方面: 1.熟悉粤语拼音. 2.熟悉粤语基本词汇. 3.粤语歌影视做为补充. 4.有一位会纯正粤语的朋友鉴定你的发音。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;a href=&#34;http://ykyi.net/school/jyutping_crashcourse.php&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;1. 粤语拼音方案: &lt;a href=&#34;http://ykyi.net/school/jyutping_crashcourse.php&#34;&gt;http://ykyi.net/school/jyutping_crashcourse.php&lt;/a&gt;&lt;/a&gt;&lt;br /&gt; 首先你必须理解普通话拼音，毕竟都是汉语语系，普通话和广东话大部分声母和一半韵母是相同的。另外会英文国际音标是极好的补充！粤语里有两个英文里常用的元音，分别是æ(apple中a的发音)和 ʌ (cup中u的发音)，但普通话里没有这两个元音，有些人听到ʌ这个元音就把它当成普通话拼音里的e，有些人把它当成a。另外粤语里的入声同英文里的短元音有点类似，比如book,shit。只是类似，学到粤语入声时可以参考下。闽南语也完整保留入声系统，会闽南语的可以无视入声.会客家话和潮汕话的也基本上可以无视。还有粤语里的 该 字的发音基本上就是英文单词boy的发音把声母由b改成g。再之，粤语有m,n,ng三种韵尾，普通话里没有m韵尾，所以大部分学习者都把粤语里的心sam1读成身san1。歌手易欣有首粤语歌。易欣就是把‘心’唱成‘身’了。要解决这个方音问题，参考一下英语单词的gun(枪),和gum(口香糖)就豁然开朗啦！你能区分gun和gum吗？&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;然后你就要开始学粤语拼音啦！很多人觉得拼音很难，想跳过这一步，我还是劝你学点粤拼先，磨刀不误砍柴刀，只学了六七成也能让你学粤语时效率提高数十倍。学粤语拼音是为了学习粤语的发音系统，如果你不熟悉粤语的发声系统，很多字的读音，你就总是用自己母语或者普通话的发音系统去理解，这时候虽然你自己听起来一样，但其实读错了。比如不懂粤拼的学习者，一百个有九十八个以为粤语的‘点dim2’和‘典din2’发音是一样的。还有时还很搞笑。比如：说‘阿伯baak3’可能说成‘阿爸baa1’。言归正传，一开始你只需要了解一些粤语拼音，学会使用这个拼音工具来帮助自己理解发音和纠正发音。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;2. 熟悉粤语基本词汇&lt;br /&gt; 这个是必须的，但也非常容易。比第一项要求要容易很多，估计只需要花你几个小时的时间。你可以买一两本粤语书教程，一般的教程基本上都讲了粤语用的日常词汇。&lt;a href=&#34;http://ykyi.net/toubou/promote.php&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;a href=&#34;http://ykyi.net/toubou/promote.php&#34;&gt;http://ykyi.net/toubou/promote.php&lt;/a&gt; 这里有介绍的书中有几本我用过&lt;/a&gt;有些人连粤语的基本词汇都不知道就冲到QQ群里叫人教粤语。拜托，谁有那么多时间啊。点解，点样，唔该，得佐，冇，先，添 这些很日常的词汇看看就会了。语法的话，虽然粤语有句式有小小不同，但基本上和普通话一样，可以无视的。大话西游里的台词&amp;quot;给个理由先&amp;quot;就是广东话的句式。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;3. 粤语歌和影视，新闻媒体&lt;br /&gt; 听唱粤语歌和看粤语发音的影视可以让你在娱乐中培养你的听觉系统把某些发音同各个汉字建立联系。因为普通话的发音同粤语话相去甚远，你需要听唱N多粤语歌和影视或者新闻来建立这个声音到字的条件反射。在这个过程中，之前你学过的一粤语拼音就要派上用场了。你听到发音的时候去想这个字的粤语拼音，在实践中理解那些你之前不懂的发音，比如 oe 是什么（实际上是国际音标中的æ）；p,t,k入声字怎么读，以及粤语的各个不同的声调等等任何你之前不理解的粤语拼音在实践中不断体会。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;4. 有一个粤语老师。&lt;br /&gt; 这个非常重要，基本上和第一条一样重要。实际上第二，第三条你都可以略去，但第一和第四条太重要了。如果缺了第一条，仅有老师，他极有可能像此文刚开始提到的那样教不会你；如果缺了第四条，你不知道自己的发音有没有发对。比如律师的律字注音为 leot6 , 用国际音标可以注为 læt, 这个字读粤语的第六声。假如这个字你没有把握，你就去问你的老师自己发音有没有读对，然后不断的参照拼音调整自己的口腔的吐气声调，直到你的老师肯定你的发音。如果没有粤拼，你很痛苦的，你的老师也更痛苦，一个不知道哪里读错了，一个不知道怎么才让你读对。比如粤语的六个音调，你就可以选夫(fu1), 苦(fu2), 富(fu3), 扶(fu4), 妇(fu5), 父(fu6) 这六个字在同你老师交流中体会学习。韵母a, aa亦然，粤拼里的a实际上是英语音标中的ʌ，aa才是普拼和音标中的a. 以粤拼为工具在和你的老师交流过程中学习吧！&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;以上四个条件，互相促进！！！如果你按照这个方法做了。学会用粤语基本沟通是很容易的事情，我就是用这个方法学的，不过用了三个月的时间而已。学会唱粤语歌更加是小菜一碟了！&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</description>
    </item>
  </channel>
</rss>
