让mac的cpu不再狂转

On 十月 29, 2011, in mac os, by pensz

众人皆知,在mac上,flash绝对是cpu杀手,只要一开有flash的网站,那cpu马上疯狂的转,不知道是adobe的问题,还是mac的问题。

鉴于此,禁用flash是个最直接的解决方法,而且一般网站大部分flash都是广告。safari中推荐使用 clickplugins这个扩展,他可以将flash暂时屏蔽,若你需要看,点击一下即可。firefox中同样有这样的插件,名字叫做flashbock,使用方法一样,需要看的时候点一下。

关于视频网站的解决方法:在safari中可以将user agent设置为iPad,这样,大部分视频网站将会给你html5的视频,这样播放起来无压力。firefox下由于不支持html5,那都是浮云了。事实上,clickplugins这个插件会对国外网站上的视频转成html5,无需切换user agent,可惜这些网站在我朝是不存在的。

Tagged with:  

关于js执行顺序和jquery.html

On 十月 28, 2011, in 技术记录, by pensz

下面这些知识虽然是前端相关的,但是做为一个想深入web的人,还是非常有必要知道的。很多时候当前端跟你抱怨为什么我的js中明明声明了变量,但还报未定义的错;为什么我写一个alert调试就好了?很有可能就是下面所提到的问题。

1 js为什么不按代码中的次序执行了?

正常的html中外联script,script无法并行下载,阻塞后面其他资源的下载;且执行顺序可以得到保证(新版本浏览器有改进,可以并行下载js,执行顺序也会保证)。所以我们一般在html中写的js都没有问题,但问题是,这个会影响整个网页相关资源下载速度。

鉴于此,人们又想了很多方法来“欺骗”浏览器,以达到加速下载js和相关资源文件的目的,方法大概有以下几种:

  • XHR Eval :ajax获得js内容,然后执行
  • XHR Injection : ajax获得js内容,然后创建一个script的node,插入到文档dom tree中
  • Script in Iframe : iframe src为js文件
  • Script DOM Element :动态创建script,然后设置其src
  • Script Defer : script标签加入 defer属性
  • document.write Script Tag :document.write(“<script type=’text/javascript’ src=’A.js’><\/script>”);

既然可以并行下载,那么执行顺序就是一个需要确认的问题了,可惜的是,不是每种技术都能保证脚本执行的次序。具体情况可以参考下表(节选自 《Even Faster Web Sites》):

2 jquery的html函数好像有时候也不灵啊!

假设我们如此调用:

$(‘#content’).html(data);

jquery 的html函数使用同步ajax下载data中的外联js。对于inline的js,执行Script DOM Element在head节点插入一个script节点。

从上面的分析来看,data中js的执行顺序是可以保证的。但有时调用jquery.html,却仍然出现执行顺序混乱的情形,原因是外联的js是不同的域。由于ajax无法跨域,故这时候无法通过同步ajax下载来加入外联js,而是通过和内联js一样的方式:将外联的js以Script DOM Element 的方式插入到head节点。按照上面的图,执行顺序是无法在所有浏览器上保证的(ensures order)。

解决方法: 在调用jquery.html前,使用 document.write Script Tag将外联的js载入。

3 文章开头提到的问题

外联js定义了js变量,但还报undefined错:很有可能就是执行顺序不对,执行使用变量的代码时,定义的js虽然在前面,但还没有下载完呢。

alert一下,一切就是好的了:还是一个道理,定义的外联js没有下载完成,同时,你可以试试setTimeout,将你使用外联js的变量的代码晚点执行,也会是好的。

4 参考资料

下面这些资料,非常值得一读:

  • 《Even Faster Web Sites》
  • http://www.cnblogs.com/sanshi/archive/2011/02/28/1967367.html
  • http://www.cnblogs.com/sanshi/archive/2011/03/01/1968275.html
  • http://www.cnblogs.com/sanshi/archive/2011/03/02/1969224.html
Tagged with:  

从leopard升级到lion

On 十月 19, 2011, in mac os, by pensz

1 前言

话说上回将iPad2升级至iOS5,正欢天喜地的尝试wifi同步,但可惜的是我的leopard系统里面竟然连wifi同步选项都没有!我非常、极其的生气,打了一通apple的客服,无果;上苹果的论坛一看,一大堆人反映和我一样的问题。有人实测,只有在10.6.8后才能够wifi同步,连10.6.6都不行。我恨啊。

难道真的要升级系统了吗,现在老系统的问题越来越多,主要有以下方面:

  1. 输入法,可恨的输入法,竟然大部分都不支持10.6.8以下的系统
  2. 还是输入法,10.5.8里面不能设置不同窗口使用不同输入法,实在不爽(据说10.4还是可以设置的)
  3. 没有mac app store,下载软件完全靠游击战
  4. qq等很多软件不再支持10.6.8以下
  5. webkit在编译有些部分时,不支持10.6以下的系统
  6. 刚才说的,没有办法和iOS设备wifi同步

之前没有升级,主要是偶尔工作时会用,当心开发环境什么的;现在好些了,那狠下心来升级吧,为避免后面再升级,准备现在一次升到lion算了,同时,加内存到8G。

 

2 升级过程

升级的过程是 10.5.8 -> 10.6.3 -> 10.6.8 -> 10.7 -> 10.7.2,也就是从leopard到snow leopard再到lion,因为leopard是无法直接升到lion的。

其中10.6.3 -> 10.6.8和10.7 -> 10.7.2算更新,去apple网站下载更新包即可;其他的嘛,要么买正版(其实也不贵,snow lepord卖¥248,lion 下载时卖$29.9),要么你懂得。

升级到10.6.3的时候,最后时刻出现了安装失败,真的是让我心都凉了;幸好重新安装后成功,估计是光驱读盘的问题吧。

硬件的升级放在了安装上10.6.8之后,原有的2G内存早已不够lion用的了。内存倒是亲民价,2条4G的三星金条连350都不到。

拆开后盖,拔出之前的内存,换上新的内存(顺便可以清理一下风扇什么的),开机一次点亮。之前网上有人说可以使用1333MHz的内存,我这里算也是再次验证了,不过它工作的频率应该还是1066MHz。

系统信息

下面是我机器的更加详细的信息,可以看到,虽然是2008年后期的mb 466,但是还是可以升级到lion的。
系统简介

整个升级过程还算顺利,只需开机放入光盘或者点击安装程序即可,默认情况下也是升级安装,也就是说用户的程序(包括应用程序下的程序)和文档都还在的,甚至连之前应用程序的数据都在,比如safari的浏览历史,下载记录。iTunes无法识别iPad2,不过重装一下iTunes就好了,app、音乐以及图书都还在。

 

3 使用感受

  • 8G的内存没白加,lion使用起来还是非常顺畅的;另外,系统占的硬盘空间也比leopard少了4G左右。
  • 由于从leopard切换过来的,一时无法适应手势滚动方向的改变:之前leopard中,手势滚动的是滚动条,而现在lion滚动的是内容,这也和移动设备是一致的。
  • 手势程序切换以及全屏是目前使用起来比较舒服的功能。
  • safari浏览时,前进后退比以前更加酷了。
  • iTunes终于可以iPad2无线同步了。
Tagged with:  

iOS5使用有感

On 十月 14, 2011, in mac os, by pensz

ipad gestures

10月12号,apple正式发布iOS5,现在更新,虽然算不上第一时间,但这时候稳定些。下面将相关过程和初步使用体会分享一下。

更新的过程:

  1. 更新iTunes至10.5
  2. 直接在iTunes中升级至iOS5(也可以直接下载对应的固件文件,然后通过iTunes里面options(shift in windows)+恢复完成)

直接下载固件的列表:

关于更新后app都需要重新下、游戏记录都没有的问题,我这边倒是没有发现,更新后app照样在,照片也在。应该是始终用一台电脑的原因吧。总之,更新过程没有遇到什么问题,就是下载固件时间长了些。

使用感受,下面的功能是个人觉得比较好用的:

  1. 手势:通过手势切换应用程序,回到主屏幕,查看正在运行的程序等等;有了手势,可以少按home键了
  2. 更新的键盘:有输入法切换的改进,增加常用的符号输入,支持浮动、分开的布局键盘;总之,输入更加方便
  3. safari的更新,标签操作直接可以在safari的主界面搞定,和mac版的safari类似;另外还有read later以及阅读器的功能
  4. 和电脑通过wifi 同步,可惜我的Leopard系统(10.5.8)好像不支持,完全没有
  5. iCloud,可以同步一大堆数据
  6. 更好的通知中心

当然,也有些更新其实不是那么好玩了,比如报刊杂志,个人觉得是鸡肋,至于iMessage,我觉得还不好说呢。

Tagged with:  

10月4日,苹果举行了今年秋季的产品发布会。按apple之前的惯例,本应该今年早些时候发布新产品的;拖到现在,使很多投资者和消费者有了更多的期待,但总体来说还是让人比较失望的,这在苹果的股价上有很好的体现。发布会主要有以下信息:

  1. 没有iPhone5,只有iPhone 4 的升级版iPhone 4s,即使这样,连iPhone 4s的介绍也不是CEO Tim
  2. ios 5的介绍,主要是iCloud, Find my Friend 以及一个Card的程序
  3. iPod, iPhone产品全线降价
  4. 其他相关apple store, iPod, mac,iPhone, iPad, ios等数据介绍

其实我等围观之,主要是想要看看apple能够有哪些新功能的推出,但是创新也不是那么容易的,不可能每次发布会都能像iPhone, iPad刚推出来那样让人耳目一新。但个人觉得本次发布会,Siri还算是一个亮点了(Let ‘s talk iPhone 中 的talk应该是指这个意思吧),Siri虽然基础是语音识别,之前也有很多类似的语言识别程序,但之前的程序交互性不强,大多数的功能也是将语言转换成文字;而Siri则更在问答、帮忙人们完成任务这一方面更进一步。

 

上次和同事聊到了验证码中有表达式求值的问题,说起来应该是比较简单了,也是数据结构上经典的算法问题。可是自己写一写才会发现,做对一件看似简单的事情不是那么容易。

本来自己弄了一个c的stack,但是c没有模板,想不到怎么支持不同的类型,只好换用c++了。

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

#include <stack>
#include <iostream>

using namespace std;

/**
 * 比较运算符之间的优先级
 */
static short int Precede(char c1, char c2) {
    if (c1 == c2) {
        if (c1 == '#') {
            return 0;
        } else if(c1 == '(') {
            return -1;
        } else {
            return 1;
        }
    }

    switch (c1) {
        case '+':
        case '-':

        if (c2 == '*' || c2 == '/' || c2 == '(') {
            return -1;
        } else {
            return 1;
        }
        break;

        case '*':
        case '/':
        if (c2 == '(') {
            return -1;
        } else {
            return 1;
        }
        break;

        case '(':
        if (c2 == ')') {
            return 0;
        } else {
            return -1;
        }
        break;

        case ')':
        return 1;
        break;

        case '#':
        return -1;
    }
}

/**
 * 对加减乘除进行求值
 */
static float Operate(float a, char theta, float b) {
    switch (theta) {
        case '+':
        return a+b;
        break;

        case '-':
        return a-b;
        break;

        case '*':
        return a*b;
        break;

        case '/':
        return a/b;
        break;
    }

    printf("bad operator");
    return 0;
}

int main() {

    stack<char> optr;
    stack<float> opnd;

    optr.push('#');

    char theta, tmp[20], *tmppoint, basechar[20];
    tmppoint = basechar;
    float a, b;

    char c = getchar();

    while (c!='#' || optr.top() != '#') {
        if (isdigit(c)) {
            *(tmppoint++) = c;
            c = getchar();
        } else {

            if (tmppoint > basechar) {
                *tmppoint = '\0';
                opnd.push(atof(basechar));
                printf ("push number %s\n", basechar);
                tmppoint = basechar;
            }

            if (c != '+' && c != '-' && c != '*' && c != '/' && c != '(' && c != ')' && c != '#' ) {
                c = getchar();
                continue;
            }

            short int precede = Precede(optr.top(), c);
            switch (precede) {
                case -1:
                optr.push(c);
                printf("pushed operator %c \n", c);
                c = getchar();
                break;

                case 0:
                optr.pop();
                c = getchar();
                break;

                case 1:
                theta = optr.top();
                optr.pop() ;

                if (opnd.empty()) {
                    printf("opnd is empty\n");
                }
                b = opnd.top();
                opnd.pop();

                a = opnd.top();
                opnd.pop();

                cout << " cal a=" << (float)a << " theta=" << theta << " b=" << (float)b << endl;

                opnd.push(Operate(a, theta, b));
                break;
            }
        }
    }

    /* 最后的结果 */
    printf("%f\n", opnd.top());
    printf("%c\n", optr.top());

    return 0;
}
Tagged with: