re: 设计的两难:选择异常还是两段构造 肥仔 2010-03-05 10:31
@饭中淹
每个对象都要显示的create和release。那基本上等价于放弃了C++构造函数和析构函数这两个特性。
对于栈对象,这样会很累,也很容易泄漏。
re: 美利达公爵 vs ATX740 肥仔 2009-10-19 10:29
我是博主,楼上的说话不雅
Ragel用来解析协议是很棒,很快的东西。
Ruby的若干个http服务器,是使用Ragel生成http_parser的。还有解析html,xml的,等等。
做网络或者Web数据抓取的,也有空的兄弟,可以研究下,无奈中文资料基本没有,国外使用的人也不是太多。
@陈梓瀚(vczh)
我知你对这类东西蛮有研究的,介绍Ragel,你不妨去弄弄,据我现在所得结果,虽然都是自动机识别,但他比Lex要快,尤其-G2选项之后,函数全部内联,统统goto,没有用数组,速度快到无法形容。
另外还可以生成dot文件,调用Graphviz画出自动机的图形,这个很爽啊(我把ragel生成的r_atoi自动机图补到上面了,翻上去找找...)
不知谁有闲时间去翻译一下它的man page,我想去翻译,无奈真是太忙了,生活所迫啊。
再次改善了一下,加了一个inline,时间变为 2562 ms了,因为去掉了函数调用开销
inline long my_atoi(const char *str)
{
long val = 0;
bool b_neg = ('-' == *str);
if(*str == '-' || *str == '+')++str;
while(*str)
{
if(('0' - 1) < *str && *str < ('9' + 1))
val = val*10 + *str++ - '0';
else
break;
}
return b_neg?-val:val;
}
改善了一下my_atoi, 同等规模下测试,时间为:3468 ms
这一下心里平衡了,可以安稳睡一个觉了
long my_atoi(const char *str)
{
long val = 0;
bool b_neg = ('-' == *str);
if(*str == '-' || *str == '+')++str;
while(*str)
{
if(('0' - 1) < *str && *str < ('9' + 1))
val = val*10 + *str++ - '0';
else
break;
}
return b_neg?-val:val;
}
刚刚自己再手写了一个my_atoi,同等规模下测试,时间为:13536 ms
为什么差距就这么大涅?
long my_atoi(const char *str)
{
long val = 0;
bool b_neg = ('-' == *str);
if(*str == '-' || *str == '+')++str;
while(1)
switch(*str++)
{
case 0:
return b_neg?-val:val;
case '0':
val = val*10 + 0;
break;
case '1':
val = val*10 + 1;
break;
case '2':
val = val*10 + 2;
break;
case '3':
val = val*10 + 3;
break;
case '4':
val = val*10 + 4;
break;
case '5':
val = val*10 + 5;
break;
case '6':
val = val*10 + 6;
break;
case '7':
val = val*10 + 7;
break;
case '8':
val = val*10 + 8;
break;
case '9':
val = val*10 + 9;
break;
default:
return 0;
}
return 0;
};
@NeutralEvil
第二条补充得太棒了,我没有想到你补充的那点,汗!
STL的伟大,正是在抽象之后,形式上的统一,优美啊。
re: VC++ 6 的 MSDN 插件 肥仔 2008-12-22 20:35
我用VC6和SDK/MSDN 2003,不需要额外的东西就可以关联。
MSDN用那么高版本有什么意义吗?如果VC6能够把编译器升级到高版本才叫爽啊,可惜不行。
re: 代码坏味3 肥仔 2008-12-22 20:21
我的几个观点,供参考
1、从代码看来,你的设计是面向功能的,按功能分解是结构型程序设计方法的模式;
2、OOP应该是面向对象的,非:pulic 功能,应该是:public 基础对象;
3、好的设计不应该出现多继承;
请参见转贴的这篇博文,有更好的对如何继承的原则描述
http://www.cppblog.com/woaidongmao/archive/2008/12/16/69567.html
re: 日志该怎么记录? 肥仔 2008-12-22 12:18
日志作用大了去了,查bug,特别是业务逻辑的bug,查安全,黑客,做roll back, 作业务分析,用处实在太多了
一个大系统,若没有规范的日志体系,那就是个豆腐渣工程。
总是有很多人喜欢说别人搞不清什么跟什么的区别。我真的很糊涂,那些所谓的区别,在眼里根本就不值一提的东西,有必要写出来吗?
我支持搂主,原创即分享,Great。
re: 面试在华为 肥仔 2008-12-18 18:42
华为的名声在深圳这边很差,有工作经验的coder,如果打电话过来叫面试,一听是华为,马上就挂了,我也挂过很多次,压根没投过他的简历,他也找得到你,估计和51job有合作关系。
华为工资不高,但把人当牛使。喜欢去的都是没毕业或刚毕业的学生,觉得华为牛而已吧,事实却和想象有蛮大的差别,需要慎重考虑了。
re: 实现程序自己更新自己 肥仔 2008-12-17 23:28
批处理实现不了太复查的更新逻辑,这个是弱点
re: 代码的坏味2 肥仔 2008-12-17 23:10
re: 代码的坏味2 肥仔 2008-12-17 22:56
个人感觉搞错了方向,可能的原因有2种
1、死锁,可能性不大,因为并不是每次都不行;
2、工作线程执行了更新界面的操作,且通过调用引用控件的方法来更新的。因为控件方法调用实际上是SendMessage,应该用PostMessage就不会错了。
考虑如下情况:
按下按钮,界面线程执行OnButton,等待工作者线程释放锁;
在同一时刻工作者线程更新界面,因为任何界面更新实际上都是界面线程完成(通过消息队列),如果用的是SendMessage模式,工作者线程必须等待完成才可以走一下步,而等待完成的前提是OnButton完成。
这样就OnButton在等待锁,工作者线程在等待OnButton完成才可以释放锁,无响应了,所以工作者线程更新,应该用PostMessage。
@于
这个是从别人博客抄过来的,你需要google一下这个标题,就应该能找到原作者了。
re: 用Mis平台生成Mis 肥仔 2008-12-12 13:58
上传个你软件生成的HTML前台如何?
re: 用Mis平台生成Mis 肥仔 2008-12-12 13:54
很不错啊
HTML做出了桌面软件的风格。
你那个软件是用来定制HTML的和数据库表的?
定制生成前台这个ideal很棒!!!
re: 小写了个XML解析器 肥仔 2008-12-10 18:20
struct xmlNode
{
...
struct xmlNode *child;
struct xmlNode *sibling;
};
==================
这种结构处理起来,好累的。我的xml解析器采用下面这种结构
struct xmlNode
{
...
vector<xmlNode*> childs;
struct xmlNode* parent;
};
re: 回调函数和函数指针 肥仔 2008-12-07 20:13
re: 回调函数和函数指针 肥仔 2008-12-07 20:10
good.
回调函数和函数指针是低阶的技术特性。
一个建议是,可以在此基础上,更进一步,学习理解“委托”这种基于回调的高阶编程思想,将得到更多。。。。。。
@helpsoff.com.cn
呵呵,好了。
我必须得承认,你很强,你问的问题让我不知所措,我非常地茫然,几乎无地自容。当然不会删你的留言,只要不是粗痞话,我都不会删。大侠的更要留着偶尔看看,好让自己感到自卑。
这既然是一个你不屑的地方,就不必再来了吧,何必来看这么肤浅的文章影响了您老人家的心情?
送客了,远方的客人请您别再来~~~,:)
@helpsoff.com.cn
呵呵,这不是我们第一次交流了,你这位同志比较喜欢好为人师嘛。但是需要说出点稍微有参考价值的东西,才可以教育别人,是不是。
交流需要平等,干嘛老摆个姿态呢,我觉得不好。
@guest
汗,VC6如果对POD这样的标准都支持不了,那就太那个。
VC6一直在用,而且最近1~2年内应该还是会作为工作的首选,没觉得有什么不好。赛扬CPU,512MB的内存,开4个VC6 IDE,并行开发一点都不卡,舒舒服服。
AMD双核,2G内存,打开一个VS 2008,只听到硬盘狂叫,10秒以上才能出个界面,这就是.net的效果?。
上次CSDN看到一个投票,目前C++集成开发环境,10年了的VC6占30%多,依然居第一位。
@vczh
这种核武器都用上了。。。
看来看去,还是宏最简洁,优美,漂亮。
@RedNax
?? 有差别吗? 代码不好看,我指p_self->data.val_a,多了一个data,能够去掉这个data就好看了。
因为项目中需要提供一个这样的能力:有几百个全部是static成员的struct,它们只有最后一个字段是个POD数组,长度会不同,需要有一个统一的接口来访问这些struct的成员,所以做了这个测试。
@RedNax
根据你的提示,测试了另一个种情况,证明内存确实不连续,与定义顺序相关 +编译器相关。
我找到了一种强制内存连续的办法,接口转换也OK,但代码不好看了,如下:
#include "stdafx.h"
#include <stdio.h>
typedef struct
{
struct __Data
{
char* text;
int val_a;
int val_b;
} static data;
} sData, *Self_Ptr;
typedef struct
{
char* text;
int val_a;
int val_b;
}* Other_Ptr;
sData::__Data sData::data
={ "this is a test string\0", 100, 200};
int main(int argc, char* argv[])
{
Self_Ptr p_self = 0;
Other_Ptr p_other = (Other_Ptr)&(sData::data.text);
printf("%d\n", sizeof(sData));
printf("val_a: %d-%d\n", p_self->data.val_a, sData::data.val_a);
printf("val_b: %d-%d\n", p_self->data.val_b, sData::data.val_b);
printf("val_a: %d-%d\n", p_self->data.val_a, p_other->val_a);
printf("val_b: %d-%d\n", p_self->data.val_b, p_other->val_b);
return 0;
}
@RedNax
right, 你的判断正确,换成Self_Ptr p_self = NULL; p_self->val_a不会内存访问违规,说明编译期已经替换了p_self->val_a。
@RedNax
如果我没有记错的话
class不是POD,即使是非静态成员,也不能保证连续,标准没有这样的规定。
成员为内置内型或POD类型且同时没有成员函数的struct可以归为POD了,标准规定POD内存必须连续,有static成员的struct还算不算POD,这个我倒是不知道。
re: 聪明反被聪明误,一个bug 肥仔 2008-12-03 10:56
@brian
牛,确实太油才了
re: 我绘制的圆饼图 肥仔 2008-12-03 01:00
程序是好的,想法是好的,就是少那么点美感。泡个做美工的女孩调教调教吧
re: 系统优化日志(1) 肥仔 2008-12-01 15:42
a. 这一层的类命名为 CxxxDlg, CxxxView……
------------------------------------------
应该是CDlgXXXX,CViewXXXXX, 这样文件名和class view排序都会连续,而且更易理解,看左边几个字符,并明白了类型。
一点经验。
re: 截取网页快照的dll 肥仔 2008-12-01 12:57
很有创意,且提供源代码
可惜没有这方面的需求,用不上了。
@周星星
传说中挖bug狂人?
我blog偷盗了你蛮多篇文章,不要报警啊
文法好写,也好理解,但文法之后的事情才叫难于上青天,借助YACC解析代码生成一颗语法树就非常头痛了,剩下的符号提取,解释器,语法树运算更不用说了。
我找过很多yacc的文章,但还来没有发现过中国谁用它真正实现了一个脚本引擎的。可见难度之不低。
@908971
资料都是收集别人的,我也学别人,一起学习。
@陈梓瀚(vczh)
牛,yacc可不是一般的轮子
都依赖于自己造的轮子,对别没有价值,除非别人愿意用你的轮子。否则也就落到自娱自乐了。
反正都是基于文件系统,直接写文件不行吗?没有与其他进程共享内存通讯,为什么要MappingFile呢?难道速度有优势?
似乎没有什么用,读书时候考的人比较多,工作后的人都很少在乎这些了,程序员不像其他行业,能力有多少,写几天代码就彻底暴露了,证书能够顶个球用。
@megax
我理解你所说的和你的建议,书里面也是如你所说的。CRT,MFC也是从来ASSERT后面,没有if,没有参数合法性检查。
但是这种形式给我带来过很多麻烦,请听听我的理解:
以strcpy举例(在这个函数上没有栽过跟头的程序员,不是个合格的程序员),strcpy(buf, NULL);将导致程序崩溃,为何?因为ASSERT后面没有带if,也就是没有对参数合法性进行校验。
我理解的,strcpy这样行为的后果是:把一个业务逻辑的bug,转成耦合了平台底层的bug。
1、strcpy(buf, NULL),逻辑上的bug应该是buf没有拷贝任何数据,如果作了参数检查,那么这个bug的最终表现形式是逻辑上的:buf没有出现应该出现的数据;
2、因为没有参数检查,程序崩溃了,那么这个bug就耦合上了平台的内存管理规则,内存访问违规了,程序崩溃是这个bug的表现,这种表现形式和逻辑上应该出现的结果有联系吗?没有;
3、检测与修正业务逻辑的bug的难度远远小于与平台耦合的bug,可以依赖于日志,模拟重现等许多方法。但是比如程序崩溃这样耦合了平台的bug,如果不是到了一定程度的程序员,让他去调查一个服务器运行几天down掉的原因,那将难于上青天。
4、若写服务器,你将体会到,偶尔业务逻辑执行不正确不是什么大事情,只是一个业务逻辑上的bug而已,真正的大事情是服务器时不时给你来个crash down。很多情况的发生都是因为参数错误不合法,到了ntdll或者其他系统dll里面崩掉了。
C/C++库里面,成千上万的函数,你需要一个个了解他们传递什么样的参数才是合法,要保证不犯错误,是不可能的,但是一旦犯错,它给你来一刀,可不是很好受,为什么如此?原因就是ASSERT后面没有if。
所以,吃过亏后,我一般都在参数的ASSERT后面,带上一个if,个人觉得很受用。
@陈梓瀚(vczh)
Debug会有ASSERT,也会有if
Release没有ASSERT,有if.
没有不同行为
@www.helpsoff.com.cn
程序以外,人生很多地方都需要与别人探讨,对于不合己见者,请不必太在怀,更没必要带着情绪和语气,摆出姿态。这样才能赢得更多的合作,我想我的这几句话还算中肯。