2014年3月

现在有很多的项目,对计数器的实现甚是随意,比如在实现网站文章点击数的时候,是这么设计数据表的,如:”article_id, menu_id, article_name, article_content, article_author, article_view......在article_view中记录该文章的浏览量。诈一看似乎没有问题。对于小站,比如本博客,就是这么做的,因为小菜的博客难道会涉及并发问题吗?答案显而易见,一天没多少IP,而且以后不会很大。
言归正传,对文章资讯类为主的项目,在浏览一个页面的时候不但要进行大量的查(查询上文的记录,已经所属分类的名字、热门文章资讯评论、TAG等),还要进行写操作(更新浏览数点击数)。把文章的详细内容和计数器放在一张表尽管对开发很方便,但是会造成数据库的压力过大(不然为什么大项目都要分库分表呢)。
那么,分两张表存放就好了么?一张表存文章详细信息,另一张表单独存计数器。

CREATE TABLE `article_view`(
    `article_id` int(11) NOT NULL,
    `view` int(11) NOT NULL,
    PRIMARY KEY (`article_id`)
)ENGINE=InnoDB;

这种方式,虽然分担了文章表的压力,但是每当有一个进程请求更新的时候,都会产生全局的互斥锁,只能串行,不能并行。在高并发下会有较长的等待时间。
另一种比较好的办法是对每一个文章的计数器不是一行,而是多行,比如吧,一百行。每次随机更新其中一行,该文章的浏览数就是所有行的和。

CREATE TABLE `article_view`(
    `article_id` int(11) NOT NULL,
    `pond` tinyint(4) NOT NULL COMMENT '池子,就是用来随机用的',
    `view` int(11) NOT NULL,
    PRIMARY KEY (`article_id`, `pond`)
)ENGINE=InnoDB;

小访问量的随机池子100个肯定多了,三五个足矣。每次访问的时候,随机一个数字(1-100)作为pond,如何该pond存在则更新view+1,否则插入,view=1。借助DUPLICATE KEY,不然在程序里是实现得先SELECT,判断一下再INSERT或者UPDATE。

INSERT INTO `article_view` (`article_id`, `pond`, `view`) VALUES (`123`, RAND()*100, 1) ON DUPLICATE KEY UPDATE `view`=`view`+1

获取指定文章的总访问量的时候:

SELECT SUM(`view`) FROM `article_view` WHERE `article_id`='123'

Ps:凡事都是双刃剑。为了更快的读我们通常要牺牲一些东西。在读比较多的表要加快读的速度,在写较多的表要加快写的速度。各自权衡。在加快读的速度的时候,我们牺牲的并不仅仅是写的性能,还有开发成本,开发变的更复杂,维护成本等。所以并不是读的速度越快越好,需要找一个平衡点。

注:这里仅仅是Mysql方面,有人会说高并发下你这是直接读写Mysql啦,项目的瓶颈本来就在数据库啦。。。其实。。。这里只是说Mysql的表怎么去设计而已。你完全可以在这个地方用队列去写表,你也可以把计数器在内存中保存,一直来累加,1个小时持久化一次。你也可以去用号称每秒读写十万次的Redis。

版本1.2.0改动日志:
1、前端框架BootStrap2.0升级为3.0.3。
2、布局由全屏显示变更为居中显示。
3、将评论用户提交的URL不转换为链接。
4、将错误页面统一为BootStrap布局
5、删除多个CSS和JS,提升加载速度。
6、界面美化
7、添加TAG随即显示

版本1.2.0:发布日期:2014-05-27 下载地址:https://github.com/lixuancn/LX_Blog/tree/master

版本1.0.0:发布日期:2014-03-17 下载地址:http://www.lanecn.com/themes/download/blog_1.0.0.rar

环境:PHP+Mysql

前端:bootstrap

说明:解压后是源码文件夹和数据库的MySQL文件。

数据库配置信息请在config/develop/cloud.conf.php和config/online/cloud.conf.php修改。

URL配置请在config/develop/sys.conf.php和config/online/sys.conf.php

使用请保留鄙人的友情链接。谢谢~

欢迎指正BUG。

因时间关系,做的比较粗糙。细节尚未完善。

可直接跟贴回复。每天都会看的。

问题请直接在下方留言,邮件和论坛看的不及时。留言请注明邮件。谢谢~

本文前提是安装好Virtual4.3。在Fedora下如何安装请点击http://www.lanecn.com/article/main/aid-9查看。
打开软件,点击新建。输入一个名字,随便写,自己能认就OK。按照系统默认的选项一直下一步。一直创建完成。选中创建的项目后点击上方的显示。选择一个ISO镜像文件。(XP,WIN7,老毛桃,深度,雨林木风等)。
现在虚拟机就开始开机了。
安装和正常是一样的。
本文主要说遇到如下错误:
UIDE,01-15-2008 80-MB cache,CD/DVD name is mscd001
IDE1 controller at IO address Fgooh ,chip I.D.1002438ch
IDE2 controller at IO address Fbooh ,chip I.D.10024380h
IDE2 secondary-slave disk is WDC WD 1600AAjs-22psao,ata-133
CD:IDE1 primary-master, teclast DHB16H,ATA-33.

解决方案:
1、对虚拟磁盘分区。
2、进入winPE。
3、GHOST。
4、一般下载的IOS镜像里有GHO文件。可以直接用来GHOST.
从PE安装就不会有上面的提示。

由于我的Ubuntu实在用这不爽,作为Linux新手我完全不能应对Ubuntu的各种报错,比如今天图形界面的关机按钮没有了,明天图形界面的时间没有了,后天图形界面的输入法不显示了。之前用过几天的Fedora,感觉界面比较炫。
在Fedora 20 安装VirtualBox的时候发生了些小意外。
第一步、下载Vbox。上官网,下对应自己系统的版本。

sudo rpm -i VirtualBox-4.3-4.3.8_92456_fedora18-1.i686.rpm

然后。让我头疼的事情来了。
警告:VirtualBox-4.3-4.3.8_92456_fedora18-1.i686.rpm: 头V4 DSA/SHA1 Signature, 密钥 ID 98ab5139: NOKEY
错误:依赖检测失败:
	libGL.so.1 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libQtCore.so.4 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libQtGui.so.4 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libQtNetwork.so.4 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libQtOpenGL.so.4 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libSDL-1.2.so.0 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libX11.so.6 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libXcursor.so.1 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libXext.so.6 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libXinerama.so.1 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libXmu.so.6 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libXt.so.6 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libasound.so.2 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libc.so.6 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libc.so.6(GLIBC_2.0) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libc.so.6(GLIBC_2.1) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libc.so.6(GLIBC_2.1.1) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libc.so.6(GLIBC_2.1.2) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libc.so.6(GLIBC_2.1.3) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libc.so.6(GLIBC_2.15) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libc.so.6(GLIBC_2.2) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libc.so.6(GLIBC_2.2.3) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libc.so.6(GLIBC_2.3) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libc.so.6(GLIBC_2.3.2) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libc.so.6(GLIBC_2.4) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libcrypt.so.1 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libcrypt.so.1(GLIBC_2.0) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libcrypto.so.10 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libcrypto.so.10(libcrypto.so.10) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libcurl.so.4 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libdevmapper.so.1.02 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libdevmapper.so.1.02(Base) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libdl.so.2 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libdl.so.2(GLIBC_2.0) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libdl.so.2(GLIBC_2.1) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libgcc_s.so.1 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libgcc_s.so.1(GCC_3.0) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libgcc_s.so.1(GLIBC_2.0) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libm.so.6 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libm.so.6(GLIBC_2.0) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libm.so.6(GLIBC_2.1) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libpng15.so.15 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libpng15.so.15(PNG15_0) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libpthread.so.0 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libpthread.so.0(GLIBC_2.0) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libpthread.so.0(GLIBC_2.1) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libpthread.so.0(GLIBC_2.2) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libpthread.so.0(GLIBC_2.3.2) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libpthread.so.0(GLIBC_2.3.3) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libpthread.so.0(GLIBC_2.3.4) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libpython2.7.so.1.0 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	librt.so.1 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	librt.so.1(GLIBC_2.2) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libssl.so.10 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libssl.so.10(libssl.so.10) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libstdc++.so.6 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libstdc++.so.6(CXXABI_1.3) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libstdc++.so.6(CXXABI_1.3.1) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libstdc++.so.6(GLIBCXX_3.4) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libstdc++.so.6(GLIBCXX_3.4.11) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libstdc++.so.6(GLIBCXX_3.4.15) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libstdc++.so.6(GLIBCXX_3.4.9) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libvpx.so.1 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libxml2.so.2 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libxml2.so.2(LIBXML2_2.4.30) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libxml2.so.2(LIBXML2_2.6.0) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libxml2.so.2(LIBXML2_2.6.8) 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要
	libz.so.1 被 VirtualBox-4.3-4.3.8_92456_fedora18-1.i686 需要

我去年买了个表啊!!!这么多的库文件却是难道要我一个一个手打安装????
各种Baidu\Google。然后。被我发现了一个好发方法。。
双击打开!!
然后他会自己安装这些关联关系的软件包。

是不是要喷?开头我就说了很狗血的~

-------------我是分割线------------------------

安装完成,打开。报错
不能为虚拟电脑 XP 打开一个新任务.
The virtual machine 'XP' has terminated unexpectedly during startup with exit code 1.



RTR3InitEx failed with rc=-1912 (rc=-1912)

The VirtualBox kernel modules do not match this version of VirtualBox. The installation of VirtualBox was apparently not successful. Executing

'/etc/init.d/vboxdrv setup'

may correct this. Make sure that you do not mix the OSE version and the PUEL version of VirtualBox.

按照提示输入/etc/init.d/vboxdrv setup都提示OK了也没有用啊。
搜索的解决方法
sudo yum install kernel-devel
sudo yum install gcc
sudo /etc/init.d/vboxdrv setup

再次打开,还是不可以,报同样的错。

继续搜索~
来了个狠的,更新系统
sudo yum -y update
sudo /etc/init.d/vboxdrv setup

Stopping VirtualBox kernel modules                         [  OK  ]
Uninstalling old VirtualBox DKMS kernel modules            [  OK  ]
Removing old VirtualBox kernel module                      [  OK  ]
Trying to register the VirtualBox kernel modules using DKMS[  OK  ]
Starting VirtualBox kernel modules                         [  OK  ]
好了。可以了哦

题目一:

<?php
echo -10%3;
?>

答案:-1。
考查:优先级。
因为-的优先级比%求余的优先级低,也就是-(10%3)。

题目二:

print (int)pow(2,32);

答案:0

题目三:

//file1.php
<?php
$a = '123';
?>
//file2.php
<?php
echo include('file1.php');
?>

答案:1.
考查:返回值。
因include()也是一个函数,有返回值。在成功时返回1,失败时返回错误信息。如果被包含的文件有return,则inculde()成功时返回该文件的返回值。

题目四:

<?php
$count = 5;
function get_count() {
    static $count = 0;
    return $count++;
}
++$count;
get_count();
echo get_count();
?>

答案:1.
考查:static和++。
因static $count,所以只在第一次调用get_count的时候对$count赋值为0,第二次再进来这个函数,则不会第二次赋值。其次就是return $count++和return ++$count了,前者先返回,后者先++再返回。

题目五:

<?php
$arr = array(0 =>1,'aa' => 2,3,4);
foreach($arr as $key => $val){
    print($key == 'aa' ? 5 : $val);
}
?>

答案:5534.
考查:类型转换。
因遍历数组第一次的时候,$key和aa的比较实际就是0和aa的比较,一个是int一个是string,这个时候会转换类型,将字符串转换为数字再与数字比较。所以0=='aa'就是0==0,所以为true,也就是输出5。虽然PHP是若类型语言,但是人家也有类型的好吗。

题目六:

<?php
echo count (false);
$a = count ("567")  + count(null) + count(false);
echo $a;
?>

答案:2.
考查:count的用法。
因count()的官方解释“If the parameter is not an array or not an object with implemented Countable interface, 1 will be returned.”.意思是说,如果不是数组或者对象的其他类型,返回1.那么这个值应该就是1+0+1了(boolen人家也是一个类型,虽然是讨厌的false)。NULL的意思是没有值,难道在计数函数中还能有1?

题目七:

<?php
$arr = array(1,2,3);
foreach($arr as &$val) {
    $val += $val % 2 ? $val++ : $val--;
}
$val = 0;
print(join('',$arr));
?>

答案:330。
考查:++和&。
因foreach结束后的数组应该是array(3,3,7);最后给第三个元素赋值为0,所以就是330了。其中注意的是&,如果有&则是对原变量操作,如果没有,则是先生成一个新变量,然后给这个变量复制,最后操作的是这个新变量。

题目八:

<?php
echo intval((0.1+0.7)*10);
?>

答案:7。
考查:浮点数的概念。
因0.1+0.7=0.8 0.8*10=8 所以转换成整数后还是8?错!因为0.1+0.7=0.8是浮点数,0.8*10在数学计算中是正整数8,可是在计算机中它仍然是浮点数8,什么叫浮点数8?每一个看起来像整数的浮点数,其实都不是整数,比如这个8,它其实只是7.9999循环,无限接近于8,转换成整数会舍弃小数部分,就是7喽。

题目九:

<?php
ini_set('display_errors',0);
$arr = array(1=>1,3=>3);
$i = 2;
$a = 'test' . isset($arr[$i]) ? $arr[$i] : $i;
请问$a的值是什么?
A、test B、NULL C、2 D、test2
?>

答案:B。
考查:优先级。
因“."的优先级高于三元运算符"?:"。所以程序其实报错了。会说$arr的索引2不存在。

题目十:

<?php
$a = 3;
$b = 5;
if($a = 5 || $b = 7) {
    $a++;
    $b++;
}
echo $a . " " . $b;
?>
A、6 8  B、6 6  C、2 6  D、1 6  E、4 6

答案:D。
考查:优先级,基础概念,++。
因“="的优先级低于“||”,所以先逻辑判断再赋值。也就是($a = (5 || $b = 7))。所以,最后其实给a赋值了,$a等于1.

题目十一:

<?php
$x = 2;
echo $x == 2 ? '我' : $x == 1 ? '你' : '它';
?>
输出的结果是()
A、我
B、你
C、它
D、syntax error

答案:B。
考查:优先级。
因“=="的优先级高于“?:”。我已经不想说为什么了,整理一下这种东西,我感觉要疯了,除了笔试题外估计也不会遇到了吧。