Category Archives: Uncategorized

设计师该了解的移动分辨率(2)

接上篇

实际沟通过程中,还是会遇到一些问题。首先是对像素密度(Pixel Density)的理解。

像素密度(例如72ppi)是屏幕的,图片没有这个属性

像素密度讲的是,一个屏幕上,一英寸有多少个像素。图片的长宽,只跟像素有关,即640×1134,是说宽有640px,高哟1134px。加入在普通的桌面屏幕上,像素密度为72ppi,那么图片的原图大小就是640/72个英寸长。如果在retina屏幕上使用,像素密度一般大于300ppi,那么就是640/300个英寸长。同一张图片,在两个屏幕上,显示出来的物理长度是不同的。

Photoshop中,新建图片的分辨率设置为300ppi真的好嘛?

我们看到,图片是没有这个属性的,就算我在PS中新建了300ppi的图,该是630×1134的像素数,还是这么多。因为本来计算机中的图片,就是记录每个像素值的颜色。那变的是什么呢?变的是字体的单位!PS默认字体单位为point,这个是印刷中的单位,表示这个字的物理长度。注意,是物理长度,而不是像素数。point的默认长度是1/72英尺,如果在72ppi的屏幕上,刚好是1px的长度。现在问题来了,如果你把图片的分辨率设置成了300ppi,那么PS就会“聪明”的识别出来,因为在300ppi中的物理长度变长了,因此,字也要相应的变大,同样是12pt的字,在300ppi中的字要使用更多的像素!

是不是被换算绕晕了?最后的结果是,设计师仍然以为pt和px是相同的,直接跟程序员说,这个字11个像素,程序员一写就瞎眼了。因为pt和px只有在72ppi下才相等。设计师改了ppi之后,这两个值就不相等了。

直接使用72ppi,即可!

那么设计师直接使用72ppi会不会有问题呢?没有问题。图片只认像素,屏幕才认ppi。如果设计师一定要使用其他ppi值,请在PS的首选项->标尺与单位中,将字体的单位选成像素pixel,这样告诉程序员那个字有多少个像素,也是可以的。

ClassLoader内存溢出-从tomcat的reload说起

原文链接:http://nius.me/classloader-memory-leak/

对于j2ee项目,一直使用eclipse的wtp,每次修改代码后,可以自动热部署。简单的项目wtp似乎没什么问题,但一旦项目代码稍微多一点,就很容易出现各种莫名其妙掉挂的现象,不得不整个重启tomcat服务器,这个时候就很痛苦了。

于是,我换用了maven的jetty插件,启动一个轻量级的jetty服务器,这下热部署似乎没那么多问题了!但是jetty似乎在热部署几次之后,也仍然会崩溃!这是什么情况!tomcat和jetty到底发生了什么?jetty的崩溃最常看见的异常就是OutOfMemoryException,Perm区的内存占满了

short version

不要慌!为了节省时间,先上解决方案:classloader-leak-prevention

  1. 在maven中添加如下配置:
<dependency>
  <groupId>se.jiderhamn</groupId>
  <artifactId>classloader-leak-prevention</artifactId>
  <version>1.9.3</version>
</dependency>
  1. 在web.xml__顶部__添加一个listener
<listener>
    <listener-class>
        se.jiderhamn.classloader.leak.prevention.ClassLoaderLeakPreventor
    </listener-class>
</listener>
  1. 去西湖玩一天

long version

看看Perm区到底都是些啥

今天实在忍不了了,上Visual VM,监视一下Perm区的情况。

果然,reload几次之后,Perm的使用量蹭蹭的往上涨。看看Perm区都是啥

怎么这么多char[]呀,好像也看不出什么,还是dump一下吧。中间翻阅了一些博客,觉得应该是class loader的问题。oql查询一下。(这里因为是jetty,所以查询了jetty的WebAppClassLoader,如果使用tomcat或者其他容器,应该有对应的Loader,可以通过Saved Queries->PermGen Analysis->ClassLoader Types看一下有哪些ClassLoader)


上图是刚启动的时候,WebAppClassLoader只有一个实例。经过两次reload,嘿,问题来了。如下图:

居然出现了3个WebAppClassLoader实例,前两个Loader都没有销毁!哟呵呵,gc销不掉,一会就进Perm区了,然后多几次reload,Perm区再大也都撑满了。

发生了什么,gc不靠谱?

首先,我们回忆一下gc的运作过程。通过minor gc,清理eden区(eden generation)的没有被引用的对象,活下来的进入suvivor区,接下来的minor gc会让对象在两个suvivor里面倒腾倒腾,挺过几次的进入old区,这里面进行的就是full gc了,耗时长,如果old区还挺了好几次,就会进入Perm区。Perm里面发生的也是full gc.

一个普通对象,只要没有引用了,就一定会在某一次gc被回收。那么ClassLoader进入了Perm,说明在reload的时候,虽然程序取消了对Classloader的直接引用,但是仍然有其他对象间接的引用了ClassLoader。其实如果单纯的仅仅是ClassLoader一个对象,也就罢了,但是ClassLoader并不是一个普通的对象。

任何一个Java类,都是通过某个ClassLoader加载的。通过这个ClassLoader加载的类的实例,会保存这个类对象的引用,也就是MyClass.class这种。而类对象,会保留这个ClassLoader的引用。反过来,在ClassLoader中,也会保持对这个类对象的引用。(注意区分类对象MyClass.class,不是这个类的实例。好吧如果还是混淆了,我也不知道该怎么说清楚了)。关键在于,ClassLoader和类对象之间是双向引用。

双向引用有什么问题嘛?一般情况下没有问题。因为如果ClassLoader的外界引用,和具体类对象的外界引用都消失了,那么这两个对象都不可达了,都会被gc。但是在一些情况下,类对象可能不仅仅被这个类的实例保存,还可能被其他对象保存!如果这个对象是其他OtherClassLoader加载的呢?那意味着,如果这个对象不回收,那么其引用的类对象不会被回收,于是ClassLoader不会被回收,于是,所有ClassLoader加载的类对象都不会被回收!WebAppClassLoader会加载多少个类?如果你恰好使用的是Spring、Hibernate这种大家伙,嚯嚯。如果对此很感兴趣,这里有一篇写的很详细的:Anatomy of a PermGen Memory Leak

怎么解决

你并不知道什么时候会出现某个外部对象会引用到类对象。所以解决问题的思路是,换一个ClassLoader。一开始的解决方案classloader-leak-prevention就是依赖这个思路的。核心代码如下:

      // Switch to system classloader in before we load/call some JRE stuff that will cause 
      // the current classloader to be available for garbage collection
      Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());

      try {
        java.awt.Toolkit.getDefaultToolkit(); // Will start a Thread
      }
      catch (Throwable t) {
        error(t);
        warn("Consider adding -Djava.awt.headless=true to your JVM parameters");
      }

      java.security.Security.getProviders();
      
      java.sql.DriverManager.getDrivers(); // Load initial drivers using system classloader

      javax.imageio.ImageIO.getCacheDirectory(); // Will call sun.awt.AppContext.getAppContext()

让这一段代码运行在servlet初始化之前,在所有的listener之前。

Using git without a center repo

Sometimes we do not want to use a center repo for many reasons. And we still can use git to transfer our codes, with the help of git bundle

To package your local commits, you can use:

git bundle create changes.bundle -1 master

-1 means package the latest 1 commit, you can package latest n commits with this command. And this command is identical:

git bundle create changes.bundle master~1..master

After packaging, you can send the changes.bundle file by any means (say, email) to your partner. Your partner then can pull the commits just like the remote repo:

git pull /path/to/changes.bundle master

It will just behave the same as you pull from a remote git repo.

中华琳娜

《爱情买卖》是一首很接地气的歌,被称为“神曲”。大约是觉得太烂俗了,所以一般听惯了流行歌的人都比较不屑这首歌。这种音乐种类间的互相不买账也一直存在,学院派根本就觉得流行是个渣渣,高端得来美声、民歌。唱摇滚的说我就是要颠覆你们,一切现存的都是颠覆对象。

把学院派的民歌歌手龚琳娜放到一群唱通俗流行歌的选手中间PK,按照传统逻辑,嗯。

龚琳娜唱歌的思路很明显,就是用音乐表现一切可以表现的东西。《金箍棒》很多人说欣赏不了,其实这就是《金箍棒》表达的内容。孙悟空是个什么角色?大闹天宫,我行我素,本来就不是“正道”,你说用什么唱法去表现孙悟空?首先中国传统元素少不了,听起来得是个中国歌。孙悟空武艺高强,不把各路神仙放在眼里,所以歌曲一开始的“俺老孙”,唱的那叫一个飞扬跋扈,得意洋洋~这不是孙悟空是谁?后面的“呔哩个呔,呔哩个呔”,这不是孙猴子蹦来跳去,挥着金箍棒打来打去,大闹天空嘛!闹完了,孙悟空自封“齐天大圣”,气势磅礴,又有点孙悟空的嬉皮笑脸。

《金箍棒》一共就那么几个词,但一个捣蛋的孙悟空的形象已经完全在人脑子里形成了,完全不需要大段的歌词,听着听着,大伙就乐了。

相反,流行歌是严重依赖歌词的。你可以说流行音乐的旋律好听,但是不听歌词,你能知道流行歌在唱什么嘛?大部分流行歌做不到。

回到《爱情买卖》。这周全能星战,龚琳娜用来PK孙楠的歌曲,让所有人目瞪口呆。同一段旋律(主题),用民谣、流行节奏、爵士、吆喝、说唱、美声、花腔、戏曲、音乐剧、乡村摇滚,各种不同的唱法来表现,每种一小段。让人应接不暇。听完先是对龚琳娜佩服至极,学院派就是学院派,什么唱法都来一个,同时又感觉每种都没听爽,怎么一下就过去了呢。老锣解释,这是要表现现代社会,变化太快,就是要表现人们接受不过来的那种感觉。

你看,老锣编曲想表现的就是接受不了,很显然,他的目的达到了!但你让我说夸这首歌好听,这确实不如流行歌好听。

初中音乐老师在讲经典和流行的时候,说了一句话:“流行音乐就是要好听的。”这句话我当时十分不理解,这不是废话嘛?现在就觉得很好理解,流行乐除了好听,就没了。这种好听是用那些有限的几个大众能理解的和弦构成的好听,所谓“大众能够欣赏的音乐”,当然就是简单,熟悉,好听。所以流行乐要想创新是十分难的,因为创作的空间有限,你把歌剧里面大起大落的旋律放流行歌里,就没法传唱了,大部分人唱不了呀,那还怎么流行!?所以流行歌的创新确实是非常难的,发展也是很缓慢,大家都限制在“条条框框”里面,畏首畏尾,又不能烂俗,又不能难唱。

龚琳娜的歌,首首都难唱。只能听,不能唱。谁唱谁知道。全能星战里面翻唱了几首流行歌,也绝对把非常有特色、突破性的龚琳娜元素加入到里面了。第一首《明月几时有》,看把评委们吓的。网上评论非常好,为什么?龚琳娜一张嘴,苏轼的形象马上浮现出来,这才是音乐的表现力!龚琳娜一张嘴开始“啊”,很多人都听哭了。《小河淌水》也是,没有歌词的地方,反倒显得干净,表现力极强,这才是艺术,这才是音乐。

孙楠在这场比赛里说,艺术是有标准的。流行歌如果按照她的方式发展下去,就没法发展了。我觉得孙楠这两句说的都很对,但口气不对。首先艺术确实有标准,从艺术的标准看,龚琳娜的歌首首都是艺术。艺术本来就是要表现生活的,龚的《爱情买卖》,就是要表达这世界变化再快,商业化再发达,爱情还是不能买卖。这就是艺术。其次,流行歌确实不能按照龚琳娜的方式来发展。龚琳娜的歌大家都唱不了,怎么传唱、怎么流行,KTV怎么生存?这些话,其实在我看来恰恰是对龚琳娜极高的赞赏。

全能星战,本来就没有说是“流行歌”的舞台。龚琳娜也没有说要引领“流行歌”的发展。流行歌手听到龚琳娜,马上吓坏了,这样的歌以后变成流行歌,那我们还怎么混?当然变不成流行歌,龚琳娜和老锣本来的目标就是发扬中国传统音乐,至于音乐的具体表现形式,到现在为止好像还真没考虑过流行。这点孙大哥大可放心,真流行不起来,人家追求的艺术跟你的艺术就不是一种东西。

龚琳娜的“怪”,恰恰在于,龚琳娜唱的音乐,就从来不受拘束。根本就不是流行,不是一切所有已知的风格、形式、体裁。所以,大家只好称为“神曲”。因为没有办法形容。

依我看,不如龚琳娜的这种风格,就叫中华琳娜。洒脱不羁,自由浪漫,探索音乐中的无限可能。

龚琳娜 《爱情买卖》 http://www.bilibili.tv/video/av872088/
(B站上黄色的字幕把龚琳娜的音乐剧的故事性讲的很明白,欢迎欣赏)

苍南支教——音乐课

这次去支教的四个人当中,就我会识谱,会弹琴的一个没有,所以音乐课就全部交给我了,于是我除了4年级都教了一遍。小学的音乐说简单也简单,说难也难。说简单是因为让小朋友们听唱学起来很快,说难是要让他们安静的听你讲讲五线谱是怎么回事,简直太难了,根本听不懂,也不想听。课本上确实是用心选过的歌曲,中外的歌、曲、戏、剧都有,希望让小朋友们对音乐有一个完整的认识,免得以后只能欣赏流行歌。我小学的时候大概是没有意识到这一点,所以说给小朋友们,他们也不会明白。

课本里一般一节课会包含一些欣赏的曲目,一些是让小朋友们学唱的歌。欣赏的一般比学唱的复杂一些,但课本选的范唱也会对原曲进行节选、简化。三年级节选了圣桑《动物狂欢节》里面的《公鸡和母鸡》,确实很好听,我让小朋友们去听乐曲中的鸡叫声,咯咯哒!咯咯哒!有几个同学听出来了,但还是不买乐曲的帐,为什么不唱出来呢?我也回答不了,一句要学会欣赏啊!就糊弄过去了。6年级课本上有《图兰朵》,配合茉莉花教的。于是我就把图兰朵猜谜的故事跟他们讲了一遍,他们对猜谜特别感兴趣,就是猜完了,就把图兰朵忘了。当我说讲完国内各个版本的茉莉花,跟他们说,《图兰朵》可以算是外国版本的茉莉花时,小伙伴们都惊呆了。合着我前面铺垫了半天的图兰朵公主的故事都白说了。不说了,直接上张艺谋版本的《图兰朵》,大家听出这一段的庄严大气的茉莉花的旋律没有?小伙伴们说,舞台上的人好像僵尸啊,好恐怖啊。

低年级教的基本是儿歌,例如《小红帽》,二年级小朋友们都特别喜欢这首歌,我也很喜欢,多好听呀。高年级会有《茉莉花》这种绕来绕去的歌。孩子们的听谱能力还是可以的,先上一遍网上下好的范唱,然后我再一句句的示范唱一遍,他们跟唱一遍,基本就记住了。

中国人的乐感真是没的说。但是乐感好,就会让小朋友们自己改谱子啊囧。教5年级《雏鹰之歌》,中间一段几个音都是do,大概是do do do do 的样子,楞是被唱成了do do re do,我纠正了好几遍。孩子们才不管谱子呢,虽然他们都很想唱对,但估计对他们来说那里感觉就不是do啊,于是嘴里出来的还是不对,于是我就放弃了。嗯,不要在意细节。孩子们对节奏的把握也很好。虽然我在说了半天谱子上的浮点是怎么回事,他们还是一脸不明觉厉的看着我。但是我范唱一遍之后,大家就都按照正确的节奏来唱了,甚至大家一起唱的时候,我都忘了浮点,孩子们唱的还都是对的。孩子们的音域也挺不错,毕竟是童声,《茉莉花》最后一句饶来绕去的高音,6年级的小朋友完全hold住啊,虽然大家唱的乱七八糟的,但确实每个音都唱出来了。

找到课本上的伴奏、范唱是一件很不容易的事。理论上应该教师用书会自带光盘,但我其实上课都是提前去教室里随手拿一本学生用书。所以,得去网上下。好容易找到一个有对应歌曲的网站,还收费,幸好不贵,十块钱基本随便下了。另外,课本确实想与时俱进,于是弄了一些电视剧、电影的主题曲进去,结构都是孩子妈妈们、奶奶们小时候看的电影了,跟看着《爸爸去哪儿》长大的孩子们完全脱节啊。孩子们根本没看过这些电影,所以也没法与剧情、歌曲产生共鸣。不过要做到课本的与时俱进,确实也是一件难事。一年级时听一首什么歌来着,我一搜是一部5几年还是6几年的电影,歌是好听,可孩子们问,这是什么电影呀?我只好说,是一部老片,看起来不错。

说到与时俱进,我们一开始以为小朋友们都喜欢听流行歌,不喜欢课本上的歌。一教才发现,他们哪懂什么教流行歌曲呀,还是喜欢课本上的歌。我也喜欢,课本上的歌其实都挺好听的,而且适合小孩唱。估计只有初中二年级才会对课本上的歌嗤之以鼻,被流行歌蒙住双眼,当年我就是这样的,当时问来教务处玩的四年级小朋友,你们喜欢听什么歌呀?《外婆的澎湖湾》!于是我就惊呆了!这不是他们爸妈小时候的歌么?后来才发现是课本上教过的。你看,好听的歌不管到什么时候,都好听。

我们为什么换社交网路

突然意识到,这是换圈子的过程。

在成长的过程中,朋友圈子在不断的更换。但社交网络中,曾经的朋友仍然会一直是朋友,即使很久不再联络。但人们总是需要跟更亲密的当下的朋友有更多的交流,切换社交网络能够一定程度上满足这一点。

换圈子是一段时期就会发生的一件事。因此,微信之后,仍然会有机会留给后来的社交网络。

同时,我们仍然放不下老朋友,因此在各个社交网络间疲于奔命。

而又有那么一些朋友,无论换到哪个社交网络,彼此还是能看到对方的新鲜事。

科技改变生活?

看了黑镜第一季里面的3,你能够保留你所有的记忆,还能随时在眼睛里、墙壁上投影。这简直是一个加强版的google glass哇。

最终仍然是一个隐私的问题。男主不断怀疑自己的老婆有婚外情,并从小三和女主以及自己的记忆中寻找蛛丝马迹,一个劲的追究。关键是,这个追究本来是不可能的,因为大家都可以回放自己的记忆,这下变成可能了。= =b 最终妻子不堪忍受离去。

技术真的能够改变生活嘛?某些角度看可以。但同样也会引起很多问题。时间能够抚平记忆中的很多事情,一个可以回放的记忆,让这种自然的模糊不再存在。

产品的自信与时代的自信

每天,关注互联网的人通过rss阅读器、微博、知乎等等各种渠道,看到互联网的新闻。苹果推出了新的ixx。某某创业团队/天才少年/少女搞出某个牛逼玩意。国外又火了一个新产品,国内的山寨版情况如何如何。

信息时代,我可以很自豪的说,从技术资讯到产品资讯,再到产业资讯,国内完全可以做到跟国外没有延迟。大家阅读着同样的新闻,讨论着同样的next big thing。

我们看着硅谷做出来一个又一个新产品,阅读着一个又一个breaking news。

阅读-讨论。阅读-讨论。讨论的内容却无法逾越出硅谷的内容。大家讨论的出奇的一致。如果硅谷做出来了,山寨就可以做出来。如果硅谷没有做出来,似乎都还停留在idea阶段。本土自信的产品,可能微信算的上一个。

时代给了我们相似的眼光,相似的思考,相似的能力,相似的局限。下一个创业项目是什么?眼镜?腕带?还是微信平台?还有其他选项嘛?我们的时代,仅仅就这样了嘛?

Git stash

Sometimes, you may suddenly recall some emergency task in coding but you have already been working on your current work in a half way.

So you may want to save your work temporarily, but not commit the half-completed codes.

# git stash
# git checkout <another_branch>

 

When you come back to resume your previous work, you can simply do:

# git checkout <original_branch>
# git stash pop

 

That’s cool!