About wesleysong

Simply a Flash Actionscript engineer. Eager to try new things.

Georgia Tech 毕业典礼见闻

omscs-coc

2015年12月11日,作为 Georgia Tech 的 OMSCS项目的首批毕业生之一,我去学校和所有on-campus的学生一起参加了毕业典礼(commencement)。上图为 College of Computing 为2015届毕业生专门举行的 reception。

申请成功仿佛就在昨天,转眼间就毕业了,how time flies!

Commencement 是在学校礼堂举行的,场面十分宏大。

gatech-commencement-2015

毕业生们排队上台领取学位。

omscs-commencement-yingnan omscs-graduated

以下是其他一些相关链接:

毕业典礼视频,跳到 01:12:00 可以直接看 Computer Science 毕业生们。
来自 The Chronicle of Higher Education 以我这次前往GATech校园参加毕业典礼的经历而刊发的叙事报道,原文需订阅才能查看,点此查看副本
College of Computing 对项目第一批OMSCS毕业生的报道
由学校制作的第一批OMSCS毕业生资料页
同时,GATech Daily Digest 的11日刊,和 College of Computing 的11日刊都提到了OMSCS首批毕业生。

在 iTerm2 for Mac 中使用 rz 和 sz

大致的方法参见这篇教程,但是执行 brew install lrzsz 的时候站点SSL证书目前已经过期了,brew会安装失败,所以我在安装的时候做了一些workaround。

总体安装步骤详述如下:

  1. 安装 iTerm2,详见:http://www.iterm2.com/
  2. 手动安装 lrzsz
    1. 下载 lrssz 源文件:curl ‘http://www.ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz’ > lrzsz-0.12.20.tar.gz
    2. 解压缩:tar -xvf lrzsz-0.12.20.tar.gz
    3. 进入文件夹:cd lrzsz-0.12.20
    4. 准备编译:./configure
    5. 编译:make
    6. 安装:make install
    7. 建立连接:sudo ln -s /usr/local/bin/lsz /usr/local/bin/sz
    8. 建立连接:sudo ln -s /usr/local/bin/lrz /usr/local/bin/rz
  3. 下载 iTerm2 rz/sz 脚本
    1. 下载:curl ‘https://raw.githubusercontent.com/mmastrac/iterm2-zmodem/master/iterm2-recv-zmodem.sh’ > iterm2-recv-zmodem.sh
    2. 加执行权限:chmod +x iterm2-recv-zmodem.sh
    3. 拷贝到系统目录:sudo cp iterm2-recv-zmodem.sh /usr/local/bin/
    4. 下载 curl ‘https://raw.githubusercontent.com/mmastrac/iterm2-zmodem/master/iterm2-send-zmodem.sh’ > iterm2-send-zmodem.sh
    5. 加执行权限:chmod +x iterm2-send-zmodem.sh
    6. 拷贝到系统目录:sudo cp iterm2-send-zmodem.sh /usr/local/bin/
  4. 增加 iTerm2 触发器(Trigger)
    1. Profiles -> Open Profiles -> Edit Profies -> Advanced -> Triggers -> Edit
      1. rz
        1. Regular Expression: rz waiting to receive.\*\*B0100
        2. Action: Run Silent Coprocess
        3. Parameters: /usr/local/bin/iterm2-send-zmodem.sh
      2. sz
        1. Regular Expression: \*\*B00000000000000
        2. Action: Run Silent Coprocess
        3. Parameters: /usr/local/bin/iterm2-recv-zmodem.sh
  5. 大功告成!

将MySQL中的数据导入ElasticSearch

在海盗湾上下载到了AshleyMadison的数据,脑子一热想拿来试试数据挖掘,于是拿ElasticSearch搞起。但问题是源文件为MySQL的dump文件,将其导入到MySQL中之后还不够用的,为了方便搜索,需要将数据再导入到ElasticSearch中。在网上找了很多相关资料和方法进行尝试,出现了各种各样奇怪的错误。最后终于折腾成功,记录一下。

首先,重要的事情说三遍:版本号一定要相互对应,版本号一定要相互对应版本号一定要相互对应版本号不对的话,会出现很多奇奇怪怪的错误,挖下去会是各种无底洞呀……

简单记录一下我的历程:在DigitalOcean上新建了一个Droplet,按照DigitalOcean提供的ElasticSearch安装教程安装了ES 0.90.7,之后按照这篇记录中的方法尝试使用river插件导入,无果。原因是,ES版本不对应。折腾了半天之后发现目前比较靠谱的方法应该是使用elasticsearch-jdbc来直接进行数据导入。

以下为一些简单的命令记录,如果也是用Ubuntu 14.04的同学可以直接拷贝使用。

版本:
ElasticSearch: 1.7.0
elasticsearch-jdbc: 1.7.0.1

1、下载 ElasticSearch 1.7.0

wget https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.7.0.deb

2、安装 ElasticSearch 1.7.0

dpkg -i elasticsearch-1.7.0.deb

3、配置 ElasticSearch 1.7.0

vim /etc/elasticsearch/elasticsearch.yml

之后修改 network.host: localhost

4、启动 ElasticSearch 1.7.0

service elasticsearch start

5、下载 elasticsearch-jdbc 1.7.0.1

wget http://xbib.org/repository/org/xbib/elasticsearch/importer/elasticsearch-jdbc/1.7.0.1/elasticsearch-jdbc-1.7.0.1-dist.zip

6、解压 elasticsearch-jdbc 1.7.0.1

unzip elasticsearch-jdbc-1.7.0.1-dist.zip

7、配置 elasticsearch-jdbc 1.7.0.1

新建一个.sh文件: vim import.sh

文件内容

bin=/data/elasticsearch-jdbc-importer/bin
lib=/data/elasticsearch-jdbc-importer/lib
echo ‘{
“type” : “jdbc”,
“jdbc” : {
“url” : “jdbc:mysql://localhost:3306/<dbname>“,
“user” : “<dbuser>“,
“password” : “<dbpass>“,
“sql” : “select * from aminno_member_email;“,
“index”: “am“,
“type”: “email
}
}’ | java \
-cp “${lib}/*” \
-Dlog4j.configurationFile=${bin}/log4j2.xml \
org.xbib.tools.Runner \
org.xbib.tools.JDBCImporter

注意红字部分需要根据自己需要进行替换

之后 chmod +x import.sh

8、执行导入

./import.sh

9、测试导入结果

curl -XGET ‘localhost:9200/am/email/_search?pretty&q=*’

微信JS自定义分享接口失效问题描述以及应对办法

微信团队在跨年夜送给了广大开发者一份大礼——直接粗鲁地禁掉了微信内的JS分享API,具体影响为:
1、分享气泡的题目会变为当前页面标题;
2、分享气泡的图片会变为页面代码中出现的第一张图片(无法完全确认,目测是微信客户端的网页解析逻辑);
3、分享气泡的URL只能是当前的URL;
4、分享气泡给单个好友或群聊时,气泡描述为当前URL;
5、无法获取客户端触发了分享行为,也无法获知分享操作的结果

基于这种情况,开发者目前已经无法直接通过微信的JS API对分享气泡进行定制了。

好消息是,开发者还能利用上面的默认规则1~3对分享出去的气泡进行浅层次的定制,方案简述如下:
1、将分享的标题设成页面标题(此改动会对用户体验有一定的影响,但影响比较次要);
2、在页面最前面插入一个用户不可见的img标签,专门用来存放分享图,hack分享图片的解析逻辑;
3、微调业务逻辑,在每个可能触发分享的页面的URL中都要附加上用于分享的参数信息。因为各业务的具体流程有所不同,需要case by case分析。总体而言,将分享信息放在url的search或fragment里都是不错的思路,特别是放在fragment中时可以不触发页面刷新,对用户体验而言比较无伤。
4、无法使用分享回调的问题可以从游戏设计上规避,把“发出分享后主动发奖”类的流程,改为“对方点开气泡接受邀请之后,再发奖给邀请者”。

充分利用微信分享相关功能一直是大家做HTML5小游戏设计时的重点,此次微信的调整也给H5游戏设计者指了一条道路,即:在设计时,可以设置一个专门的分享页,在需要引导用户分享的时候,首先跳转到该页面,然后再让用户自己去触发分享。依此设计的游戏在QQ、人人和微博分享时也能够转起来。

有个问题是,“分享气泡的图片会变为页面代码中出现的第一张图片”这个无法完全确定。但是我自己在开发的时候,还没有发现分享图URL不是第一个img tag的src属性值的情况。

以上技术方案权当抛砖引玉,欢迎亲们在下方留下更多的思路,一起讨论:)

在Unity游戏中使用Parse或AVOS Cloud组件

Parse和AVOS Cloud分别是国外和国内相对比较靠谱的BaaS提供商之一,然而在尝试将它们的SDK整合到自己的Unity游戏进行发行的时候,遇到了一些问题,记录如下。

问题重现方法:
1、按照官方说明,将SDK加入Unity项目中;
2、输出到iOS或者Android平台时,选择Stripping Level为Use micro mscorlib;
3、输出的时候Unity会报错,提示file not exist等…

问题原因:
Strip code的时候把Parse/AVOS Cloud的反射相关功能一并砍掉了。

问题解决办法:
1、Stripping Level不要选择Use micro mscorlib,改为Strip bytecode即可正常输出工程文件;
2、在Unity工程的Assets目录下增加一个link.xml文件,将Parse相关的库放进去,防止被一起Strip掉。文件内容如下:








使用Genymotion调试Unity发布的Google Android Project

需要解决的几个问题依次是:

1. 使用Unity打包发布Google Android Project
2. 使用Eclipse导入这个Project
3. 在Eclipse里调出Genymotion,启动应用调试

遇到了如下这么多坑:

1. Unity发布出来的Project Folder, 使用Eclipse不能直接导入
> 解决方法:先用Eclipse建立一个Google Android Project,然后把Unity发布出来的所有文件拷贝进去

2. Genymotion不支持Arm架构处理器和GApps
> 这个就说来话长了,为了解决这个问题,在网上找了好久解决方案…
> 解决方案的原文在这里:http://forum.xda-developers.com/showthread.php?t=2528952
> 如果能按照里面说的一步一步做下来,倒也没有任何问题,关键是有些版本的Genymotion对于拖入文件处理不同
> 有些可以直接安装,我的版本是把文件拷贝到了 sdcard/Download 里
> 对于这种现象,解决方案是,安装Root Explorer,然后把Genymotion-ARM-Translation.zip解压出来的System文件夹与安卓系统根目录的System文件夹合并,之后使用adb做一次reboot

Learning Grunt

1、安装方法
sudo npm install -g grunt
sudo npm install -g grunt-cli

2、基本启动流程
grunt.initConfig(); //初始化配置
grunt.loadNpmTasks(); //加载任务
grunt.registerTask(); //注册任务
3、各种插件
JS合并 grunt-contrib-concat
JS合并、混淆、压缩 grunt-contrib-uglify
CSS压缩 grunt-contrib-cssmin
文件复制 grunt-contrib-copy
图片压缩 grunt-contrib-imagemin 依赖于 jpegtran-bin
HTML压缩 grunt-contrib-htmlmin
4、各种插件遵循的基本配置格式
{
     “options” :
     {
          //特定于插件的各种配置
     },
     “procedure_name” :
     {
          //特定步骤的配置
          //一般会有files配置
          //可以是Object格式
          files : {
               ‘DestinationFileName’ : ’SourceFileName’
          }
          //可以是Array格式
          files : [
               {
                    src : ‘源地址’,
                    dest : ‘目标地址’
               },
               //或者可以为各种扩展出来的格式
               {
                    expand : true,
                    //这里是各种扩展出来的属性
               }
          ]
     }
}

Georgia Tech Online Master of Science in Computer Science 项目经验分享

项目关键词:
工科名校,计算机硕士学位,MOOC授课,价格低廉

GaTech,乔治亚理工,美国工科名校,计算机系在US排名前列
学校介绍详见 http://en.wikipedia.org/wiki/Georgia_Institute_of_Technology
OMSCS项目介绍详见 http://www.omscs.gatech.edu/
MOOC详见 http://en.wikipedia.org/wiki/Massive_open_online_course

项目时长:2~6年
项目花费:全部加起来7000刀左右,性价比极高,适合经济条件不宽裕,并且不想中断当前工作的同学
适合人群:计算机相关专业本科毕业,有一定英语水平,目前从事与计算机科学相关的岗位,对名校硕士学历有追求,经济条件不宽裕

对申请者的最低要求:
1、拥有4年本科计算机科学相关专业学士学位;
2、本科成绩GPA在3.0/4.0以上;
3、托福成绩100+ (没有严格要求,最好能考到90以上)

————————个人申请经历————————

背景:
本科西安交通大学计算机科学与技术系2011届,毕业后一直在大陆从事互联网类开发工作,GPA 3.2/4.0,英语相对较好

关键时间点:
2013年5月份在cnBeta上看到相关新闻,加入Mailing List;
2013年9月份突然得到项目开始接受申请的消息,决定尝试申请;
2013年9月下旬赴柬埔寨裸考TOEFL,10月4日得到成绩106;
2013年10月9日写完Statement of purpose、Background Essay;
2013年10月14日搞定三份Recommendation Letter并成功提交申请;
2013年12月,得知申请结果:申请人数爆棚,未能录入Spring Semester;
2014年3月,申请复议,被告知发错了录取通知,实际上已录取,录入Summer Semester;
2014年4月,邮寄补充材料,完成入学注册;
2014年9月,完成Summer2014学期课业,获得3学分;
2014年12月,完成Fall2014学期课业,获得6学分;
2015年5月,完成Spring2015学期课业,获得9学分;
2015年9月,完成Summer2015学期课业,获得3学分;
2015年12月,完成Fall2015学期课业,获得9学分,并赴GATech校园参加毕业典礼

————————申请注意事项————————

1、GPA的计算是有很多水分的。有很多种算法,官方渠道的话,可以花一点小钱去WES网站上估算一下GPA。申请的时候填写几种算法算出来最高的那个。有任意一种算法到了3.0就能满足条件了。

2、去学校打印成绩单的时候,可以顺便把学历学位证明也办了。申请时只需在网上提交本科成绩单的电子文档,而一旦申请通过就需要向GATech邮寄官方材料了。个人因为在申请通过后又回学校办了学历学位证明而耽误了一周多。

3、就推荐信而言,GATech官方建议,找学校老师和单位领导比同班同学和同级同事会更有说服力。整个推荐流程是在网上完成的,在申请者提交了推荐人信息之后,系统会往推荐人邮箱里发送一个链接,由推荐人点开链接完成表格录入。

4、建议尽早准备TOEFL考试,因为需要有这个成绩才能提交申请。注册TOEFL考试的时候建议直接填写成绩的接收学校为GATech,这样就不会浪费一次免费寄送成绩的机会。笔者没有合理利用TOEFL的免费邮寄成绩的机会,在提交了申请后又额外花了几十刀寄送成绩。

5、有任何问题一定要多写邮件甚至打电话询问。这个项目的申请人数很多,很多资源都要自己主动争取。

————————2014/10/07补充:上课感受————————

截止到2014年10月7日这天,Summer2014小学期已经结束,Fall2014也过了一半,谈谈我至今为止对OMSCS的感受吧。

考虑到Summer小学期时间比较短,并且需要为自己重新进入学生状态预留一定的“缓冲期”,所以我一开始并没有选择workload特别重的课程。另外,由于人还在大陆,网络环境不太适合使用ProctorU进行在线考试,所以倾向于选择仅基于assignment进行评分的课程。综合多方面因素,我最后选择了课业负担比较轻的CS6300 Software Development Process作为参与OMS CS的第一门课。

果真如之前上过该门课的同学们所说,SDP这门课的课业负担比较轻,作业量并不大。Udacity上的lecture内容很丰富,老师请来了很多在软件工程方面比较权威的人参与了录制,并且还留了很多补充内容,供感兴趣的同学查阅。课程得分是完全基于assignments+projects的。Assignments由个人完成,Projects是由自己的team共同完成的。在课程一开始,老师让大家完成了一个表格,填写对于分组的选择倾向(基于编程经验、空闲时间等)。在把team定下来之后,基本上就是要每两周交替完成individual assignments & team projects的样子。总体而言难度和复杂度都不大,甚至有些时候因为总体工作量太小了,老师明确要求大家合理分配工作量,免得有人比较积极,多贡献了10分钟,导致其他同学无事可做… 每个team project完成之后,每位组员还要填写一个表格,评价在此project中自己及同组所有人的贡献情况,team总得分乘一下个人贡献度才是自己的最终得分。所有人的成绩出来之后,老师将成绩分布normalize了一下,根据排名百分比,最后给出了letter grading。

上完这门课,我基本摸清楚了OMS CS的学习方式:
– 在Udacity观看lectures
– 使用Piazza与讲师&同班同学互动
– 使用GATech的校园内部系统T-square查看作业、提交作业、查看作业批改情况及成绩
– 使用WebEx或者Google hangout进行在线视频答疑(每门课可能不一样,取决于讲师)
– 使用ProctorU进行在线考试(如果有的话)

在SDP的成绩出来几天之后,就到了Fall2014的选课时间。因为有了之前上课的经验,我感觉这次可以挑战较难的一些课程了。参考了各个专业方向的要求之后,发现CS6505 Algorithms的适用性最广,基本每个方向都要求修这门课。虽然早有耳闻此课在undergraduate阶段是最难的,但还是毅然决然的选了它。由于是大学期,不再有了只能选一门课的限制,考虑到各方面因素,选择了课业负担较轻、内容相对简单、得分完全基于individual assignments的CS6250 Computer Networks——难易搭配相对靠谱一些嘛。

选完课交了学费过了一两周就开始上课了。果不其然Algorithms很多都是讲理论的,对于抽象逻辑思维的要求比较高。但个人还是感觉比Advanced Operating System和Machine Learning都好一些(听说AOS的第一个作业是拿C写一个线程库唷)。从第三周开始,发现有些lecture开始听不懂了,反反复复看了好几遍都不懂,于是果断入手教材,并在网上找了很多资料辅助学习,终于把晦涩的内容啃了下来。值得一提的是,lecture的长度其实都不算长,但是消化这些知识,需要自己查阅很多其他的相关资料辅助学习,基本上需要其8倍的时间左右。更不用提assignments了,每次会留5道左右的题目,基本上每一道都要啃两三个小时。好在讲师和TA都比较认真负责,在piazza上也给了大家很多指导,所以虽然课程比较难,但还是顺利地进行了下去。再过半个月就是Algorithms的mid-term了,希望自己的VPN给力一点吧,至少不要在用ProctorU的时候抽风。

至于CS6250简直匪夷所思,开课几天之后丝毫不见动静,Udacity上的所有内容还都是上个学期的,t-square上没有任何announcement,也没有人主动邀请进入piazza。过了一周之后,讲师终于出现了,说不好意思啊记错时间了记成一周之后了,大家呵呵呵呵… 之后就是很规律的看lecture,做assignment了。这个assignment也很奇葩,一般留半个月完成一个assignment,但是老师自己给出的代码经常有各种bug,导致很多人做的时候掉进了坑里,在piazza上提问反馈了,之后才有assignment update。连续三个assignment都是这样的,于是我决定只在deadline的前两三天再开始做CS6250的作业,这样首先会确保作业本身不会有大的bug存在,遇到什么问题还能去piazza搜索。总结下来这半个学期对CS6250的感觉,就是“不靠谱”三个字了。

————————2015/12/24补充:项目总结————————

已经毕业了,只是想说,选课需慎重啊,一学期三门课真的会死人的……

Unite China 2014

QQ20140413-1@2x

Recently I’ve been focusing on Unity3D mobile game development when I heard about this Unity’s developers conference to be held in Beijing. Lucky that I got a free ticket from a friend of mine who happens to work for CSDN, which is also one of the hosts of this conference. There’re some very informative sessions on Unity game development and Unity 5 new features. Also there is a real-time motion capture dancing show, which is impressive and much beyond my expectations.

Following are some points that impressed me the most.

Session #1 Development, management and publishing strategies for Unity projects
Of all aspects, art resources influences the whole project the most.
There should be tools or scripts for validating art resources.
When seeking optimization, more time should be focused on CPU / logic parts than GPU / shaders.
Different aspects regarding code architecture should be based on project targets and aims, such as whether use incremental update or not, whether the size of installation package should be strictly restricted, whether the game should support low-end mobile devices, etc.
Regarding memory management, reducing texture sizes is always the most effective way, noting there’ll always be trade-off between art effects and program performance.
The new asset bundle feature is an optimized way of handling resources.
Try not to dispose frequently used UI resources when going through different scenes.
Multi-threading on loading assets might cause drops on performance, so choose the number of threads wisely.
Use of legacy particle systems is depreciated.

– to be continued

Integrate Google Analytics and Admob into Unity3D

Recently I’ve been focusing on mobile game development using Unity3D and fount it necessary to add some plugins to monitor user actions and monetize. After searching on the web for some time, I decided to utilize Google Analytics and Google Admob. However it did take me some time to integrate them into Unity3D project. So I’m simply listing all the things I have done in case this might be helpful to you.

Integrate Google Admob into Unity3D project for iOS

1. Register on Google Admob and get a publisher ID.
2. Download the latest Admob plugin for Unity3D on Google Developer’s Website .
3. Import Admob plugin to your Unity3D project.
4. Add C# code for showing ads. Remember to modify publisherID in the code.
5. Build an Xcode project from your Unity3D project
6. Download the latest Google Admob SDK for iOS from Admob’s Official Site.
7. Follow the instructions listed in the ReadMe file to be able to compile :
7.1 Add SDK files into the Xcode project
7.2 Add “-ObjC” flag in Other Linker Flags in Build Settings
7.3 Import libraries and frameworks needed by SDK, including: AdSupport, AudioToolbox, AVFoundation, CoreGraphics, CoreTelephony, MessageUI, StoreKit, SystemConfiguration
8. Build the project and test your app out on your device.

Actually some weird problems occurred while finishing these steps…

Problem #1 :
When building the project, the linker outputs “library not found for -liphone-lib”, which terminates the building process.
Reason :
It seems that when adding files from the Admob SDK into Xcode project, the Library Search Paths param in Build Settings is not modified in the right way.
Solution :
Modify Library Search Paths param in Build Settings, delete the \” characters in the beginning and ending position so it is exactly  $(SRCROOT)/Libraries

Problem #2:
My code called the method AdMobPlugin.CreateBannerView and set the param positionAtTop to false, hoping the ad banner will show at the bottom of the screen. To my disappointment, that param is not working at all. The ad will always be showing at top.
Reason :
The implementation for CreateBannerView is not complete in the SDK. The flag is not working.
Solution :
Open AdMobPlugin.mm file in the Xcode project and modify the createGADBannerViewWithPubId method like this :

 - (void)createGADBannerViewWithPubId:(NSString *)pubId bannerType:(GADAdSize)adSize
{
    self.bannerView = [[[GADBannerView alloc] initWithAdSize:adSize] autorelease];
    if (!positionAdAtTop_)
    {
        [self.bannerView setFrame:CGRectMake(self.bannerView.bounds.origin.x,

                                             UnityGetGLViewController().view.frame.size.height - self.bannerView.bounds.size.height,

                                             self.bannerView.bounds.size.width,

                                             self.bannerView.bounds.size.height)];

    }
    self.bannerView.adUnitID = pubId;
    self.bannerView.delegate = self;
    self.bannerView.rootViewController = UnityGetGLViewController();
}

Everything is working properly now :-)
Still another thing to note, the AdBannerView won’t get destroyed when we create a new one. It will definitely cause memory leak.

Integrate Google Analytics into Unity3D project

Google Analytics is a very handy toolset for indie game developers. It is easy to set up and totally free. Thanks to Mass Threat Labs, we can finish GA integration in minutes.
1. Set up your Google Analytics account.
2. Download the plugin on Mass Threat Labs’s website.
3. Import the plugin into your Unity project.
4. Drag the prefab into your first Scene.
5. Call the API anywhere you want to report.

The real-time graph is super cool =]