最近有点烦

每天都很忙,但是不知道在忙撒。事情非常琐碎,我找不到成就感,这让我觉得很可怕。

技术几乎没什么长进,我明知道很多地方有更好的实现方式,但是,我没有时间停下来去优化。开始的时候我会跟自己说,等这阵子忙过了,再回过头来处理,但我已经渐渐的失去了耐心,因为总是忙不完。

工作三年来,第一次感到迷茫,似乎离我的目标越来越远,应该以怎样的姿态来对待现在的问题?在一个有梦想有激情的团队,自己却觉得没给这个梦想创造多大的价值,这有多郁闷。

 

Android 学习笔记(1)–布局方式

今天终于收到了《Google Android SDK 开发范例大全》,迅速的配置好了开发环境,写了一个hello world。

发现这本书完全是围绕示例来写的,完全没有系统的总结,我就把学到的内容加上网上的搜索把一些知识点总结一下,记录再这里,方便自己以后开发的时候查询。

Android 的layout是通过xml配置的(这让我想起了Flex中的界面),而且也有样式表(不是css,也是一个xml)。

一段布局代码:

  1. <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android
  2. android:orientation=”vertical”   android:layout_width=”fill_parent”
  3. android:layout_width = “fill_parent”
  4. android:layout_height=”fill_parent”>
  5. <TextView android:layout_width=”full_parent”  //宽度与父容器一样(也就是和屏幕宽度一样)
  6. android:layout_heigth =”wrap_content” //高度自适应
  7. android:text=”hello world!”
  8. />
  9. </LinearLayout>

Android 的布局类型有五种:

  • FrameLayout:框架布局,这个布局浏览单张图片的时候很合适,放入其中的所有元素都被放置在FrameLayout区域最左上的区域,而且无法为这些元素指定一个确切的位置。如果一个FrameLayout里有多个子元素,那么后边的子元素的显示会重叠在前一个元素上。这个布局方式的宽与高的参数 一般是用wrap_content。
  • LinearLayout:线性布局管理器,只能进行单行布局,是由参数android:orientation(方位)决定的,分为水平和垂直两种(或者说是行 与 列两种),vertical表示竖直排列,horizontal表示横向排列。
  • TableLayout:任意行和列的表格布局管理器。其中TableRow代表一行,TableRow的每一个视图组件代表一个单元格。
  • AbsoluteLayout:绝对布局管理器,坐标轴的方式,这个很好理解,左上角是(0,0)点,往右x轴递增,往下Y轴递增,组件定位属性为android:layout_x 和 android:layout_y来确定坐标。
  • RelativeLayout:相对布局管理器,根据另外一个组件或是顶层父组件来确定下一个组件的位置。

再看一个采用TableLayout布局的例子(3行2列):

  1. <TableLayout xmlns:android=”http://schemas.android.com/apk/res/android
  2. android:layout_width=”fill_parent” android:layout_height=”fill_parent”
  3. android:stretchColumns=”1″>
  4. <TableRow>
  5. <TextView android:text=”用户名:” android:textStyle=”bold”  android:gravity=”right” android:padding=”3dip” />
  6. <EditText android:id=”@+id/username” android:padding=”3dip” android:scrollHorizontally=”true” />
  7. </TableRow>
  8. <TableRow>
  9. <TextView android:text=”登录密码:” android:textStyle=”bold” android:gravity=”right” android:padding=”3dip” />
  10. <EditText android:id=”@+id/password” android:password=”true” android:padding=”3dip” android:scrollHorizontally=”true” />
  11. </TableRow>
  12. <TableRow android:gravity=”right”>
  13. <Button android:id=”@+id/cancel” android:text=”取消” />
  14. <Button android:id=”@+id/login” android:text=”登录”  android:layout_width=”wrap_content”  android:layout_height=”wrap_content”/>
  15. </TableRow>
  16. </TableLayout>
Tagged with:
 

img标签src为空的陷阱

把页面中的img标签的src设置为“”存在巨大的风险,无论是在html中写入

<img src=”" />

还是在js中写入

var img = new Image(); img.src = “”;

出现一次这样的标签会导致向你的服务器多做一次请求。

  • 在IE中,这样做会请求一次当前页面所在的目录。如在http://playgoogle.com/demo/a.html 中出现这种空src的标签,会导致重新请求一次://playgoogle.com/demo/
  • 在Safari 和 Chrome中,将请求当前页面本身。
  • 在Firefox 3.5以前的版本中,有和Safari同样的问题,但是在3.5中修正了这个BUG。
  • 在Opera 中,不会做额外的请求。

在一个访问量不高的网站中,多一个这样的请求也无所谓(甚至可以让你的网站浏览看上去翻番),但在一个千万级访问量甚至更高的WEB站点里,这样会导致你的服务器和带宽的成本显著增加。 另外一个隐患是,重新请求某个页面可能会导致用户的一些信息被无意中修改,例如cookies,或者ajax操作。

你永远不会写出这样的代码?

我并不这么认为,很多时候这种情况在无意中出现,比如下面这段php代码:

<img src="$imageUrl" >

你原计划是从服务器端读取这个src地址,但是由于某个原因,这个地址还未设置,或者代码的BUG导致读取失败,就会出现空的src标签。

其他的标签中的空src会不会导致这样的问题?

好消息是,在IE中只有image标签有这个问题。坏消息是,在Chrome, Safari, 和 Firefox中<script src=""><link href="">都会导致出现一个新的请求。

如何解决这个问题?

可以从两方面着手,一是尽量避免这种坏的编程方式,不要出现空的src标签。另外,可以从服务器端着手,在发现时这种无意义的请求时不要返回任何东西给客户端。

<?php
    //Works for IE only when using path URLs and not file URLs

    //get the referrer
    $referrer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';

    //current URL (assuming HTTP and default port)
    $url = "http://" . $_SERVER['HTTP_HOST']  . $_SERVER['REQUEST_URI'];

    //make sure they're not the same
    if ($referrer == $url){
        exit;
    }
?>

原文网址:

Empty image src can destroy your site

Tagged with:
 

国产JS框架–Como JS 1.0 正式发布

综合了多个框架的优势,希望能给各位开发人员带来更大的方便。

由于框架刚发布,会存在很多不足之处,我们会在后续不断推出新的版本,也希望大家有任何意见或建议与我们联系。

Email/Gtalk/MSN: KevinComo@gmail.com

Como 是一款代码简易而功能强大的Javascript框架,这也是开发者在工作过程中的经验总结,实用性强;通过它,能够简化Javascript代码开发,增强代码重用性,能够异步按需加载js和css文件,增强page的加载速度;
Como完全兼容市场目前的主流浏览器:Internet Explorer6+, Firefox 2, Safari 2+, Chrome, Opera 9+, 及其他基于IE内核的浏览器如Maxthon、360、Sogou等
待Como完善成一套框架体系后,我们将提供出一套基于BSD协议的开源方案,供大家学习和分享。我们也将逐步推出一些扩展组件,比如编辑器等。

昨天晚上一口气读完了。书很薄,只有十万字左右。但是写的非常不错,翻译的也很流畅。作者以一个工程师平实的语言、从局内人的视角,描述了这个传奇的web2.0网站初期的爆炸性发展。

如果自己缺乏创业的能力,能有幸见识并亲身体验到一个伟大公司的诞生也是一段值得回忆的事。而其中对“寻梦”这个主题的描述,我觉得对想要创业的年轻人会非常有用,对那些对自己的职业规划不清晰的人也非常有用。

以下内容节选自“《从零到百亿Facebook创业故事》”

“要想找到属于自己的创业梦想,要么从头做起,要么发现一个刚刚起步但却前程似锦的创业团队。

发现这样一个创业团队需要两个要素:运气和判断。我是非常幸运的,因为是Facebook找上了我。不过正如人们所说的那样,幸运之神只眷顾有所准备的人:我一直是LinkedInr的忠实用户。而判断这部分,对我来说也很容易:因为Facebook在很多大学校园里已经相当流行了,显然,它也会很快在其它校园里流行起来。我真的希望你也能像我这样容易地找到你的创业梦想。

1.在我之前加入Facebook的每个人,同扎克之间都是很知根知底的。从这里你该学到,要紧跟你那些才华横溢的朋友,并且鼓励他们去成功!

2.紧跟所有有才华的朋友并不现实,所以要能够明智地取舍。如果某个朋友恰好有个让你激动万分的创意,你就该好好想想,自己怎样才能不遗余力地帮助他实现这个创意。

3.一旦你加入了团队并且感觉良好的话,要努力让自己变得对团队不可或缺。团队的创始人所需要的,是能够完全信赖的高效的执行者,是能够了解其心意的人。开创一个新的公司,有太多的事情要做。创始人头脑中的想法——如果你能够很好的实施的话——才是最有价值的。相比之下,你对公司应该怎样动作的想法,只会是不合时宜的捣乱。

4.要有很强的适应力。熟悉掌握那些最需要的技能——不论它是什么。年轻人在这方面有绝对的优势,而且是得天独厚的优势。达斯汀还在“睡在我上铺的兄弟”时代就成了扎克的左膀右臂。是他把站点扩张到了所有的校园,一路上披荆斩棘,学习一切需要的东西,包括编程和各中技术。

5.行胜于言。不要空谈,也不要质疑。只管去做。创业团队需要用最快的速度完成很多事情——不管是用什么方式。

“只管去做”这句话意味深长,它所体现的是一种态度,它意味着快速地做出抉择,并矢志向前直到达到目标;它还意味着不要无休止地询问应该怎样做,就按你认为是最佳的办法去做吧。没有多少时间可以留给完美主义;你的激情的态度才是关键。理智的人会考虑实际情况,特别是时间上的限制。

 

检验能够成功的标准:

那么,在你众多朋友们的好主意里,哪一个会成长为下一个巨无霸公司呢?

第一个检验标准就是激情。你的朋友要坚信他的主意是最好的,并准备投入自己的毕生精力。

第二个检验标准是未来的宏图能通过简单的几个小步骤来实现。一个创意,应该不需要很长的时间或大量的工作,就能够成为现实。即使再复杂的构思,也必须从一个易于理解和完成,单纯、简单的项目开始。如果这种从简单创意到宏伟图景的阶梯非常清晰的话,那是好迹象。相反,如果你的领头羊还不清楚首先要做什么以及最终完成的是什么,那就比较糟糕了。

第三个检验标准是能否得到参与者迅速、有力的支持。不同于艺术——一些艺术家们或许在生前从不被理解——流行的网站大多是在早期就获得了成功,并拥有一批真正理解和追随其宏图远景的铁杆支持者。第四人检验标准是低用户流失率和用户使用率的增长”

Tagged with:
 

递归练习,做个奥数题

今天有个朋友问我一个小学生的奥数题,酒1元钱1瓶,2个空瓶子可以换一瓶酒,问20块钱可以喝多少瓶酒。我OUT了,我被鄙视了。

我不会,但是谁让我是写代码的呢,写了个小程序用来鄙视他。告诉他,我不仅知道20块能买多少酒,你就是20000块我也能算出来。

var allWine = 0;  // 20块钱可以买20瓶酒
var otherBottle = 0;
//递归函数,瓶换酒
function bottleExchangeWine(bottle)
{
    if(bottle % 2==1){ //保证瓶子的数量为偶数
        if(otherBottle>=1){//若不为偶数,且之前有剩余的空瓶子
        bottle += 1;//加一个瓶子
        otherBottle -= 1;
        }else{
            bottle -= 1
            otherBottle +=1;
        }
    }
    var newWine =bottle/2;
    allWine +=newWine ;
    if(newWine>=1)
    {
        bottleExchangeWine(newWine);
    }
    return;
   
}
function getWine(){
    otherBottle = 0;
    allWine = parseInt(document.getElementById("txtMoney").value);
    bottleExchangeWine(allWine);
    alert("共有:"+allWine+"瓶酒,共有:"+otherBottle+"个空瓶子还没有换!");
}

点击查看

Tagged with:
 

收藏:图片格式详解

Gif格式图片的特点:

透明性

Gif是一种布尔透明类型,既它可以是全透明,也可以是全不透明,但是它并没有半透明(alpha 透明)。

动画

    Gif这种格式支持动画。

无损耗性

     Gif是一种无损耗的图像格式,这也意味着你可以对gif图片做任何操作也不会使  得图像质量产生损耗。

水平扫描

      Gif是使用了一种叫作LZW的算法进行压缩的,当压缩gif的过程中,像素是由上到下水平压缩的,这也意味着同等条件下,横向的gif图片比竖向的gif图片更加小。例如500*10的图片比10*500的图片更加小

间隔渐进显示

Gif支持可选择性的间隔渐进显示

  由以上特点看出只有256种颜色的gif图片不适合照片,但它适合对颜色要求不高的图形(比如说图标,图表等),它并不是最优的选择,我们会在后面中看到png是最优的选择。

Jpeg

  透明性

     它并不支持透明。

  动画

      它也不支持动画。

  损耗性

     除了一些比如说旋转(仅仅是90、180、270度旋转),裁切,从标准类型到先进类型,编辑图片的原数据之外,所有其它操作对jpeg图像的处理都会使得它的质量损失。所以我们在编辑过程一般用png作为过渡格式。

   隔行渐进显示

     它支持隔行渐进显示(但是ie浏览器并不支持这个属性,但是ie会在整个图像信息完全到达的时候显示)。

   由上可以看出Jpeg是最适web上面的摄影图片和数字照相机中。

Png

类型

   Png这种图片格式包括了许多子类,但是在实践中大致可以分为256色的png和全色的png,你完成可以用256色的png代替gif,用全色的png代替jpeg

透明性

   Png是完全支持alpha透明的(透明,半透明,不透明),尽管有两个怪异的现象在ie6(下面详细讨论)

 动画

    它不支持动画

 无损耗性

    png是一种无损耗的图像格式,这也意味着你可以对png图片做任何操作也不会使  得图像质量产生损耗。这也使得png可以作为jpeg编辑的过渡格式

 水平扫描

   像GIF一样,png也是水平扫描的,这样意味着水平重复颜色比垂直重复颜色的图片更小

间隔渐进显示

    它支持间隔渐进显示,但是会造成图片大小变得更大

更多关于PNG

  PNG8

    256色PNG的别名

  PNG24

    全色PNG的别名

  PNG32

    全色PNG的别名

 其它图片格式与PNG比较

    众所周知GIF适合图形,JPEG适合照片,PNG系列两种都适合。

 相比GIF

PNG 8除了不支持动画外,PNG8有GIF所有的特点,但是比GIF更加具有优势的是它支持alpha透明和更优的压缩。所以,大多数情况下,你都应该用PNG8不是GIF(除了非常小的图片GIF会有更好的压缩外)。

相比JPEG

    JPEG比全色PNG具有更加好的压缩,因此也使得JPEG适合照片,但是编辑JPEG过程中容易造成质量的损失,所以全色PNG适合作为编辑JPEG的过渡格式.

Png8的在ie中的怪异表现:

1.半透明的png8在ie6以下的浏览器显示为全透明。

2.Alpha透明的全色PNG(png32)在ie6中会出现背景颜色(通常是灰色)。

由上面可以总结:

(a)全透明的png8可以在任一浏览器正常显示(就像gif一样)。半透明的png8在除了ie6及其以下的浏览器下错误的显示成全透明,其它浏览器都能正常显示半透明。这个bug并不需要特殊对待,因为在不支持半透明的浏览器下只是显示为全透明,对用户体验影响不大,它反而是透明gif的加强版。 

(b)第二个bug没有什么好的方法解决,只能通过影响性能的方法AlphaImageLoader与需要加特殊标签(VML)。

因此得出结论就是:请使用PNG8。

Png8的软件问题

  1.Photoshop只能导出布尔透明的PNG8。

  2.Fireworks既能导出布尔透明的PNG8,也能导出alpha透明的PNG8.

  3.pngquant与pngnq这两个命令行软件可以转换全色png为256色的png8。

Tagged with:
 

Python学习笔记(2)

  1. Python中没有 switch case语句,只有if elif else
  2. 字符串、数字、元组是不可变的,改变其值会创建新的对象(这也是为什么大量字符串的拼接会导致效率降低的原因)
  3. 字符串模版(直觉是这个功能做WEB的时候很有用,可以轻易的实现根据模版生成静态页面的功能):
    from string import Template
    s = Template("There are ${test}")
    print s.substitute(test="python")  ==>输出 There are python 
    substitute中参数如果没有对应声明字符串模版中的
    Template 对象还有另外一个方法save_substitute(),该方法在没有声明key的情况下不会报错,直接输出
  4. 浅拷贝与深拷贝
    在拷贝一个列表时,有两种拷贝方式。浅拷贝,就是新创建了一个类型跟原类型一样,其内容是原来对象的引用,也就是说这个拷贝本身是新的,但是它的内容不是。而深拷贝则是建了一个与原对象独立的,但值一模一样的新对象。
    如何实现浅拷贝?
    通常有三种方式,(1)完全的切片操作[:](2)利用工厂函数,比如list(),dict()等。(3)使用copy模块的copy函数。
    a 前拷贝的示例:
    person = ["name",['male',19]]
    girl = person[:]    # 将人这个列表浅拷贝到girl
    boy = person[:]  # 将人这个列表浅拷贝到boy
    gilr[0] = "lily"   #修改名字
    gril[1][0] = "female"
    boy[0] = “john”
    boy[1][0]="male"
    boy[1][1]=22

      例认为打印出girl 和boy结果是什么?
    boy ====>  ["johu",['male',22]]
    girl ====>   ["lily",['male',22]]
    为什么名字相互之间没有影响,而性别和年龄之间有影响呢?这是因为该列表中的第一个元素是一个字符串,是一个不可变的对象,一旦对其修改,就会独立生成一个新的对象。因此当拷贝的时候,字符串被显示的拷贝了,而列表只是拷贝了一个引用。
    那么,如何实现深拷贝
    在copy模块,有一个deepcopy()方法,可以轻松实现深拷贝。

 

Tagged with:
 

Python学习笔记(1)

由于公司的服务器端用的是Python,所以决定抽点时间熟悉一下,也好在以后的工作中能和其他同事有比较好的配合。

我主要是把Python和其他语言(特别是Javascript和c#,因为我熟悉)一些不一样的特性列出来。

首先说一下对Python的大体印象,Python和Javascript一样是解释性的语言,也是弱类型的语言。同时也是面向对象的一种语言,一切皆是对象:甚至字符串,变量,函数,都是对象。Python的设计也非常酷,用起来很灵活,习惯使用Javascript的人,一定会爱上Python 

  1. 没有大括号,靠缩进来控制代码块的开始与结束。语句结束不用分号,但一行中有多个语句,用分号隔开。
  2. // 运算符和 ** 运算符
    //特殊的除法运算(千万别以为是注释代码的,Python的代码注释用#),运算符对整型和浮点型都会取整。如:2.0//3.0=0   **是就幂,如:2**3 表示2的3次方。
  3. 不等号有两种写法 != 和<>
  4. 逻辑操作符的关键字是 and or not
  5. 三引号(三个连续的单引号或者双引号)中的特殊字符自动转义
  6. Python中没有数组,只有列表,但其特性跟js中的数组一样,也就是长度可变的数组。
  7. 列表可以用引号(:)来获取元素
    如:a = [0,1,2,3]   a[1:4] =[1,2,3]   a[:3]=[0,1,2]   a[1:] = [1,2,3]
  8. for 循环就相当于c#中的foreach ,有一个range函数来提供索引.
    #遍历数组
    a = [1,2,3]
    for(item in a):
        print item
    #另外一个例子
    for eachNum in range(3)
        print eachNum

    这里 range(obj1,obj2)为内建函数。obj1不提供默认为0,obj2不提供默认为1,返回一个从obj1到obj2的数组

  9. 可以多元赋值
    x,y= 1,2  等价于  x=1 y=2      x,y = y,x   交换x和y的值(很好很强大,哈哈)
  10. 布尔值为False的对象有
    None(相当于js中的null),False,所有值为0的数,空字符串”(注:’0′为True),空元组(),空列表[],空字典{}
  11. 多个比较操作符可以在同一行中进行
    3<4<5  等同于(3<4 and 4<5)
  12. 用 is 来判断两个变量是否指向同一个对象。
    a is b 等同于id(a) is id(b)      id()是获取对象的内存编号。但是要注意的是 Python为了提高性能会对整型和字符串类型进行缓存。但对浮点型不会。
    例如 a =2 ;b = 2; a is b  返回True,a=2.0;b=2.0 a is b 返回False
  13. 逻辑操作符的优先级 not 高于 and  高于 or
  14. 几个标准内建函数
    type(obj) 获取obj的类型,类似Javascript中的type of
    str(obj) 将obj 转换为 字符串类型
    repr(obj)是奖obj 序列化,转换为字符串,但是可以通过eval()还原,所以obj == eval(repr(obj))
  15. 与Javascript一样,Python 不支持方法和函数的重载(弱类型语言的特点)
  16. 字符串和列表、元组统称为序列,可以进行 in 、not in、+、*操作
    obj in seq  判断obj 元素是否包含在seq中,在返回True,不在返回False
    + 操作符可以把两个序列连接起来。  [1,2,3] +[4,5,6] == [1,2,3,4,5,6]
    * 操作符把一个序列拷贝多分。  [1,2]* 2 == [1,2,1,2]
  17. 列表的下标可以是负数,负数标识从结束点往左找。
    [1,2,3][-2]==2

今天先到这里,未完待续

12/29 更正:感谢butterinsect ,我确实没有弄清楚,python是强类型的语言,确切的说是,python是隐式类型的强类型语言。也就是说,在声明变量的时候,不需要显式说明它的类型,但是在Python里,是有明确的类型的概念,而且不同类型的对象不能相互替代和操作,比如:

>>> 10 + '20'

会出现错误 TypeError: unsupported operand type(s) for +: ‘int’ and ’str’

Tagged with: