WTF » Passer-byB's blog » Programing



这是一张无法正常缩放的图片,因为目前主流的图像处理软件以及浏览器的图形缩放算法都是有问题的。包括photoshop,gimp等试用广泛的软件都不能正常将这张图缩放到50%%u4E00旦缩放到50%%u5F97到的将是一张全灰的图像。而这张图即使不放大,在不同角度观看也会有奇妙的效果。我是在这里找到的这个问题。文章中分析了原因,其中之一是:在将图片缩放50%%uFF0C有些软件会选取没单位4个像素之一为新的像素,这样在一个2*2的单元就缩放成了一个像素,从而实现缩放,但这显然是错误的。另外一些算法会根据4个点的平均色度灰度决定新的像素的色度灰度,但决定过程中采用的是线性变换。如,(4+8+12+16)/4=10。而在亮度上缩放应采用亮度的能量表示来缩放,也就是二次方。目前主要的错误都来源于此。有兴趣可以下载这个包,自己制作这种图片。并用自己的图片编辑器测试。


搜索引擎对动态页面不是很友好,像我的博客之前显示文章都是用article.php带查询方式,也就是形如article.php?a=12的方式。但是搜索引擎对后面的查询字段通常忽略,把所有article.php当作一个页面,因此多个页面无法被搜索引擎捕获。我们可以通过重写url将地址静态化,改成12.html等形式,这样浏览器就可以很容易的区分不同页面从而抓取。伪静态方法有很多,我这里用的是.htaccess方法,利用apache的rewrite模块进行,里面涉及到非常简单的正则表达式知识。这个方法主要是创建并编辑.htaccess文件。一、创建.htaccess因为我通常在linux下开发web因此没有无法生成.htaccess文件的困扰。对于windows用户,可以新建xx.htaccess然后在cmd里copy xx.htaccess .htaccess得到这个文件。这个文件可以用任意一款文本编辑器编辑。二、书写rewriterule这里首先打开.htaccess文件,然后输入如下文本:RewriteEngine OnRewriteBase [path]RewriteRule [from] [target]其中[path]是指从web根目录开始,要重定向的文件所在目录,比如本站,article.php在blog目录下因此[path]写成/blog。[from]是你希望用户在浏览器里输入的url形式,比如我这里希望用户输入 一些数字.html的形式,那么[from]写成^([d]+).html。这里的^表示目标串的开头,表示从开头匹配,一对圆括号的作用是今后引用它,而一对方括号的意思是将它包括的东西算作一组,后面的加好表示前面的一个或一组模式出现1次或以上次。因为.在正则表达式里有特殊含义,因此要加将其转义。[target]是要转向的文件,因此[target]在我这里是article.php?a=$1。这里的$1就是对前面的小括号的模式的引用,前面如果出现多个小括号就是匹配第一个,$2就是第二个,以此类推。值得注意的是,如果页面内大量链接以及图片的引用用的是相对路径形式,如x.jpg,需要保证重定向后目录层级不变,否则会造成链接失效,图片无法显示的问题。这个问题很容易理解,因为重定向发生在服务器端,因此浏览器并不清楚目前的目录到底在哪里比如在浏览器里输入地址www.domain.com/a/b/c.html并在服务器端指向www.domain.com/index.php?a=a&b=b&c=c文件,这是就会出现问题。原因是浏览器在查找相对路径x.jpg时,会在www.domain.com/a/b/目录下查找,而事实上并不存在这样一个目录。这个问题的另外一个解决办法是所有的链接都采用绝对路径形式,不过这样对今后网站转移和维护都会造成困扰。如果网站会频繁转移,又想用绝对路径,那就只能定义一个全局变量或者常量使其值为”http://www.domain.com/”这样,只要把这个变量在需要链接的位置的相对路径前输出即可。网站转移的时候只要修改这个全局变量。三、上传.htaccess文件书写好这个文件之后需要将这个文件上传到服务器。目前国外的linux主机几乎都支持这个功能,因此只要把这个文件传到想要作用的目录下即可。四、.htaccess的其他功能这个文件功能其实很强大,也可以自定义404错误等各种错误页面。网上这些资料很多。这段时间我会将站内几乎所有的链接都静态化,这可能会导致很多错误,因此只能在错误中前进了。


libevent是个事件驱动库,网上关于它的文章很多,这里就不再多说了。如果你搜到这篇东西,一定是想要在你的ubuntu10.10下面安装/使用它,或者说你遇到了问题。这个问题很可能就是你遇到了段错误。通过gdb调试后发现问题出在libevent中。然后你很无奈。其实问题不在libevent上,而在安装libevent的过程本身。我是采用源码的方式安装的libevent。http://monkey.org/~provos/libevent/在这里下载到你想要的版本后,转到你下载文件保存的目录,tar -xzvf 你下载到的文件名。然后进入解压出来的那个目录。之后./configure,然后make,sudo make install。顺利的话你就安装完成了,看起来很平常。但是当你使用它的时候就会出现问题。这很可能是段错误。问题的原因我现在就开始解释。ubuntu10.10默认会安装一个libevent1.4.2版本的libevent在你的系统里,这个版本的libevent在/usr/lib目录下有个libevent.so.2的文件。而你用源码安装的libevent的so文件保存在/usr/local/lib目录下,这样当你在用编译器选项-levent的时候,系统就在/usr/include,/usr/lib,/usr/local/lib三个目录下寻找libevent.so这样的文件作为连接时候用到的目标文件。问题就出在这里,系统首先找到的是/usr/lib/libevent.so.2这个文件而不是你安装的/usr/local/lib这个目录下这个版本对应的目标文件,于是连接产生的程序就会读取一段不应该读到的内存,于是bug就产生了。因此,在安装libevent之前,首先确保你的系统里是否已经安装了其它版本的libevent,如果发现有安装,那么果断卸载之。 更新:libevent的official site上的document说struct event需要分配到heap(堆区)。如果分配到stack,当临时变量神马的用多了会导致很多意想不到的问题,博主这两天就深受其害。


这个问题折腾了我有一个星期了,因为最近一直在搞有关磁盘的I/O的测试,因此需要绕过或者关闭VFS的cache直接对磁盘进行读写。Google过之后发现基本上想要关闭cache是不可能的,只有想办法绕过了。于是很自然的想到了write()和read()这两个东西,可是当时并没意识到buffer跟cache并不是一个东西。write()跟read()虽然叫直接I/O但事实上他们只是绕过了buffer,也就是说在读入跟输出的时候不进行任何的缓存,但VFS本身的cache仍然存在,VFS仍然会选择在合适的时候将cache的数据写入磁盘。 于是找了很多方法,有的是通过drop cache的方法,就是”echo 1 > /proc/sys/vm/drop_caches”这样的方法,不过这种方法只能清除一次cache,读写一次,很是麻烦。于是果断放弃了这种不靠谱的方法。 后来想到了APUE上没有提到的一个O_DIRECT flag(因为APUE讲的是UNIX编程,当然没必要照顾到GNU Linux特有的东西)。具体怎么用呢,下面就来说说。 首先在文件头需要定义 #define _GNU_SOURCE 然后,这个东西用在open()获得文件描述符时所填写的第二个参数,也就是open(path,flag,mode)的第二个参数。比如你要以写方式创建一个路径为”/home/user/test.test”新文件,并且要直接I/O绕过cache,就可以这样写: int fd=open(“/home/user/test.test”,O_WRONLY|O_CREAT|O_DIRECT,S_IRUSR|S_IWUSR); 之后在你需要read()或者write()的时候,传入的buffer的首地址,以及buffer的大小都必须跟文件系统的page size对齐。这个page size可以通过getpagesize()获得。memalign()可以用来得到这样一个buffer: int buffersize = getpagesize()*page_num; int pagesize=getpagesize(); char * buffer = memalign(pagesize, buffersize); 之后你就可以用这个buffer来read()或者write()了。如: read(fd,buffer,buffersize); 要注意的是,在2.4以前的kernel里,buffersize必须是页大小的整数倍,并且buffer指向的地址也必须是页大小的整数倍。用上面的简单计算就可以得到满足条件的buffer。之后的I/O便是完全绕过cache的direct I/O了。 PS:完成这个之后,周末就可以放心的回家了,很开心。


今天中午收到前天晚上在当当网定的书,当当的送书效率着实让我受惊若宠了一下。说来惭愧,三本书中两本是马上期中考试了的科目,因为觉着科目浮云,就连书都拖着到现在才买。当然,那本觊觎已久的APUE的到来还是让我兴奋了一下。今天早上自学完成OS之后还在愁上课没事干,下午这本圣经就突如其来的到手了。不过那700+页数的厚度还是很恐怖的。慢慢啃吧。啃完它再啃两本《UNIX网络编程》。言归正传,今天在逛M牛的博客的时候,发现了一个很好的算法题,正在感慨算法的精妙时,突然就在北邮的新oj发现了这么一道题,于是就做了。题目是说要求在内存1000K的条件下,完成记录一个10^6次方大小的数组的相同元素个数大于1%所有元素,并且按出现次数降序排列(出现次数相等则按元素从小到达排列)。这题的直观想法是,用一个数组记录每个值出现的次数,但题目中说每个数的范围是2*10^9,因此直接打消了我这个念头。1000K的内存甚至不足以记录所有10^6个数。因为这题明显改编自在M牛那看到的那道题,因此观察输入,将数组输入两遍,这就相当于我们只可以对原数组扫描两遍便得出结果。这里就要引出这个很牛逼的算法。第一遍扫描,我们用一张100大小的表记录某个元素的出现的次数,当这个表在扫描到某个元素时超过了100个记录时,则对表中的每个元素的出现次数减一,这样就能保证将表的元素数控制在100以下。当处理最后一个数时,无论是否超过100个元素,都将这个值添加到表中。这个第一遍找出的元素包含但不限于所有满足要求的结果。证明如下:反正,设总共有n个元素,且有一个x的出现次数p>=n/100。若x不在这个集合中,则必有在这个x之后又做了至少p次对所有出现次数减一的操作。因为每次操作减少100个元素,因此有减少了100p,而数组中总共有n个元素,且最后一个元素不会被去掉,因此100p<n,这与p>=n/100矛盾,得证。有了这样一个集合,我们就在第二遍输入的过程中简单记录在这个集合中的元素出现的次数,并且最后去掉所有不满足要求的元素(出现次数<1%,排序输出即可。因为这个表最大不超过100,因此是O(1),因此不超过1000K的内存限制。code: #include<stdio.h>#include<stdlib.h>struct NODE{ int num,count; NODE *next;};int main(){ int n,in; int total,flag; int i,j,k; NODE *p,*q,*r; NODE head,ans; while(scanf(“%d”,&n)!=EOF) { head.next=NULL; ans.next=NULL; total=0; for(i=0;i<n;i++) { scanf(“%d”,&in); p=head.next; flag=0; while(p) { if(p->num==in) { p->count++; flag=1; break; } p=p->next; } if(!flag&&total<100) { p=new NODE; p->num=in; p->count=1; p->next=head.next; head.next=p; total++; } else if(!flag) { p=new NODE; p->num=in; p->count=1; […]


0 简介Perl是Practical Extraction and Report Language的缩写,也有人戏称它为Pathological Eclectic Rubbish Lister(反常、折衷的垃圾陈列器);它是由Larry Wall开发并维护的;Perl的目标是帮助Unix用户完成一些常见任务,而这些常见任务对于Shell又太复杂;Perl也可以作为一种WEB开发中的CGI语言;Perl的许多特性来源于C语言;Perl是一种脚本语言,由固定的解释器运行;Perl一般位于/usr/local/bin/perl或者/usr/bin/perl;Perl可以免费用FTP获取,解压并编译到目标目录;每个Perl脚本都是由#!/usr/local/bin/perl(这是Perl所在的目录)开头的;Perl的简单语句以分号(;)结束;在Perl脚本里,#号后面的是注释内容;Perl运行时需要有x权限,由命令$chmod +x filename实现;1 数据类型Perl的数据类型有三种:标量,列表数组和关联数组1.0 标量标量就是单一的,非矢量非数组的数据;Perl中的标量是以美元符号$和一个字母标识的,并且其后可以是若干个字幕,数字和下划线;Perl变量名区分大小写;Perl中的标量无论初始化还是引用都要有$;Perl的标量分为数字跟字符串两类;Perl的所有数值都由浮点型表示,形如1.3e5;Perl的字符串类型的取值来自全部ASCII表,字符串的长度”无内置限制”;Perl的字符串变量分为单引号字符串和双引号字符串;单引号字符串取消两个单引号之间所有内容的特殊含义,\和’例外,当在单引号字符串内需要表示时需要输入\在单引号字符串内需要表示单引号时需要用’;Perl的双引号字符串内支持转义字符,由开头,如n表示换行,t表示一个制表符table;Perl支持一般的算数运算,如 + – * / ** %;Perl支持逻辑运算,如 < > = == != ;Perl支持字符串运算,如 . x eq ne lt gt le ge cmp;Perl在对字符串进行数值运算时,会将字符串转换成十进制浮点数进行运算,如果字符串的开头或结尾有非数字,则将其去掉;Perl对数值进行字符串操作的时候会将上面的过程反过来进行;Perl同样支持三元运算符’ ? : ‘;1.1 列表数组列表数组的命名规则同标量相同,并以@符号开头;列表数组是圆括号内由逗号隔开的一系列标量;列表数组内支持..运算符,这个运算符的意思是生成一个从..左边到..右边的一些列连续值,如果不能生成,则生成空的列表数组;列表数组可以用=直接赋值;如果列表数组赋值时如果左右两个数组元素数不同,则在右边元素多时截去多余元素,左边元素多时多余的量被赋值undef(未定义);列表数组可以用@变量名[索引]的方式单独所以其中的每个元素;列表数组支持push()和pop()操作,结果同一个堆栈的同名操作;shift()和unshift()操作跟上面两个操作结果相似,其操作目标是列表数组左边元素而非右侧;reverse()运算符可以将列表数组内元素反向后的结果返回并保持原列表数组不变;sort()是排序运算符,返回按ASCII字符串字典顺序排序的列表数组,并保持原列表数组不变;chop()操作跟名字一样,去掉最后一个元素;1.2 关联数组关联数组的命名规则跟标量相同,以%%u5F00头;关联数组与列表数组类似,区别是其元素的索引可以是非数值,并且可以自定义;这些索引值成为关键字,可以方便的实现哈希散列;关联数组内的元素没有特定顺序,它可以是任意的;关联数组%array可以用$array{$key}引用;keys()操作生成由关联数组中所有关键字组成的列表数组,可用foreach(流控部分会讲到)遍历;在标量环境里keys()返回的是关联数组中名值对的个数;values()操作返回由关联数组中值组成的列表数组;each()返回关联数组中的一个名值对,连续使用则可遍历关联数组中的所有名值对,对数组赋值后将返回初始位置;delete()操作是用于删除名值对的;


这个是这学期微机原理的大作业,汇编程序编写个计时器。这学期一直没好好上课,不仅不好好上,还逃课,罪孽罪孽。连大作业都是截止日期写完的,好在东拼西凑是弄出这么个东西。里面涉及到jmp时near不够用的情况,方便起见就做了中间跳跃。这是第一次写汇编程序,可能是高级语言用多了,感觉汇编的结构性实在是差,或者说汇编语言根本就没什么结构性。源码及程序:点击下载


总得写点什么,不能总让这个Programing空着。我的WEB程序是自学的,学习不系统,也不专业,轻拍。从这个学期开始,发现身边好多同学在看有关WEB的书,这里就简单写一下应该怎样学WEB。我对WEB程序的理解很简单,就是生成HTML代码,无论静态网站还是动态网站。因此学习WEB首先要掌握基本的HTML。HTML会一些就好,首先个人认为HTML各种元素以及他们的属性一次性记不住,其次有些书介绍元素和属性在今天的WEB程序里已经很少用到,随着样式跟内容的分离,HTML已经失去了控制表现形式的义务,内容表现更多是交给CSS处理。刚提到了CSS,我是在学习过服务端脚本以及客户端脚本之后才接触的,不过我发现这个东西比较适合安排在学习HTML之后,有了CSS,HTML就基本算学会了WEB的表现部分,可以实现页面的布局以及表现。比较早接触CSS的另一个原因是,CSS学起来比较简单,本身就是个负责控制HTML表现的表,没啥具体语法要求。这样不至于过早对学习失去兴趣。之后我建议开始接触服务端语言,PHP或者JSP等。选择一门自己适合的服务端语言。我个人比较喜欢C风格的语言,因此选择了PHP。PHP在WEB中的作用就是生成HTML代码。一个PHP程序通过处理数据逻辑,并将数据添到HTML,从而中生成我们看到的代码。这就是服务端语言的作用。接着可以开始看javascript。Javascript有在客户端控制HTML的能力,因此适合处理一些不需要服务器参与的简单数据逻辑寻算。另外好多无刷新更新页面内容的功能也是通过Javascript控制的。因此Javascript肩负着使页面有更好的页面体验的使命。Javascript也是Ajax技术的核心,比如人人网上可以无刷新浏览照片,无刷新删除新鲜事,无刷新提交留言等。基本学习WEB就是这么个顺序。这些算是基础知识。更深层次的学习,比如mvc架构,如何提高页面的可用性有效性这些可以在开发中慢慢体会。


昨天比较受挫,google adsense申请第二次失败了。上网查原因,各种说法,比较可信的是我的域名注册时间不足6个月,而这项政策是google针对中国,印度等地区的。我的域名注册连6天还不到呢,不给我过也能理解。之后晚上又去看了阿里妈妈,觉得那种东西不靠谱,也没多少收入,就放弃了。于是我决定继续完善页面功能,第一步就是做了很久就想做的RSS订阅。RSS用的是xml,<channel><item>两个标签以及其子标签会用了就可以很方便的生成RSS FEED。<channel>主要用来说明这个FEED的基本情况,如名称<title>地址<link>描述<description>等。<item>用来表示一篇篇的文章,<title>表示标题,<link>原文地址,<description>用来描述文章,这三者为必须,其余的有可选的<author><pubDate>等.熟悉xml就可以很方便的创建自己的RSS FEED,值得注意的是,RSS FEED可以是动态文件,*.asp,*.php都是可以的.之后发布到网上,叫人订阅就ok了。另外欢迎订阅本站FEED,页面右侧就有。订阅之后可以无须登录本站的情况下,查看那更新。更重要的是,用RSS阅读确实方便,您可以添加很多关注的网站,这样就不用每天打开很多网站查看更新了。


今天用smarty帮谷歌(人人帐号)同学写了个东西,应该是什么机构的测试吧。总体感觉用smarty确实比之前的开发模式更方便。这也坚定了我以后自己构建smarty思想模板的决心。smarty的目的是实现前后台分离。因为在正式的web开发场合下,多数采用多人开发模式,这就要求分工明确,才能保证开发效率及质量。我曾尝试过按模块分工,这种方式比较适合各模块界限鲜明,工作模式简单的开发,个人认为对于RIA(Rich Internet Application)横行的今天,这种开发模式几本没有生存空间。除非各开发者之间默契超强,或者这次开发只由一人完成。更理想的情况是,按照前后台分工,对于后台再具体细分模块。因为大多数的web开发团队里,各个成员要么是美工很强,而对后台程序感觉较差,或者是后台程序能力很强而页面美工做不好(也许开发者自己认为页面很美观,比如我。而事实上开发者的审美观不能很好的满足用户)。Smarty就是适合这种分工方式的模板。Smarty不是一种MVC架构。在Smarty里,页面美工人员可以专注于页面布局,书写纯html代码,在需要数据处用smarty默认的或个人配置的定界符标识动态变量。当然多数情况下,html是很难预测页面具体由多少个样式重复的不同动态内容,因此Smarty在前端提供了foreach,for,if等流控关键字。事实上,前端开发者也只需用到如上的几个关键字。其余的完全可以交由后台程序员在php文件中对形如{$xx}的变量进行赋值等操作。事实上,如果后台开发着有良好的前端布局能力,也完全可以参与到前台布局中,只需要对前端标定的变量进行赋值即可。但这不符合前后台分离开发的根本需求,因此不推荐。不过这个事实说明,smarty开发是相对灵活的。而对于后台php人员,其程序量并没有本质变化,后台人员仅需要对smarty提供的smarty类的成员进行简单理解,并习惯于用smarty->assign方式对变量赋值即可。最后一点,smarty是基于php的。

CodePhoto.WTF © 2025