存档

2009年10月 的存档

从谷歌操作系统看做产品的三大要素

2009年10月15日 2 条评论

第一,Vision,洞势,解决做产品之“我们应该这么做”的问题,其核心理念是行业先于客户,即产品成功的关键是击败竞争对手,而不是满足顾客需求。

第二,Position,定位,解决做产品“我们必须这么做”的问题,其核心理念是将做产品上升为做品牌,将产品与技术之争上升为品牌、商业模式与产业链之争。

第三,Innovation, 创新, 解决做产品的“我们可以这么做”的问题,其核心理念是有目的、有组织、系统化的持续创新。

三大要素总结的不错,虽然不是完全赞同第一个观点。

详情请看:http://www.programmer.com.cn/680/

---------------------------------------------------------------
本站作品根据创作共同协议进行授权, 转载时请务必以超链接形式标明文章原始出处
原文地址:http://www.mirecle.com/2009/10/15/google-operating-system-as-products-from-the-three-major-factors-that.html
---------------------------------------------------------------

分类: 产品与商业, 互联网 标签:

mysql学习笔记-1

2009年10月13日 没有评论

clip_image001

mysql最不同也是最重要的特性,就是它的存储引擎架构。如图,存储引擎只处理mysql server发送的请求,不处理sql语句的解析与缓存等内容。但innodb是一个例外,因为innodb有外键定义,而mysql server目前还没有实现相关内容。

在mysql内部,每个连接都有一个线程来处理这个连接上面的请求(所以事务是不能跨越在两个连接上的,一个连接在同一时间也只能启动一个事务)。

在sql语句的parser,将sql解析成树状结构,这里可能会重写sql决定使用哪个索引等。在query cache存储sql语句与result,如果命中,就不再到存储引擎进行查询了。Query cache只存储select语句。

mysql server本身使用表级锁,如ALTER TABLE使用的就是mysql server提供的。行级锁是在存储引擎实现的,各存储引擎都有自己实现行级锁的方式,mysql server对此不需要了解。

大多数存储引擎的隔离级别是read committed,但Mysql的默认隔离级别却是repeatable read。innodb是通过多版本的方式解决repeatable read带来的幻读问题的。附:

l read uncommited即脏读,一个事务修改了一行,另一个事务也可以读到该行。如果第一个事务执行了回滚,那么第二个事务读取的就是从来没有正式出现过的值。

l read commited即一致读,试图通过只读取提交的值的方式来解决脏读的问题,但是这又引起了不可重复读取的问题。一个事务执行一个查询,读取了大量的数据行。在它结束读取之前,另一个事务可能完成了对数据行的更改。当第一个事务试图再次执行同一个查询,服务器就会返回不同的结果。

l repeatable read即可重复读,在一个事务对数据行执行读取或写入操作时锁定了这些数据行。但是这种方式又引发了幻想读的问题。因为只能锁定读取或写入的行,不能阻止另一个事务插入数据,后期执行同样的查询会产生更多的结果。

l sieralizable完全串行,用的太少,就不写了。

默认情况下,mysql开启autocommit,只有调用start transaction,它一直认为每个sql都是一个单独的事务。如果关闭了autocommit,除非你调用了commit或者rollback,你会一直在一个事务里面。当调用commit或者rollback后,它会自动的帮你在启动一个事务。

因为存储引擎自己实现事务,所以一个事务无法跨越多重存储引擎类型的表。

在一个事务中任何时候都可以获取锁,但只有事务结束时才会释放锁。lock in share mode是允许其他session读但不能写,读取的数据行如果被其他事物锁着,就会等待直到那个事务提交。for update则是排他锁,不允许读或者写。

Innodb实现Mutiversion concurrency control(MVCC),通过为每行数据记录两个隐藏的值,这两个值分别为数据创建点与过期点(binlog中的那些版本号)。增删查的处理就不用多说了,改的时候,innodb通过增加一个数据行的拷贝来完成,拷贝的创建号与原数据行的删除号就是当前系统号。

遗留问题:

在repeatable read下,innodb是怎么处理这个lock in share mode的呢?

---------------------------------------------------------------
本站作品根据创作共同协议进行授权, 转载时请务必以超链接形式标明文章原始出处
原文地址:http://www.mirecle.com/2009/10/13/mysql-study-notes-1.html
---------------------------------------------------------------

分类: 程序员 标签:

再次升级micolg的留言验证,防止垃圾评论

2009年10月12日 15 条评论

最近发垃圾评论的实在太猖獗了,gae提供的图片模块又没法支撑captcha的能力,个人又不太喜欢直接删除所有纯英文评论的做法,其它的验证码服务搭建起来会使micolog依赖性增强,再加上我懒…

一系列原因,导致我今天做了个小升级,看是否有效果。原理是根据文章id与访客的ip地址生成一个随机数加在网页中,访客通过网页留言的话是正常的,但如果通过工具进行留言,就必须每次重新获取一下随机数。为了增加工具的门槛,以后需要在页面上增加一个js来对随机数混淆,先放上这个简单的看看效果如何:)

blog.py中把这两个类列出来,就不多说了

[code lang='python' style='vs']

class SinglePost(BasePublicPage):
    @cache()
    def get(self,slug=None,postid=None):

        if postid:
            entries = Entry.all().filter("published =", True).filter('post_id =', postid).fetch(1)
        else:
            slug=urldecode(slug)
            entries = Entry.all().filter("published =", True).filter('link =', slug).fetch(1)
            if not entries or len(entries) == 0:
                return self.error(404)

        entry = entries[0]
        addReadTime(entry)
        makeHighlight(entry)

        comments = Comment.all().filter("entry =",entry)
        commentuser = ['','','']
        checknum = random.randint(1, 100000)
        memcache.set(str(entry.key())+self.request.remote_addr, str(checknum), 900)

        tpl_vars = {
            'entry':entry,
            'relateposts':entry.relateposts,
            'comments':comments,
            'user_name':commentuser[0],
            'user_email':commentuser[1],
            'user_url':commentuser[2],
            'checknum':checknum
        }

        if entry.entrytype=='post':
            self.render('single', tpl_vars)
        else:
            self.render('page', tpl_vars)

 

class Post_comment(BaseRequestHandler):
    #@printinfo
    def post(self,slug=None):
        useajax=self.param('useajax')=='1'
        name=self.param('author')
        email=self.param('email')
        url=self.param('url')

        key=self.param('key')
        content=self.param('comment')
        checknum=self.param('checknum')

        saved_checknum = memcache.get(key+self.request.remote_addr)
        if (not saved_checknum) or (str(saved_checknum) <> checknum):
            if useajax:
                self.write(simplejson.dumps((False,-102,_('Checknum not correct .'))))
            else:
                self.error(-102,_('Checknum not correct .'))
            return
        memcache.delete(key+self.request.remote_addr)

        content=content.replace('\n','<br>')
        content=myfilter.do_filter(content)
        name=cgi.escape(name)[:20]
        url=cgi.escape(url)[:100]

        if not (name and email and content):
            if useajax:
                self.write(simplejson.dumps((False,-101,_('Please input name, email and comment .'))))
            else:
                self.error(-101,_('Please input name, email and comment .'))
        else:
            comment=Comment(author=name,
                            content=content.replace('^~','<img src="http://' + g_blog.domain + "/static/images/icons/icon_").replace('~^','.gif" />'),
                            email=email,
                            entry=Entry.get(key))
            if url:
                try:
                    comment.weburl=url
                except:
                    comment.weburl='http://'+url

            #name=name.decode('utf8').encode('gb2312')

            info_str='#@#'.join([urlencode(name),urlencode(email),urlencode(url)])
            logging.info("info:"+info_str)
            #info_str='#@#'.join([name,email,url.encode('utf8')])
  
60;         cookiestr='comment_user=%s;expires=%s;domain=%s;path=/'%(info_str,(datetime.now()+timedelta(days=100)).strftime("%a, %d-%b-%Y %H:%M:%S GMT"),'')
            comment.save()
            memcache.delete("/"+comment.entry.link)

            self.response.headers.add_header('Set-Cookie', cookiestr)
            if useajax:
                comment_c = self.get_render('comment',{'comment':comment})
                self.write(simplejson.dumps((True,comment_c.decode('utf8'))))
            else:
                self.redirect(self.referer)

[/code]

最后,要记得更新你的comments.html文件,提交的form里面带上checknum

---------------------------------------------------------------
本站作品根据创作共同协议进行授权, 转载时请务必以超链接形式标明文章原始出处
原文地址:http://www.mirecle.com/2009/10/12/upgrade-again-micolg-message-authentication-to-prevent-spam-comments.html
---------------------------------------------------------------

分类: micolog 标签:

冲动是魔鬼

2009年10月10日 9 条评论

昨天中午吃饭时候临时起意,想换个机身,就发贴到蜂鸟上了,想着至少得1个月才能卖出去吧…没想到,下午就有两个人打电话过来说要买,也不能说不卖啊。一个哥们跑过来就给买走了…

现在没相机用了,感觉郁闷了….

听说tt决定要每月买100元的彩票,身边越来越多人要尝试这个玩意了啊。不过咱要是像河南彩民那样,中个3亿,相机就有着落了嘿嘿。囧,不说这没谱的事了….

---------------------------------------------------------------
本站作品根据创作共同协议进行授权, 转载时请务必以超链接形式标明文章原始出处
原文地址:http://www.mirecle.com/2009/10/10/impulse-is-the-devil.html
---------------------------------------------------------------

分类: 生活 标签: