2011 年 12 月

浏览模式: 标准 | 列表 | 图文
转:php变量连接函数短路操作($f) && f(),$condition && function()用法意思解释说明

转:php变量连接函数短路操作($f) && f(),$condition && function()用法意思解释说明

其实我是真想自己写这一段内容的,只是后来找了找手册,居然不知道在哪一章了。
短路操作符,很容易让人误解是if条件中的 && 或者 ||,但实在不知道从何说起(至于是不是叫短路操作符,我也记不清了,先这么命名吧)
其实这个玩意大家都见过,只是大家都忽略了。想起很久很久以前,所有的参考书上有一段连接数据库的代码:
$conn = mysql_connect(localhost,root,123456) or die('could not connect db');
这段代码,就是一个很简单的例子。
如果能够连接上,就返回$conn,否则直接输出。。。。无非就是将||换成了 or,于是很多人就不认识了罢了。
然后,国内用的最多的这种代码的是某一个论坛,在他们的代码里大量充斥了这种操作符,很多人在第一次看他们的源码时都会比较郁闷。。。这个论坛叫phpwind。
好了,我不多说了,上原文吧:http://feihu.cd00.cn/itweb/index.php/php-duanlu-condition-function

什么是php短路操作,先看下面代码
($f) && f(); 或者
$condition && function();
这是什么用法
短路操作,什么意思呢

如果$f为真,就执行f()函数调用
如果$condition为真,就执行function()函数调用
if ($f) {
f();
}

另找了篇文章来详细说明之
mysql_query($sql) or die(’Execute failed!’);
!file_exists($cache_file) && @update_cache($id);

这两句很像是条件语句,但是准确的说,他们是利用了短路运算符的运算特点来实现的条件语句:
or、||、and、&& 都是短路运算符
&&(and)运算符检查第一个表达式是否返回“flase”,如果是“false”则结束语句并返回“false”,否则检查第二个表达式。
or(||)运算符检查第一个表达式是否返回“true”,如果是“true”则结束语句并返回“true”,否则检查第二个表达式。
该用法正是利用了短路运算符这种特性实现了条件的判断和执行

----------
再看这一篇:http://biancheng.dnbcw.info/perl/241992.html

和C类似,Perl提供 &&(逻辑 AND)和 ||(逻辑 OR)操作符。它们从左向右计算( && 比 || 的优先级稍稍高一点点),测试语句的真假。这些操作符被认为是短路操作符,因为它们是通过计算尽可能少的操作数来判断语句的真假。例如,如果一个 && 操作符的左操作数是假,那么它永远不会计算右操作数,因为操作符的结果就是假,不管右操作数的值是什么。

例子 名称 结果
$a && $b And 如果$a为假则为$a,否则$b
$a || $b Or 如果$a为真则为$a,否则$b

这样的短路不仅节约时间,而且还常常用于控制计算的流向。比如,一个经常出现的Perl程序的俗语是:

open(FILE, "somefile") || die "Can't open somefile: $!\n";

在这个例子里,Perl 首先计算 open 函数,如果值是真(somefile 被成功打开),die 函数的执行就不必要了,因此忽略。你可以这么读这句文本“打开文件,要不然就去死!”。

&& 和 || 操作符和 C 不同的是,它们不返回 0 或 1,而是返回最后计算的值。如果是 ||,这个特性好就好在你可以从一系列标量数值中选出第一个为真的值。所以,一个移植性相当好的寻找用户的家目录的方法可能是:

$home = $ENV{HOME}
|| $ENV{LOGDIR}
|| (getpwuid($<)) [7]
|| die "You're homeless!\n";

另一方面,因为左参数总是在标量环境里计算,所以你不能把 || 用于在两个集群之间选择其一进行赋值:

@a = @b || @c;      # 这样可不对
@a = scalar(@b) || @c; # 上面那句实际上是这个意思,@a 里只有 @b 最后的元素
@a = @b ? @b : @c; # 这个是对的

Perl 还提供优先级比较低的 and 和 or 操作符,这样程序的可读性更好而且不会强迫你在列表操作符上使用圆括弧。它们也是短路的。

转:lua 5.2 的 _ENV

转:lua 5.2 的 _ENV

这篇文章是云风的博客上的文章,知道云风是在做游戏,也知道他一直在做lua、C的开发。
我也是最近才刚刚开始看lua,主要是看了一眼之后就发现,原来lua,连函数的写法,对象的格式(tabledata),几乎都一样。所以,在开始关注着。
今天看到这篇文章,转贴是因为,看到云风写的这段代码:

function foobar(env)
return setfenv(
function()
local ret = {}
function ret.foo()
...
end
function ret.bar()
...
end
return ret
end , env) ()
end

超级象javascipt,比如可以写成:

function foobar(env){
return setfenf(function(){
var ret = {};
ret.foo = function(){};
ret.bar = function(){};
return ret;
},env)();
}

感觉有点超象。。。
上原文了。地址:http://blog.codingnow.com/2011/12/lua_52_env.html

lua 5.2 正式发布了,对于 lua 语言本身的修改,重中之重就是对 environment 这个概念的修改。

可以说, 5.1 以前的 environment 已经没有了。environment 对于制造一个安全的沙盒(或是实现 DSL)是一个很重要的语言特性,我以前很喜欢使用,但也很容易用错。这次的修改我认为是一个谨慎的决定,并使得 lua 语言更为精简和严谨了。

我这样理解 5.2 中的 environment 。本质上,lua 取消了原有意义上的 environment 。所以我们可以看到 C Function 不再有环境了。function 、在 lua 中称为 closure ,仅仅只是函数体和 upvalue 的联合体。这简化了 lua 语言本身。全局变量实际上只是一个语法糖,编译时再前面加上了 _ENV. 的前缀。这样,从 load 开始,第一个 chunk 就被加上了 _ENV 这个 upvalue ,然后依次传递下去。

这个设计基本可以取代以前使用 getfenv/setfenv 改变函数环境的方法。但是又不完全等价。总体来说,增加了一些限制,但不太容易写出 bug 的代码了。

比如说,现在想给返回一个独立环境的函数,可以这样写:

function foobar(env)     local _ENV = env     return function() ... end end

而以前大约是这样:

function foobar(env)     return setfenv(function() ...  end, env) end

这不太看得出好坏,但是如果是一组函数,就有区别了。5.2 中是这样:

function foobar(env)     local _ENV = env     local ret = {}     function ret.foo()         ...          end     function ret.bar()         ...     end     return ret end

5.1 的等价代码大约是这样:

function foobar(env)     local old = getfenv()     setfenv(1,env)     local ret = {}     function ret.foo()         ...          end     function ret.bar()         ...     end     setfenv(1,old)     return ret end

或者这样更函数式一点:

function foobar(env)     return setfenv(     function()         local ret = {}         function ret.foo()             ...              end         function ret.bar()             ...         end         return ret     end , env) () end

getfenv/setfenv 更灵活,却更容易出错。

对于制作沙盒来说,我感觉 lua 5.2 会更为鼓励使用 load 这种运行时的编译行为。即一定程度上的鼓励元编程。(因为取消了 setfenv ,所以给了 load 显式的参数来制定给 chunk 一个新的环境)

btw, 这个语言设计变更的同时也增强了函数式编程的性能。因为 lua 现在可以更方便的合并那些有相同 upvalue 的 closure 了。(从前除了 upvalue 还有 environment ,合并行为更为复杂)


12 月 30 日补充:

如果非要类似 setfenv 的功能, 修改一组函数的 _ENV 大概需要这样做了:

function getfuncs()   local _ENV = _ENV   local ret = {}   function ret.foo()     ...   end   function ret.setfenv(env)     _ENV = env   end   return ret  end
瞎折腾:程序员什么时候效率最高

瞎折腾:程序员什么时候效率最高

有人说:
"有句还挺受欢迎的话是,程序员就是把咖啡变成代码的机器。随便问一个程序员什么时候效率最高,很有可能他们会说大多是深夜的时候(中文)。 有些早点,有些晚点。常见的是:在凌晨4点起床,赶在吵闹的一天开始前完成一些工作。另外一些喜欢在凌晨4点睡觉。这种做法的目的是避免干扰。但是你可以 锁上门啊,为什么夜晚这么特别呢?swizec 的博主认为可以归结为三件事:员工的时间表、疲惫的大脑和明亮的电脑屏幕。"

其实想想不完全是这样,白天的时候在单位各种各样的事情,都有可能会导致写代码的时候被打断,这种打断其实很影响写代码,思路一断,很可能半小时一小时都不会恢复。晚上没人,外面也很安静,虽然说真的是避免干扰,但其实晚上和清晨人的大脑好象很容易集中(所以我们小时候背书一般都在凌晨,当然也有深夜)。【传说,屙扁扁的时候人的记忆力是最好的,所以那个时候看书其实很容易记得牢,无科学依据,纯粹说说】。

果然有中文版的(上面斜体字中的中文版,我复制过来了,但不复制图,要看原文请移步:http://blog.jobbole.com/10797/)

有句还挺受欢迎的话是,程序员就是把咖啡变成代码的机器。

果然,随便问一个程序员什么时候效率最高,很有可能他们会说大多是深夜的时候。有些早点,有些晚点。常见的是:在凌晨4点起床,赶在吵闹的一天开始前完成一些工作。另外一些喜欢在凌晨4点睡觉。这种做法的目的是避免干扰。但是你可以锁上门啊,为什么夜晚这么特别呢?

我认为可以归结为三件事:员工的时间表、疲惫的大脑和明亮的电脑屏幕。

员工的时间表

Paul Graham在2009年写过关于员工的时间表的问题 —— 基本上,在世界上有两种类型的时间表。传统管理者的时间表是分散地切割成小时和一个个十分钟的方式绩效,通常是按一个小时的价值给你报酬。

另一种,叫做员工的时间表——针对我们这些程序员。工作于大型虚拟系统时,需要把所有涉及的事都记在脑子里——有人曾经比喻这就像用昂贵的水晶建造房子,一旦有人打扰,房子就一股脑塌落并碎成一片。

这就是为什么当有人打断程序员的思路时,他们那么恼火。

由于这种巨大的精力投入,使得我们无法简单地开始工作,直到我们能连续几小时不被分散注意力才行。刚在脑中构建了整个模型,结果半小时后就毁了可不值得。

事实上,跟很多员工交谈后你会发现,他们感觉根本不能在白天完成任何工作。接连不断地被打扰、关注重要的事物和回复邮件都不能让他们安心工作。所以他们选择在别人睡觉的深夜来完成大部分的工作。

疲惫的大脑

就算是程序员,晚上也应该睡觉。我们不是超人。也会感到白天更机敏。

那为什么我们要在大脑想睡觉的时候做最复杂的工作,而在大脑最敏锐和灵活的时候做简单的任务呢?

与巴尔默峰值类似,疲劳让我们更易集中精力,因为当你的大脑疲劳时,它就必须集中精力!没有多余的脑力让你不集中精力。(《“10倍效率”程序员/开发人员的习惯》第5点:集中精力)

我似乎在喝茶过多或不合适的时间喝能量饮料后完成的工作最少。这些让我很活跃,一会儿查看Twitter,一会儿看看Hacker News,我似乎一直在到处浏览。

你应该在想我能很好地工作——这么有精力,这么有脑力。但是相反,我一直在阻绊自己因为我不能集中精力超过两秒。

然而,当我微感疲倦时,我就能坐下来编码了。用有点疲劳的大脑,我能一小时又一小时地编码,甚至都不想查看Twitter或者FaceBook。就好像互联网不存在了。

我觉得这适用于大多数程序员。我们有太多的精力去完成80%的工作——面对现实吧,一个好的算法,需要用10倍的代码量来营造使用它的环境。即使你做的是最高级的机器学习(或者是其他的),很多工作也仅仅只是清理数据和将结果以友好的方式呈现出来。

当你的大脑并不是竭尽全力地工作时,它就会找其他的事做。疲劳使你愚钝,从而使你只能顾及手头上的工作。

明亮的电脑屏幕

这条非常简单。在夜晚一直盯着明亮的光源并且使你的睡眠周期延后。你直到凌晨3点才感到疲倦。然后中午11点起床,当夜晚来临时你并不感到疲劳,因为,呵呵,你中午11点才起床!

经过足够多的反复,本质上是把你带到了不同的时区。更有趣的是,它会保持相对稳定,一旦你进入凌晨3、4点睡觉的节奏中,你就会一直保持那样。

结语

综上所述,程序员晚上工作是因为没人强制规定你必须什么时候停止工作,这可以给你更轻松的方式,你的大脑不再一直寻找分心的事并且明亮的屏幕使你保持清醒。
转:mysql语句最大长度

转:mysql语句最大长度

我自己没注意过,但有人遇到了,就找找这方面的资料。
所以,纯转,有问题不要找我,http://bbs.zaopai.com/read-htm-tid-386.html:

max_allowed_packet用来限制mysql客户端和服务器通信数据包的长度的,mysql的默认限制1M。

所以,WIN32的, 请在你的系统目录下查找my.ini

在Linux下你查找my.cnf

在里面加入
set-variable = max_allowed_packet=6M
set-variable = net_buffer_length=4K

=========================

mysql有一个max_allowed_packet变量,可以控制其通信缓冲区的最大长度。要想为mysql将max_allowed_packet变量的值设置为16MB,使用下面的任何一个命令:

shell> mysql --max_allowed_packet=16777216shell> mysql --max_allowed_packet=16M第1个命令以字节指定值。第2个命令以兆字节指定值。变量值可以有一个后缀K、M或者G(可以为大写或 小写)来表示千字节、兆字节或者十亿字节的单位。

在选项文件中,变量设定值没有引导破折号:

[mysql]max_allowed_packet=16777216或:

[mysql]max_allowed_packet=16M

注:max_allowed_packet参数是在mysql4以后才有的,在mysql4以前版本,还没有这个参数

yii 与 namespace

yii 与 namespace

Yii在import方面已经做的很好了,很多人都说Yii无法导入命名空间,事实上官方很早就给出过意见,如这里:http://www.yiiframework.com/doc/guide/1.1/zh_cn/basics.namespace,当然,这是中文版的

4. Namespace

不要将路径别名和名字空间混淆了,名字空间是指对一些类名的一个逻辑组合,这样它们就可以相互区分开,即使有相同的名字。 而路径别名是用于指向一个类文件或目录。路径别名与名字空间并不冲突。

提示: 由于 5.3.0 版本之前的 PHP 本质上不支持名字空间,你无法创建两个具有相同名字但不同定义的类的实例。 鉴于此,所有的 Yii 框架类都以字母 'C'(意为 'Class') 作前缀,这样它们可以区分于用户定义的类。我们建议前缀 'C' 只保留给 Yii 框架使用,用户定义的类则使用其他的字母作前缀。

5. 使用命名空间的类

使用命名空间的类是指一个在非全局命名空间下声明的类。比如说,类application\components\GoogleMap 在命名空间application\components下的类。使用命名空间需要 PHP 5.3.0 或者以上版本。

从1.1.5开始,可以无需显式引入而使用一个包含命名空间的类。比如说,我们可以创建一个application\components\GoogleMap 的实例而无需去处理引入的路径,这样就增强了Yii的自动导入机制。

若要自动导入使用命名空间的类,命名空间的格式必须和路径别名相似。比如说,类application\components\GoogleMap 所对应的路径必须和别名application.components.GoogleMap一致。

----------
如果仅看中文版,或许你还是看不懂,但你应该看英文版的,下面还有评论,你就知道怎么用了
评论是这个样子的,LOOK,http://www.yiiframework.com/doc/guide/1.1/en/basics.namespace:

Namespaces in a nutshell

Namespaces in php are like directory paths in console (bash, dos etc)
When you use namespace php keyword like this

namespace a\random\namespace;   class Foo {     static function bar(){}    }

is like executing cd a\specific\directory except that the namespace is created if not exists.
Now everything follows is belonging to that namespace. This means that if you want to instantiate, extend or call a static method from eg foo class on another namespace you have to

//The leading backslash '\' here denotes the global namespace that //is the root folder or C:\ counterpart from console environment  $baz= new \a\random\namespace\Foo;  class Fighter extends \a\random\namespace\Foo {} \a\random\namespace\Foo::bar();

Yii imports a very intuitive convention here that the namespace structure (if implemented) should be reflected on the physical directory structure and additionally makes its Path Alias convenience available for that purpose.
Please be my guest to follow these steps:
1. Create a new web app 2. Go to protected\components and create a folder foo 3. Move Controller.php in foo folder and open it with an editor 4. At line 6, at Controller class declaration import this:

namespace application\components\foo; class Controller extends \CController //Note the leading backslash here
  1. Now open protected\controllers\SiteController.php for editing
  2. Replace the SiteController class declaration with this
class SiteController extends \application\components\foo\Controller

As you will see, your new web app still working fine and application path alias will point properly at protected folder.
You can find more about php namespaces here
Enjoy coding :>

--------
果然,这年头,英文版的资料比中文版多多了,手册上也是,不过PHP手册是一定要带评论,对于我们这些初学者来说,那是相当的有用啊

关于GEO的备份资料

关于GEO的备份资料

一些关于GEO的备份资料
1、google相对比较开放了查询地址的接口,免费用户每天可以查询好多次了。一般不会超出吧?

新功能!Google Geocoding API 的功能进行了显著升级和增强。本文将介绍这一最新版的 Google Geocoding API (V3)。请注意,原来的Google Geocoding API V2 已经弃用。使用该服务的用户应升级到此版本。

注意:Google Geocoding API 不再需要 Google Maps API 密钥!
Google Maps API Premier 用户还需要使用新的加密密钥为其网址签名。有关详细信息,请参见 Premier 文档。

多好的功能啊。参考:http://code.google.com/intl/zh-CN/apis/maps/documentation/geocoding/

2、根据IP获取实际地址:
这个其实都不准,我看到相对比较准的,可以算是google,但这方面google并没有接口(在firefox打开部分网页时,会提示你是否愿意分享你的地址,如果你愿意,你会发现,google地图很容易获取你的地址,相对比较准确。算上偏移量,基本上就是实际地址了。。。)
http://developer.yahoo.com/yql/
这里我贴的是YQL,YQL中 有个GEO库,试了一下,偏的认不到家了。
看了一下,他实际上用的是这个接口:http://geoip.pidgets.com/?ip=202.96.209.133
有JSON和XML两种返回值,参考:http://geoip.pidgets.com?ip=202.96.209.133&format=[json|xml]

其他一些参考资料:

  1. Google地图大数据量处理的探讨
  2. 百度地图API】——国内首款团购网站的地图插件
  3. [Google Map]畫線(GPolyline)(想象一下京东的快递线路图)

纯记录,因为会用到根据 IP查询经纬度,所以先备份

常用SQL整理

  说明:复制表(只复制结构,源表名:a 新表名:b)
SQL: select * into b from a where 1<>1 (mysql无法执行)

  说明:拷贝表(拷贝数据,源表名:a 目标表名:b)

  SQL: insert into b(a, b, c) select d,e,f from b;

  说明:显示文章、提交人和最后回复时间[这个还是用innerJOIN较好]

  SQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b

  说明:外连接查询(表名1:a 表名2:b)[MYSQL已经支持using函数]

  SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

  说明:日程安排提前五分钟提醒[MYSQL无getdate函数]

  SQL: select * from 日程安排 where datediff('minute',开始时间,getdate())>5

  说明:两张关联表,删除主表中已经在副表中没有的信息

  SQL:

  delete from info where not exists ( select * from infobz where info.infid=infobz.infid )

  说明:看看即可,不要深究

  SQL:

  SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE

  FROM TABLE1,

  (SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE

  FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND

  FROM TABLE2

  WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(SYSDATE, 'YYYY/MM')) X,

  (SELECT NUM, UPD_DATE, STOCK_ONHAND

  FROM TABLE2

  WHERE TO_CHAR(UPD_DATE,'YYYY/MM') =

  TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 'YYYY/MM') ¦¦ '/01','YYYY/MM/DD') - 1, 'YYYY/MM') ) Y,

  WHERE X.NUM = Y.NUM (+)

  AND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) <> X.STOCK_ONHAND ) B

  WHERE A.NUM = B.NUM

  说明:--

  SQL:

   select * from studentinfo where not exists(select * from student where studentinfo.id=student.id) and 系名称='"&strdepartmentname&"' and 专业名称='"&strprofessionname&"' order by 性别,生源地,高考总成绩

  说明:   从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源)

  SQL:

  SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') AS telyear,

  SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '01', a.factration)) AS JAN,

  SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '02', a.factration)) AS FRI,

  SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '03', a.factration)) AS MAR,

  SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '04', a.factration)) AS APR,

  SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '05', a.factration)) AS MAY,

  SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '06', a.factration)) AS JUE,

  SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '07', a.factration)) AS JUL,

  SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '08', a.factration)) AS AGU,

  SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '09', a.factration)) AS SEP,

  SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '10', a.factration)) AS OCT,

  SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '11', a.factration)) AS NOV,

  SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '12', a.factration)) AS DEC

  FROM (SELECT a.userper, a.tel, a.standfee, b.telfeedate, b.factration

  FROM TELFEESTAND a, TELFEE b

  WHERE a.tel = b.telfax) a

  GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy')

  说明:四表联查问题:

  SQL: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....

  说明:得到表中最小的未使用的ID号

  SQL:

  SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID

  FROM Handle

  WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a)

原文来自:精妙SQL语句精华

一句SQL:取得相同sortid的结果集,每种 ID三条数据

一句SQL:取得相同sortid的结果集,每种 ID三条数据

一个表:

CREATE TABLE `book` (
`bookid` int(11) unsigned NOT NULL AUTO_INCREMENT,
`sortid` int(11) NOT NULL,
`bookname` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`bookid`)
) ENGINE=InnoDB AUTO_INCREMENT=80729 DEFAULT CHARSET=utf8;

数据是这样的:

insert into `book`(`bookid`,`sortid`,`bookname`) values (1,1,'1'),(2,1,'2'),(3,1,'3'),(4,1,'4'),(5,2,'1'),(6,2,'2'),(7,2,'3'),(8,2,'4'),(9,2,'5'),(10,2,'6'),(11,2,'7'),(12,2,'8'),(13,2,'9'),(14,2,'10'),(15,2,'11'),(16,3,'1'),(17,3,'2'),(18,3,'3'),(19,3,'4'),(20,3,'5'),(21,3,'6'),(22,3,'7'),(23,3,'8'),(24,3,'9'),(25,3,'10'),(26,3,'11'),(27,3,'12'),(28,4,'1'),(29,4,'2'),(30,4,'3'),(31,4,'4'),(32,4,'5'),(33,5,'1'),(34,5,'2'),(35,5,'3'),(36,5,'4');

在这种情况下,要取得 sortid IN (1,2,3)的数据,每个sortid的结果是3条。
这种题目网上很多,但真的没有一种特别好SQL,在网上有很多种。最初的时候,我自己是想着用union来处理,但最终这种方法太伤了,同事clear提出的SQL不错,试了一下,在几万条数据的时候,效率还可以,而且SQL相对简单:

SELECT sortid,bookname FROM book b WHERE sortid IN(1,2) AND 3>(SELECT COUNT(1) FROM book WHERE b.sortid=sortid AND bookid<b.bookid)

表自关联,在sortid上建索引,效率还不错。

雨林木风获Win7独家封装权???

雨林木风获Win7独家封装权???

去google或者百度搜索一下标题:“雨林木风获Win7独家封装权”,新闻超多啊,只是标题后面或者前面都还有一句:没永远的敌人。
确实,在商场上没有永远的敌人,只有利益,当利益到的时候,生死之仇也会放下刀子坐在桌前谈利益的。特别对这些上市公司之流,他们要照顾的是股东的利益。
可怜的蕃茄花园就这样消失在历史的长河里了,不过,总觉得雨林木风也不是那么厚道的,可惜了深度之流。
意外的事情其实很早就有了,比如说雨林木风封装的ubuntu,在大便(debian)的分支中居然也出现了,果然团队式的操作终究只是小动作,只有公司式的运作才能给这些技术人员带来利益。
但,这样功利性的东西能够维持多久,谁也说不清,或者只有纯技术性导向的公司才会一起有坚持,以功利性为导向的,只会哪个赚钱做哪个吧?
乱发发牢骚,毕竟我更喜欢的是深度。

转淘宝UED的:互联网用户常见心理特征

由于公司对淘宝网站进行了一定的处理,连带我上ued.taobao.com也无法成功了,暂时还没有试着那个open.taobao.com是否会对公司以后业务有否需要。到时候再说了。
这一篇文章说的是互联网用户常见的心理特征,让我想起了我上家公司的测试人员,后来转产品了,她就是心理学出身的,因此她当时从测试、到产品的转换时,对产品提出的一些理念都非常有意义。
这和本文无关,随便谈谈而已,开始上正菜,作者青云,来自:互联网用户常见心理特征

注:本文是我在淘宝的内网 中发现的一片文章,作者来自于测试团队的霜波同学,她是我淘宝讲师团队的同事,爱好广泛,去年一年都在研究心理学。哈哈,让我甚是佩服。这篇文章写的是互 联网用户的心理学特征,我觉得分析的很到位,感觉这些行为就是每天发生在自己身上一样。我想,这对设计师来说,了解这些用户行为背后的原因是非常重要的。 故转发此文,与大家一同分享。

近半年持续关注了一些用户反馈和客服电话,从一些常见问题中总结出了八点互联网用户常见心理特征,在此共享,希望能共同努力提高用户体验。

1:惯性

用户:“你们的排序按钮为什么没有了?”

客服:“亲,我们把它放在右边了,这样更加的明显哦。”

用户:“你们很闲吗?没事弄这个按钮做什么!”

有一个故事,说的是将奶酪放在了迷宫的第三个格子,然后放一只老鼠进入迷宫,第一次的时候,老鼠先找第一个,再找第二个,最后在第三个格子中找到 了,很高兴。第二次的时候,先找第一个,再找第二个,又再第三次的格子中找到了,很高兴。第三次的时候,老鼠直接去了第三个格子,找到奶酪。第四次,第五 次,奶酪没有动。第六次的时候,奶酪被移入了第一个格子,老鼠看不到奶酪,于是生气,郁闷,焦躁,原地打转,却放弃了继续寻找。

人和老鼠一样,甚至比老鼠更加的具有惯性,更加的善于总结规律,更加的容易感觉生气和不爽。一旦他学会了用一个按钮,第二次一定会去原地按照原来的 方法使用。如果位置或者方法和以前不一样,他会很不习惯,并且认为这是一个非常不爽的改变。所以如果产品经理要改变原有的规律一定要三思再三思,即使你知 道你是在让原来的过程更加的美观,更加方便,更加的绚丽,也请考虑到原有老用户的习惯。在吸引新用户的同时如果让老用户少去学习是产品经理需要综合考虑的 问题。

2:我就是全部

用户:“你们的平台真烂,我商品的显示全部错了。”

客服:“亲,别人的都是好的。是不是你设置错了?”

用户:“别人和我有什么关系,我的商品显示出来就是错的!”

看上去蛮不讲理,但是每个人都是自己世界的国王,他对他自己全部的负责,所以当我们很轻易的说少数人的时候,也应该去体会这少数人的全部世界,他和 我们关心自己的kpi,关心自己的晋升一样关心着自己的小店铺,对我们来说的沧海一粟,对他们来说也许是他们最珍惜的珍珠。承认彼此的平等,也正是这些微 不足道给出反馈的用户帮助淘宝一而再再而三用户体验的改进,他们是我们最优秀的不取工资还不断帮我们提交bug的用户测试工程师,对于如此无私的行为,我 们是应该感谢了?还是感谢呢?还是感谢呢?

3:第一印象很重要

用户:“你们应该提供一个**的功能。”

客服:“亲,我们有了。在**的链接上可以链接进去。”

用户:“我之前用过,一点都不好用。”

客服:“我们改进了,你再试试。”

用户(一段时间之后):“我就说过不好用,你看看,还有***都不是我想要的。”

第一印象一旦形成,接下来所有的关注力都是为了证明自己的第一印象是正确的。所以,不要责怪你的用户不够宽容,不够拥抱变化,不能理解你持续的努 力,是你在之前没有竭尽全力去给他一个好的体验,一个满意的结果。所有单身的同学注意了,别随便糟蹋自己的形象,很可能在某一个你没有准备好的时刻,你的 Mr right就出现了,然后你需要很长很长得时间去重塑你的新形象。

4:相信熟人

用户:“我朋友说你们的这件商品很好,我也要一件。”

这是买一件东西最肯定的理由,经常在人多的地方听到一堆的女生在说这样的对话:“你的衣服很漂亮,在哪儿买的?”“在淘宝。”“快把链接发给我。” 每次听到这样的言语都忍住不的微笑,因为成为这家有意义公司的一员而骄傲。感谢这些八卦的女生们,她们用言语证明了淘宝的价值,她们是淘宝最佳的代言人。

5:简单

用户:“能不能不要让我回答这么多问题,填这么多信息。我只是想买一件衣服。”

刚开始的时候我们曾经想做成最简单的产品,随着时间的发展,随着需求的深入,随着问题的展开,我们经常看到的是一个复杂不堪的产品。然后用户望而却 步:“知道吗,我对你每一步的迈出和深入都需要勇气和热情。但是在得到真相之前,我不确定的我的这种付出是否值得。”所以,别让潜力用户在漫漫长途中放 弃。是我们的重重关卡将他们拒之门外。

6:文字图片结合

用户:“能不能在文字上直接给张图片?看着直观漂亮。”

用户:“能不能在图片旁边写上文字,否则不知道是在卖什么,干什么。”

人的头脑分左脑右脑,右脑喜欢图片、直接感觉;左脑喜欢文字,思考。有人喜欢右脑思维,有人喜欢左脑思维,作为产品的设计者,不用纠结,不用分类,让用户的2块头脑都得到充分的享受和利用吧。图片文字合理完美的结合是对不同用户最好的尊重。

7:金钱安全

用户:“我把钱放在你们这儿安全吗?你确定吗?”

用户:“你确定我的退款能成功吗?我把货退还给他了,钱能拿回来吗?”

金钱永远是让人担心的东西,金钱的安全一定是用户的第一考虑,如果我们不能给他们金钱的安全感,我们就无法留住用户,比金钱更加重要的应该是用户的信任和信心,所以在金钱的安全和保障上付出任何的努力应该都值得。

8:搜索准确

用户:“你们的搜索真差,我找不到我想要得商品。”

客服:“能告诉我你想找什么吗?”

用户:“我就想要自己喜欢的东西。”

客服:“。。。”冷汗直冒中

也许我不知道自己想要什么,但是你们应该知道我想要什么。这是很多用户的心理,我也是。永远不要指责用户的无理取闹,就像不要指责女生的善变。如果 你足够把她放在心上,你应该会知道她喜欢什么,想要什么,会买什么。她的每一次浏览,每次点击,每次购买都在告诉你她喜欢什么,想要什么,这些都是她给你 的机会,不要浪费。

9:保护私隐

用户:“你们太过分了,你们把充气娃娃让我爸爸接收了,然后,然后。。。他还当场打开了。”

每个人都有自己的私隐和不想让人知道的信息,不可以想当然的将这些信息透露出去,信任的建立很困难,需要很长的时间,信任的失去也许只是一瞬间,一 个不小心的安全漏洞,一个不合适的需求,一次不小心的透露,我们就可能摧毁我们和用户之前长时间建立的信任关系。珍惜用户包括珍惜他提供给你的一切信息。

我常想,作为产品我们应该把用户放第一,作为员工我们应该把公司放第一,作为主管我们应该把员工放第一,可是这么多第一,谁是真正的第一?问问自己的良心吧,你能坦然面对你所有的客户、员工、团队成员问心无愧,能堂堂正正说出自己所做所为所思所想,应该就是真正的成功了。

-----------------

目前的产品还没有涉及到隐私、金钱等重要的,但是用户的感观还是会有接触,所以了解一下总是好的。再加上,这两天密码狂泄,隐私,真的会被提上日程吧?