前言 今天给1702班的娃们答疑,遇到了一个问题,当时很蒙,后来想了想就是之前的一个问题,当时解决了却忘了总结了,今天赶紧总结下。 正文 源程序是这样的(就作为我们的实验1) char a = '\0x41'; printf("%x",a); 结果是个31,emmmm 看上去结果很有迷惑性,恩 其实我们只要在ASCII表里找一下0x31对应的值就好啦,是’1’。 那么我们再改成’\0x51’,’\0x61’,’\0x71’试试。 结果是一样的。 让我们再做个实验验证我们的结论: char a = '123'; putchar(a); 这时直接打印3。 需要注意的是,上面的两个实验都会报warning,而且都是相同的 1.c:10:11: 警告:多字节字符常量 [-Wmultichar] char a = '\0x41'; ^~~~~~ 1.c:10:11: 警告:隐式常量转换溢出 [-Woverflow] 那么这和哪个警告有关系呢? 第三个实验: char a = '\0x'; print 继续阅读 >>


康艺杰 18/01/06 15:08:08
前言 最近发现一个公众号,每天一道题,难度也不大,而且题干很短,搜了下,题都是LintCode这个平台的,今天注册了小号做了做,中文很友好(和LeetCode相比,可以说造福广大吃瓜群众),然后可以看到哪个用例过不去(造福非ACMer,看到WA就“卧槽,咋可能错了”的选手),并且类似LeetCode,只用写关键的方法,不用去管格式化输出输入。 正文 LintCode 144 交错正负数 描述: 给出一个含有正整数和负整数的数组,重新排列成一个正负数交错的数组。 样例: 给出数组[-1, -2, -3, 4, 5, 6],重新排序之后,变成[-1, 5, -2, 4, -3, 6]或者其他任何满足要求的答案. 我的思路很简单,因为没有要求必须是正开头或者必须是负开头,只要A[1]A[3]A[5]….与A[0]符号不同,A[2],A[4],A[6]…与A[0]符号相同就满足要求。 于是就写下这样的代码: class Solution { public: /* * @param A: An integer array. * @return: 继续阅读 >>


康艺杰 17/12/31 15:47:29
前言 有时结果和你想的不一样,并不一定是你想错了。。。可能是编译器优化了。 正文 在给学弟讲题时遇到了这样一个问题,代码如下 class A{ public: A() = default; A(const A &a): str(a.str){ cout << "copy" << endl; } A(const string &d):str(d){ cout << "str" << endl; } string str; }; void func(A a) { cout << a.str << endl; } int main() { func(string("hello world")); } 大家想一想输出结果是什么? Ok,我的思路是这样的: 首先调用std::string 的构造函数,通过一个字符串常量,构造了一个std::string对象,这个对象是个临时值,也就是说是个右值,我 继续阅读 >>


康艺杰 17/12/30 20:42:38
前言 圣诞节到了,身为单身狗保护协会的一员是不是应该关心一下身边的单身狗呢? 那么就在节日喜庆氛围而单身狗还打开电脑撸码之时,送他一份特别的惊喜吧。 效果如下: 正文 没错,我们要的效果就是 一句惊艳的祝福,然后一切回归正常,就像什么都没发生过~ 整个操作可以分为3部分 1.绘图(就是准备好你的祝福啦)。 2.设置惊喜的开关。 3.清除操作痕迹。 绘图 这里因为要在终端上显示,所以我找到一个将字符转换为“画”的软件 Figlet,这个软件也有很多年的历史啦。 在Fedora 25上直接dn安装即可 $ sudo dnf install figlet 使用也很简单,比如我想输出kangkang,就直接 $ figlet kangkang 便绘制好输出在终端上了,当然你也可以进行重定向输出到文件里 当然啦,既然我们要绘图,就一定要画得好看。 我们可以通过-f 参数选择字体。 $ figlet -f bannner kangkang figlet自带了一个预览字体的工具showfigfonts,和一个查看本机figlet支持字体(和字符 继续阅读 >>


康艺杰 17/12/25 18:39:10
前言 这周六要去上海比赛,又是一个小水赛,据说要考算法,感觉自己也没啥刷题的基础,就开始看动态规划,之总感觉DP非常的高大上和难理解,所以这两天学会一点就要赶紧总结呀~ 因为我也没怎么刷过题,只是这两天看了看,所以如果理解上有不足之处,欢迎各位指正。 正文 感觉大家一说起动态规划,都是感觉非常的难,离我们非常的远,其实不然,费波那契数列(下用fib代替)大家一定都做过。(emmmm一般提到这个都是为了讲 递归,其实这是一部分吧)我觉得求fib就是一种最简单的动态规划,为什么? 先让我们从一道典型的DP题来看看吧。 典型的DP — 数塔 数塔(HDU2084) Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 49209 Accepted Submission(s): 29082 Problem Description 在讲述DP算法的时候,一个经典的例子就是数塔问题,它是 继续阅读 >>


康艺杰 17/12/11 22:56:41
引子 秋天过去了,我很想念它。 从软件自由日之后的9月、10月、11月几乎是匆匆忙忙,跌跌撞撞地过去,也做了不少事情。 比较扯的几个比赛 图论杯 引子 这是一个叫做“图论”的培训班(一个连名字都这么专业的培训班)办的比赛,这个比赛6月中就开始宣传,然后我们在暑假之前就已经完成了初赛(笔试答卷子),复赛(上机写题)。 决赛 等待了漫长的一个暑假之后终于来到了决赛,9月24日我们去决赛—传说中的面试,(每次去比赛都是在西区xx楼5楼),平时感觉自己不错,但是真的到这种面试时,才感觉自己基础还是很薄弱。 印象最深的一道题就是 “malloc能否分配1G内存?如果机器只有1G物理内存呢?” ,当时一下子被问住了,回来之后又好好查了查,觉得就像陈老师说的,我们很多的知识都是学的一块一块的,并没有融会贯通,并且对于底层还是不够深入。 那天比赛完了(就15分钟的面试,还包括自我介绍),我自己心里暗暗地想,这学期真的要好好努力了,距离预期的目标还差的远呢。 这次宣布结果倒是挺快的,第二天,我们就收到了通知,MT一等奖,Spider和Axin 继续阅读 >>


康艺杰 17/12/02 14:49:22
前言 我们在学习的日常中会用到的各种开源软件,大一点的Linux,Apache,Nginx,MySQL,Redis,小一点的Muduo,Axel,那么如何去给一个开源项目做贡献呢。 这里我主要介绍如何使用github来为开源项目贡献,或者说,使用github进行多人协作。 本文主要使用@Hg_Yi @dela @dongmengyuan 的Java Web项目作为示例,借用了@Axin的帐号来示范操作,感谢小伙伴们的友情支持。 正文 首先我们想为开源贡献的流程往往是: 1.找到一个需要的开源项目。 2.使用、或者学习它。 3.在学习/使用中发现问题,或者想为它做贡献(改bug,加feature)。 但问题是不知道如何贡献,或者说这个流程应该是怎样的。 这里我们用一个非常简单的例子来描述一下大致的流程。 首先Fork之 在你需要的项目主页,点击右上角的fork 这样你能拥有一份项目的拷贝,同时看到你的项目与主分支有哪些差异。 Fork好啦 这就是你自己的代码,你想怎么就怎么改。 需要注意的是可以看到多了一行 This bra 继续阅读 >>


康艺杰 17/11/22 17:07:57
引子 人在桌前坐,bug天上来。昨天早上到了小组,正准备总结一下爬山之旅,东哥就给我发了一个bug,让我也帮忙瞅瞅。。。 bug描述 是一个使用Redis跳跃表的demo,可以参照 东哥在RedisDB上的求助贴 东哥在StackOverFlow上的提问 这个关于Redis的demo如下 zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank) { zskiplistNode *x; unsigned long traversed = 0; int i; x = zsl->header; for (i = zsl->level-1; i >= 0; i--) { while (x->level[i].forward && (traversed + x->level[i].span) <= rank) { travers 继续阅读 >>


康艺杰 17/11/13 12:01:53
前言 你以为我鸽了其实我没有鸽,这也算是一种鸽。 继续来填坑啦。 在上两篇中,我们都是使用的链表进行保存定时事件,当我们需要增加一个或者删除一个事件时都需要O(n)的时间复杂度,本篇我们通过时间轮(time wheel)这种数据结构来对其进行优化,而libco也是通过时间轮来进行处理的,所以就拿着它的代码来讲啦。 正文 Libco的作为一个协程库,相当于在用户态完成了逻辑流的切换,这里的调度便是一旦遇到阻塞的系统调用(如read)时,将其注册到epoll_wait中并切换逻辑流,等待其I/O事件的到达,一旦到达则进行处理,将同步阻塞I/O换成了I/O多路复用。 而这里便是将I/O事件当作定时事件来处理,将I/O事件设置超时事件,如果超时则直接处理,避免一直等待的情况。 libco管理定时事件便是使用时间轮这种数据结构,通过一种hash的思想使得添加定时事件的时间复杂度降到O(1),大大提高了效率。 我们先来看看时间轮是怎样的东西。 时间轮是个啥 在之前我们通过链表,按照超时时间进行升序或者降序的排列,这样添加事件就需要O(N)的时间复 继续阅读 >>


康艺杰 17/11/09 22:19:30
前言 心情不好就跑步,跑完步就写写博客,反正看到哪就写哪. 正文 Item 26 : Postpone variable definitions as long as possible 尽量延后变量的定义,感觉有一种“惰性求值”的味道? 当我们定义的变量具有析构&构造函数时,一旦定义它我们就需要承担析构和构造的成本,但是,如果并没有用上它,或者在定义之后,发生某种错误,而直接return了,那么就白白耗费了时间。 string cmd; string name; while(cin >> cmd){ if(cmd == "get") cin >> name; if(cmd == "quit")// 直接退出,name完全没用上,却要构造和析构 return; } 同时,当我们需要必须要定义时,这表明我们已经为这个对象的“出生”准备好了条件,否则,要先调用default构造函数,再copy构造,白白耗费一次default构造。 string cmd; string n 继续阅读 >>


康艺杰 17/11/04 22:52:10