相见恨晚的双拼输入法

随着需要输入的中文越来越多,自然就开始研究起提高打字速度的方法了。这当然不是什么新想法,上小学的时候就知道有五笔打字,多多少少也练过一点。不过最后也没有真正投入日常应用,说到底还是没有刚性需求,全拼已经可以满足各种需要了。然而如果真的需要大量码字的话,全拼就显得捉襟见肘了。
各种形码的优点很多,但是缺点是学习曲线比较陡峭,从开始学习到形成肌肉记忆需要一段时间。双拼就不一样了,一两个小时能上手,一两周就能达到实用性很强的速度,可以说是在学习难度和输入质量之间取得了平衡。现在用双拼打字也有了半年多的时间, 真的是省了不少力气,不由地感叹如果早开始用的话,这么多年得省下多少时间。
双拼方案有很多种,选哪种都没有太大的区别。我选的是小鹤双拼,除了因为名字听起来比“微软”“搜狗”感觉好一点,本身也有一点独立开发者的味道。各种第三方输入法都支持,Android和iOS系统自带。双拼的原理非常简单,单声母和单韵母不变,然后把长度在两个及以上字符的声母和韵母分配到特定的键上。官方的口诀写得很高端,什么“秋闱软月云梳翅,松拥黛粉更航安。快莺两望奏夏蛙,撇草追鱼滨鸟眠。”“秋”就是”iu”这个韵母在q上的意思。其实我是根据自己熟悉的东西记忆的,比如in这个韵母在b上,那不就是老式的二进制文件扩展名”bin”. 再比如ie在p上,”pie”比“撇”更好记。”书””吃”也比”梳””翅”要常用得多。稍微练习一下就可以开始打了。感觉非常神奇,因为从小就用全拼打字,忽然换了一种方式。开始当然会感觉有点别扭,熟悉了之后反倒是打全拼的时候需要停下来想想,甚至打其它语言的时候都想不由自主地按下对应的缩写。
用了双拼之后最大的好处当然就是速度的提升。这里说的不是打字比赛的那种一分钟多少字,而是主观上的体验。相信大家多多少少都有手跟不上大脑思考速度的体验,尤其是打音节长的字词的时候,比如一个”shuang”就要六次击键,中间打错一个可能还要全删了,非常麻烦。双拼就直接简化成”ul”,不管多长的音节都是两次击键,这样就能极大地改善手跟不上思考速度的问题。从物理角度来看也有效果,用全拼打了几千字的话手会很累,用双拼的话就好多了。
当然双拼本质上还是音码,依然有重码率高的问题,还是要依赖词库。另外在打某些常用词的时候就不能像全拼一样可以缩写。少量没有歧义的词还可以,”dbq”还是可以打出”对不起”,但是”bdxa”就不能打出”保登心爱”了。全拼打错字的时候还可以比较容易地推断出本来应该是哪个字,双拼的话打错了就差得特别远,所以打完之后再看一遍就更有必要了。
对台湾比较熟悉朋友可能会想到,这个有点像注音输入法。不过双拼比注音输入法的平均击键数更少,对于熟悉拼音的人来说学习难度也要低很多。当然注音因为要输入声调,在重码率上还是有一点优势。其实小鹤跟其它双拼方案最大的不同是它还有一套“小鹤音形”方案,在双拼两个键的基础上再加两个键的形码,由此可以做到盲打。前面提到过形码的学习成本比较高,而且目前双拼已经可以满足需要了,所以没有仔细研究过。

Puppeteer基础经验

Puppeteer是一个通过Chrome DevTools Protocal程序性操作Chrome的官方node库,其功能十分强大,Chrome能做的基本都能做。最明显的用处大概是抓数据,现在用各种framework写出来的页面通常直接http get只能得到一个加载页面,而真正的内容需要执行JavaScript才能加载出来, 放在Chrome里运行自然就不成问题了。当然最大的优点也是其最大的缺陷,那就是需要安装并运行Chrome,比较耗费资源,规模太大的话就不太适合了。
这次找到puppeteer是因为需要做一个生成Steam销量报告的工具。 这个信息只能手动登录查看,而且登录的时候会出现Steam Guard, 要输入邮件里的验证码才能继续。最后的解决方法是创建了一个bot用的Steam帐号,模拟用户操作输入,自动读取发到Gmail的验证码并输入,然后就能抓到数据了。同时还用了第二个功能,用html生成一个报告,直接放在Chrome里渲染成一个pdf发回来。用浏览器渲染pdf可能有点小题大做的感觉,但既然Chrome已经运行起来了,就顺便了。下面记录几个个人在开发中遇到的问题。

1.运行环境

Puppeteer默认会下载Chromium. 这个可以通过在npmrc里写PUPPETEER_SKIP_CHROMIUM_DOWNLOAD来避免下载,或者直接安装puppeteer-core. 这样配合chrome-launcher就可以很灵活地启动不同版本的Chrome.

const launchOptions = {
logLevel: ‘silent’,
chromeFlags: [‘–headless’]
}
const chrome = await chromeLauncher.launch(launchOptions)
const debugPort = chrome.port
const resp = await util.promisify(request)(`http://localhost:${debugPort}/json/version`)
const {webSocketDebuggerUrl} = JSON.parse(resp.body)
const browser = await puppeteer.connect({browserWSEndpoint:webSocketDebuggerUrl})
const page = await browser.newPage()

开发的时候怎么来都可以,但是因为Chrome的存在,部署是个问题。开始本来想把整个功能放在AWS Lambda上,有人专门针对这个需要做了个瘦身版的serverless-chrome,能将将塞进50MB的空间里,但是由于最开始的设想是手动输入邮箱验证码,所以没有采用。然后转向了Elastic Beanstalk, 但是运行环境没有Chrome需要的dependency, 而且不能自己配置,最后还是搞了个EC2. 系统是Ubuntu 18.04LTS, 默认也是没有dependency,需要安装。由于需要输出PDF, 还需要安装字体,不然英文之外显示的是方块。

2.异步处理

一般说到JavaScript的异步处理就是用promise, 在操作puppeteer时则需要用到async/await的写法。Async返回一个promise, 而await是要等promise resolve. 无论是转向新页面、等待页面元素出现、获取页面内容,全部需要await, 很容易写丢。Await也只能在async函数里才能使用。

await page.waitForNavigation({waituntil:’networkidle2′});
await page.waitForSelector(‘#login_btn_wait’,{hidden: true, timeout:30000})
const successButton = await page.$(‘#success_continue_btn’)
await successButton.click()
const html = await page.content()

需要抓取的内容可以通过selector单独选取,但感觉需要获得的内容多了的话,与其一个一个await, 不如直接取得整个页面,然后用别的库来处理html. cheerio貌似很流行,可以用jQuery的写法。

3. 选择页面元素

自己写网页的话用不到很复杂的CSS selector,也就是选个class选个id, 但是解析别人写的网页就比较麻烦了,尤其是遇到需要选择的元素没有id的情况。其实CSS selector还有:nth-of-type(n), :nth-child(n)这些写法,而且能一层一层串起来,这样就能选到需要的元素了。这是个人之前没有注意到的。

4.异常处理

使用puppeteer需要处理的异常很多。首先http返回值不是200要处理,需要的页面元素没有出现也要处理,总之一不留神脚本就会停止执行。异常处理同时也可以作为判断页面状态的依据,例如一定时间内某个元素没有出现,就说明登录失败了。

try{
const response = await page.goto(url,{waituntil:’networkidle2′})
if (!response.ok){
console.log(“HTTP Error”)
}
}catch (err){
console.log(“Failed to load URL” + err)
}
try{
const contents = await page.content();
return cheerio.load(contents,{decodeEntities: false});
}catch (err){
console.log(“Most likely page is redirected”);
}
try{
await page.waitForSelector(‘div#header_menu’,{visible:true,timeout:5000})
console.log(“Login success”)
}catch(err){
console.log(“Login error ” + err)
}

5. Bot判定

这个要根据目标网站来调整。比如有的网站如果访问频次过快可能会屏蔽IP, 那么每次跳转页面之间就最好sleep上几秒。Puppeteer已经是在模拟用户操作,如果目标网站防bot对策不是很强的话应该没什么问题。但如果还是遇到Captcha的话就束手无策了。

USC CS Games课程总结

主要当作自己用的一个总结,同时也希望能给后辈们一点选课参考信息吧。本人是CS Games方向,但是在技术类专业课上所有CS方向还是有些重叠的,而设计类专业课跟IMGD(Interactive Media Game Design)专业有些重叠。CS Game比其他所有CS方向必修的学分都要多,我入学的时候是要求128学分。另外还多读了一年PDP(Progressive Degree Program),上了几门研究生级别的课程,拿个没有什么用的硕士学位。当然上课体验是很主观的东西,跟个人水平也有关。本人水平很低,进学之前没有基础知识,也不是什么好学的人,有上进心的同学的体验会很不一样。另外课程要求在这几年中也发生了变化,也不一定是谁来教了。虽然基本内容不变,但是上不同教授的课感觉也是很不一样的。

总的来说CS本科教学质量还是很高的,基本能保证小班授课,更容易跟教授套近乎。不用跟别的学校比,USC的CS硕士研究生课都是好几百人一起来,感觉就很不一样了。

最新的CS Games要求:https://www.cs.usc.edu/academic-programs/undergrad/computer-science-games/

这里只说专业课,关于GE另有:USC GE课程

CSCI系列

CSCI-180 Survey of Digital Games and Their Technologies

这门课已经绝版了。虽然挂的是CS,但其实应该是CTIN的课,讲的是电子游戏发展史和一些基本的游戏设计理念,用到的两本书是The Ultimate History of Video Games: from Pong to Pokemon and Beyond还有Theory of Fun for Game Design. 这门课可以说是对我人生都有一定影响。生在十八线小城市,在上大学之前说到玩游戏也只知道各种腾讯网游之类的,主机什么的根本就没摸过。这门课从第一款电子游戏的诞生开始,细数每一代的主机,当然也有PC游戏的崛起,带领我走进了以美国和日本为主的主流游戏文化。玩游戏这种事还要上课来入门感觉有点overkill, 但其实作为游戏玩家来说要补的还有很多。

上课的结构是先lecture, 然后给时间玩指定的游戏,之后用一套固定的方法来讨论分析这个游戏。Midterm除了考试,还要玩一款叫Psychonauts的游戏并写essay分析。也是第一次知道有Steam这个东西。这是个比较传统的动作闯关游戏,手残还打不过,作弊了才打通关,冠以为了完成作业的名义。当时的室友调侃说你简直活在每个少年的梦中,作业等于打游戏。Final除了考试还要模拟pitch一个游戏。

Instructor是St. John Colon, 在Square Enix工作过。当时啥都不懂,问过一些很愚蠢的问题,什么Galgame算不算游戏啥的。当年还没有EGG,在SAL上的,现在一排办公室的那个地方。

CSCI-281 Pipelines for Games and Interactives

主要教怎么用Maya, 先跟着教程视频学做一个Phantasm Ball,一个插了几个管子的球的物体,借此熟悉了基本建模操作还有UV怎么贴上去。然后找参考图做两个无机物的模型,汽车火车飞机这种,最后做一个有机物,用自己的照片做参考图。惨不忍睹。除了Maya也可以说是3D软件入门吧,游戏引擎的编辑器都会做得类似Maya等3D软件。

Scott Easley也是Game Program里一位很重要的faculty了。当时他在搞一个AR的实验游戏,还跟St. John Colon联合做了个小iOS游戏。他还找人检查这个游戏的localization, 当时帮着测试了几次,后来不了了之了。现在这个课在EGG上,没有EGG之前是在RTH三层上的。

CSCI-103 Introduction to Programming

这是第一门“正经”的CS课程了。每所大学的入门编程课程选择的语言都不尽相同,USC用的是C++. 这门课默认你没有任何编程经验,从基本IO开始,基本控制结构,数组,函数,结构和类,类的继承,指针,动态内存,栈,队列,向量,模版。相信很多人在入学之前都有这些基本功了。比较谜的是最后两周会直接上Qt,前五个作业都是命令行程序,最后一跃直接要求套GUI. 这对刚入门的的新手比较不友好啊,从一个大while loop改成event-based感觉几乎要重写了。这让我对Qt留下了非常不好的印象,从那之后再没有摸过Qt.

有幸赶上以教201闻名的Jeffrey Miller教这门课,这是他在开始在USC任教的第一次授课,教了一次103和一次104. Miller上课特点很明显了,永远穿着西服,讲课很有激情,然后课上带着一起写代码。女儿来卖小饼干是必备节目。考试除了笔纸考试以外还会有用电脑实际写代码的考试。在RateMyProfessor上Miller的评价两极分化,有人觉得他很无聊,考两次试很恶心之类的。个人是喜欢Miller的,觉得他重视实际写代码很有帮助,人也很好沟通,他是我找的两位写PDP申请推荐信的faculty之一。

CSCI-109 Introduction to Computing

109是103的co-requisite, 没有coding只讲很高层次的概念。涉及的范围还是很广的,每一项后来都会有专门的课来学。用一个CS Department教授写的书On Computing: The Fourth Great Scientific Domain,他自创了一套表示现实生活中各种场景和计算之间关系的表示方法,学这个比较谜。然后有计算机结构,算法,抽象计算,操作系统,图形学,AI,网络之类的介绍。每一项都不会很深入。印象比较深的是学图灵机和有限状态机什么的。

负责授课的是Gaurav Sukhatme. 这个是早八点的课在SAL,当时住Parkside, 7点59起来去上课都能提前到,直接继续睡,对这个人没什么印象了。Discussion占得比重很大,每次都有作业,最后还有个presentation,跟TA接触比较多。根据最新的syllabus,109已经从3学分减到2学分,并取消了discussion.

CSCI-104 Data Structures and Objected Oriented Design

CS核心课程之一。主要内容是数据结构,还有伴随而来的一些算法。写的东西基本都是在重新造轮子,C++ STL里面都有。最后一个作业可以选择用STL替代,当时觉得STL比自己写的map之类要靠谱多了。当时还是觉得挺难的,线性结构还比较好理解,后面红黑树什么的真的没搞懂。最后成绩也很差。

上的是David Kempe的session, 讲课不用幻灯片。有一个2013 Fall总结的课程笔记,就算是自编教材了,现在好像还在用。比较有意思的是刚开始两周和每个人都面谈一次,谈谈为什么学CS之类的。

CSCI-170 Discrete Methods in Computer Science

这个要和104一起上,算是学习算法的离散数学基础。讲逻辑关系,归纳法,概率,后面还有图论。非常惭愧,这种课作业考试从来都是一塌糊涂,实在是学不会,成绩在挂的边缘。现在C-好像要重修了。

选的Ming-Deh Huang的session, 讲课比较枯燥,后来都没人来了。同时著名的Aaron Cote也在开这门课,干脆去听他的了。

CSCI-201 Principles of Software Development

第一门非C++的课,用Miller的话说就是上完之后Java比C++还熟悉。涵盖的内容很多,花不少时间写Java的GUI,然后还有多线程,网络,并行计算。最后有个final group project, 基本要求是做个有网络功能的GUI程序。当时正好上完了CTIN488 Game Design Workshop,把final project设计的一个棋盘卡牌游戏拿来做。虽然从这门课以后就再也没写过Java了,但是熟悉Java其它高级语言也很容易上手,比如C#. 另外网络知识也很实用,这一套东西放在哪里都是一样的,实际写出来是很好的练习。

Miller在上面已经提到过,201的作业量还是不小的,要花不少小时数敲代码。当然喜欢写的话不会感觉很痛苦,看有人反应太耗时间受不了。

CSCI-270 Introduction to Algorithms and Theory of Computing

算法是程序员的基本修养,要进科技公司还是要会解算法题。很可惜到今天本学渣也做不出个动规题。经典算法就这几个大的话题,贪心,动态规划,分治,网络流,NP问题,感觉就是CS的四书五经,然而要搞懂真的不容易。仰望各位能把这点事搞清楚的同学们。

170提到过Aaron Cote, 270自然选的他的。记得Cote聊过,人家来当老师是真的喜欢讲课, 不然拿着CS博士学位去哪不都是优待。Cote每节课都会发handout, 记笔记和复习的时候都比较方便。270如果能拿A,而且而且有意继续上Master的话,可以找他写推荐信跳过570去上670,给PhD上的算法课。对于我这种270就挣扎的学渣来说670听起来就像玄学一样。

CSCI-360 Introduction to Artificial Intelligence

AI其实是很多不同问题的一个很笼统的总称,具体到每个问题有一个较好的解决办法。开始从逻辑证明引入,概率,介绍神经网络,贝叶斯网络。记得考试有根据输入数据手算概率。第二部分说借助SAT solver解决问题。最后一部分讲的是搜索算法相关的。

印象比较深的是第三个作业,写一个叫Adaptive A*的算法,算是A*的改良版,证明了一个新的heuristic value, 比直白的Forward A*要快一些。随手Google了一下,结果这算法就是教授Sven Koenig研究出来的,好吧。用的教材是Artificial Intelligence: A Modern Approach,课程从书中拿出了几个章节来。CS526也用这本书,据说内容差不多。

CSCI-423 Native Console Multiplayer Game Development

这门课名字看起来很高级,其实比较神奇。用一套叫Prime Engine的代码,给的教学视频日期是2009年。结构非常的复杂,要改什么东西的话需要修改好几个文件。运行起来非常神奇,加载东西用一个python小程序沟通,加载level用的是lua脚本,然后可以实时在Maya里编辑直接反应到引擎里。有点倾向于学网络的意思,介绍TRIBES networking model, 好像是鼓励写一个基于UDP的网络通信层。光看Prime Engine已经晕了谈何大改,最后的final project也就是应用一下提供的TCP通信,加上鼠标位置raycast能在地图上点出几个小人来。真不知道传说中的大佬们是怎么用这玩意儿做出FPS来的。

授课的Artjoms Kovalovs是真厉害,在Naughty Dog工作。当时正值Uncharted 4快要发售的时候,白天在Naughty Dog晚上还来上课。感觉他上课就是想起来啥就说点啥,当老师的话可能差点,不过水平真高。记得他演示了一下如何debug, 直接反汇编改内存,当时就震撼了。跟他交流能收获不少,他的数学功底非常扎实,做游戏需要的那一套3D数学。课前有根本不知道怎么答的quiz, midterm是写一个Windows下的C++程序跟一个server用TCP和UDP通讯。

CSCI-350 Introduction to Operating Systems

其实OS相关的知识之前在别的课程中多多少少都了解过了,多线程,并行处理,内存管理之类的。这门课的重头戏是作业,用的是一套斯坦福开发的叫做Pintos的代码。因为OS太复杂很难自己编出一套作业来。分四个部分:线程管理,用户程序(栈和syscall),虚拟内存,文件系统。当然都是真正OS的简易模拟版。Pintos是用纯C写的,随便一写就是全局变量全局函数。经常是不知道这一行是怎么实现效果的,找到源头发现是asm(此处插入汇编)。Debug是相当痛苦,因为本身是OS,所以要调用printf的话会出非常大的问题,因为printf本身是一个线程,在管理线程的代码里调用直接彻底乱了,要看什么值只能直接看内存。写这个东西实在是让人欲仙欲死。Pintos的自由度很高,理论上可以有自己的设计,爱加几个变量加几个变量。

还是少见的大班课,Tatyana Ryutov说话没调,很容易睡。考试比较宽容,都是理论问题。大部分时间还是为Pintos头疼。

CSCI-420 Computer Graphics

之前已经在ITP课程里接触到不少图形方面的内容了。还是那一套3D数学,渲染,光。说的几种曲线之前没有接触过。用OpenGL, 找了几个教程,结果一种事情有好几种写法,比较头疼。Graphics的东西也不好debug, 因为涉及到GPU和显存不像一般程序可以直接看内存。作业占一半成绩,第一个是渲染高度图,第二个是做一个过山车动画,一帧一帧来。第三个raytrace, 很费时的那种离线渲染。踩着十二点deadline做,结果发现出一张复杂的图要十几分钟,悲剧了。

这学期Jernej Barbic负责教420,做图形学的好像多少都做过电影特效之类的东西。说到graphics不得不提Hao Li, 很厉害很有名,有时会教420.

ITP系列

Information Technology Program比起CS课程更注重实际应用。CS的理论跟实际写代码还是有一定隔阂的,我这种脑子不灵光的学渣更倾向于做个没有什么技术含量的码农,比较喜欢ITP课程。推荐有多余的学分多选几门,都是比较实用的内容。

ITP-280 Video Game Production

280说的多是设计方面而不是实际制作的话题。作业写一些短文,记得有一个是用League of Legend跟另一款忘了叫什么的MOBA游戏做对比,这是至今为止玩的唯一一局league, 为了做作业。那时候正赶上Flappy Bird忽然爆火,也有印象讨论这个。Project是用Gamemaker Studio做点东西,一个非常简陋的2D引擎,当时连Unity都不会用,final project简直惨不忍睹,黑历史。

Anthony Borquez是个很神的人,对中国游戏市场还有涉猎,当时在运营手游,展示后台数据是什么样子,还提倡用微信什么的。据说陈星汉大神做过这门课的TA.

ITP-380 Video Game Programming

强烈推荐,可以说是真正的技术入门课。3D数学,图形,物理模拟这些基础的东西,在一套以SDL为基础的仿Unreal 4结构的引擎里实际写比较复杂一点的C++,实现简单的物体交互,非常好的锻炼。最后一个作业稍微用一下Unreal 4,不许用blueprint全C++.

吹一下Sanjay Madhav, 想学习真正的技术就要加入Sanjay神教。游戏编程的基本功都会说到,作业编得有方向可循又不会是完全手把手,十分受用。Sanjay是我找的第二个写PDP推荐信的faculty.

ITP-485 Programming Game Engines

这可能是我最喜欢的一门课了,可以说是380的进阶版。每个作业都很精彩,调用SIMD指令集,自定义内存pool, Direct 11渲染,写Phong shader, 计算skeleton动画,特别有意思。最后一个是自己添加一个功能,我比较奇葩做了个level editor. 本身提供了level loader读取一个JSON文件,但是没有save功能。Raycast之后利用C++/CLI调出来一个C#写的对话框,可以编辑数值。存储的时候因为不知道类型直接用void*, 非常刺激。

也赶上了好时候,前半段是Sanjay教,后半段Jason Gregory来教。Jason是Game Engine Architecture这本书的作者,也在Naughty dog做lead engineer. 能进Naughty dog的当然都是神一样的人物,能在PS3硬件上做出Uncharted系列的效果。但是说到底还是那些数学,还是利用好内存,都是这么来的。

ITP-342 Mobile Application Development

ITP有两门移动端开发课,一个iOS一个Android, 这个是iOS版。这个其实可以说是给非CS专业开的课,一个组件一个组件的介绍,其实如果好歹写过一点GUI上手iOS是很快的。当然这么慢条斯理也可以说是基础比较扎实,用的是Objective-C, 早就知道syntax很奇葩,习惯一下也不是不能接受。很强调MVC设计,现在日新月异的业界好像不怎么待见MVC了,但是老方法还是可以用的。Final project要求调用第三方API,做个了用Google map + firebase实现共享位置的小程序。

授课的是Trina Gregory, 是前面提到的Jason Gregory的妻子。两人在各自的领域都颇有建树。非常蓝色,川普当选的时候说着说着说哭了。

ITP-382 Mobile Game Programming

这门课因为实在是没有时间中途drop掉了,开始是跟着教程做几个Unity小游戏,作为练习很不错。后面是自己做project, 有时间的话还是可以选的。

ITP-439 Compiler Development

这是Sanjay系列的最后一课,prerequisite是ITP-435 Professional C++. 很想上435但是实在是没抢上,给Sanjay发了个邮件就waive掉了直接上439. 好多CSGM同学都上了435,但是根本没人选439,我觉得很可惜。编译原理不会有实际的应用,能写出工业级编译器的人世界上一共就那么多,但是了解了之后就能更好理解程序语言是怎么工作的。前台的parsing, AST, 生成IR,优化和分配register, 都挺有意思。了解之后就能用编译器的眼光来看待代码,对进一步优化有帮助。作业用的是Sanjay编的一个基于llvm的编译器起名叫University Simple C. 可以实现基本控制结构,函数,递归,printf. 无聊把所有关键字换成别的,也算自创了一门程序语言了。

EE系列

CSGM专业对EE的要求非常低,都是在比较抽象的级别,不会去抠逻辑门什么的。

EE-352 Computer Organization and Architecture

抽象层面的计算机结构,CPU和内存hierarchy之类的。Mary Eshaghian-Wilner给我留下了深刻的印象,伊朗大妈,实在是太nice了。讲CPU pipelining, 拿出纸给同学,一张一张传,这就是pipelining. 做presentation,提交笔记,都可以得extra credit. 最后还只要去office hour就给extra credit, 她的办公桌上摆着糖,还给糖吃。

当然她是个很有争议的人物,听说其他faculty觉得她什么都没教,还跟学生起了冲突,搜她的名字能查到。她现在已经不在USC了。

作业是写MIPS,一种RISC汇编语言,印象比较深的是把所有寄存器都写纸上,里面存着哪个变量,一边写一边对照,还是花了不少时间的。

EE-450 Introduction to Computer Networks

一般都上CS353 Introduction to Internetworking, 我上的暑期课程选择了这个可以替代的EE450. OSI模型的每一层都讲到,常见的协议,NAT, congestion control之类的。因为是EE 的课感觉还是比较偏向底层,会说一些信号学的内容,CS的课可能不会说物理层吧。当然高层的也有,作业是在Unix下的C++ TCP编程,当时是本地的Ubuntu运行没问题,上传到aludra/nunki那个Solaris服务器上就出问题,非常谜。网络编程感觉通信本身不难,怎么处理好多线程才是比较头疼。这门课上的也是跌宕起伏,第一次midterm成绩特差, 不会算那些东西。第二次midterm有熟悉的内容,记得一道分配IP地址的大题,都得换成二进制很麻烦,写了一大张。Grading可以倾向分数高的考试和quiz, 非常大方。

Shahin Nazarian也是伊朗人,EE department伊朗人特多。当时也是睡着的时候比较多,现在想想那个夏天过得很有意思。

CTIN和CTAN系列

CTIN和CTAN是School of Cinematic Arts开设的课程,以设计类为主,也有一些技术类的课程但是对于CSGM不是必修。SCA还是很厉害的,电影学院排名基本就是第一。

CTIN-488 Game Design Workshop

非常硬核的设计课程,non-digital的在纸上进行。对于真正喜欢桌游的同学可能如鱼得水了,我是第一次接触这个世界,搞出来的东西也都是惨不忍睹,拿出来给人playtest简直是公开处刑。最后group project还要仰仗各位会设计会画画的大神。

Lecture在SCI108,那么大的放映厅一关灯就醒不过来了。Discussion占得比重很大,midterm写essay也都是在discussion时间。

CTIN-484 Intermediate Game Development

CTIN-489 Intermediate Game Design Workshop

这两个合起来叫Intermediate, 这是我认为的最好的CTIN课程。两到三人组队设计制作一个游戏,体验大多取决于队友。Instructor会模仿真正游戏开发的过程进行评价,还有多次开放的playtest, 看到真的有人发来玩自己做的游戏还是挺有意思的。这也是一次真正运用Unity的机会,不仅是做个小project试试那种感觉,从准备各种素材到打包出来整个流程都要经历一次。到现在有时候忘了怎么写什么东西还会打开当年这门课的project参考一下。Instructor不固定,赶上的是Peter Brinson和Jesse Vigil, 教intermediate的都是Game Program里耳熟能详的faculty.

https://youtu.be/5JIqQhhduUQ

CIN-485 Advanced Game Development

当时新开的课程,prerequisite是intermediate. 还是用的Unity, 做skeleton动画,利用NavMesh之类的。Arjun Prakash人挺好的,我说想用C#.NET写一套网络通信,结果在serialization上遇到问题了,帮我看了看,结果最后也没做出来,比较遗憾。

CTIN-497 Interactive Media Startup

Gordon Bellamy开的1学分课,每周请一位业界大佬来谈谈经历,偶尔会讨论同学们做的游戏。很多读MFA的人来上这个,人家做的东西都太高级。Gordon也是业界大咖,倾向做business方面的。最后还有机会单独谈谈职业规划,我当时说想去日本做游戏但觉得收入会比较低,他说你就只在乎收入吗。现在决定去日本也有这次谈话的一些因素吧。现在有很多新的CTIN课程学分少负担轻但是很有意思,有时间的话可以看看。

CTAN-452 Introduction to 3D Computer Animation

学Maya的课程,建模,动画,IK. 印象比较深的是上bump map, 第一次用离线渲染,用教室的工作站也得渲染几分钟。当时挖掘机梗很火final project做了个挖掘机,也是至今为止做的最复杂的一个模型了。Instructor是Dariush Derakhshani,写过Introducing Autodesk Maya 2016, 2015, 2014, 2013…等等,就是专业教Maya的。人也挺有意思,现在还记得他说我们这没有未成年人吧,然后F-word连发。一般上课的时候还是都装文明尽量不说这个的。

Advanced Game Project

AGP是最后一年模拟一个studio合作做出一个比较复杂的游戏,一个团队一般十几个人,也各有分工,有producer, 有artist, 有composer, 当然CSGM最多的就是做engineer. 目标和进度都由各自安排,faculty每周检查起监督指导的作用。我参与的AGP叫Skyshot,用Unreal4做的类似篮球的联网多人竞技游戏。个人来说感觉没做多少贡献,浑水摸鱼了,感觉很惭愧。也有幸看到了一些其它组的代码,别人做的怎么这么厉害。

USC的AGP可以大致分成SCA和Viterbi两种。SCA的AGP主要是本科CSGM和IMGD参加,相比来说艺术人才比较多,以SCA楼为据点。Viterbi的AGP是研究生CS Game做的,所以程序员为主,以EGG为据点,又叫Gamepipe. 两者有一些沟通,主要是招人方面,现在展示也放在一起展示了。另外SCA有游戏设计的MFA课程,我也看过一些他们的pitch, 如果说一般的AGP一看还能明白这是一个游戏,MFA的大神们搞的东西都感觉特别玄乎。虽然AGP是只有最后一年才正式选课,但是大三大二也可以volunteer, 比较可惜当初没有利用这个机会,怪自己啥都不会。

Bonus Track

Progressive Degree Program的是申请条件是GPA在3.2以上,加上两个faculty的推荐信,当然不用考什么GRE. PDP项目只能是CS General,要上另外的CS方向就要普通申请了。通常CS General需要28学分,且一学期只能上两门课8学分,所以要两年读完。而PDP减免到20学分,一学期可以上三门课,所以一年就可以读完。理论上大三申请成功的话大四就可以上500级课了,但是空余学分我选择了上ITP的课。另外因为人多500级的课可能需要等D-Clearance,不一定能上到想上的课。PDP可以在D-Clearance发放之前就直接注册上,不用排队。

CSCI-570 Analysis of Algorithms

还是270的那些问题,但就是学不会。晚上三个小时的超长lecture, discussion也跟lecture差不多。特点是作业完全不算分,爱做不做,成绩全在三次考试。两位instructor Shahriar Shamsian和Victor Adamchik讲课各有特点,讲得挺好的,可惜自己水平太差。

CSCI-571 Web Technologies

全栈技术都有涉及,HTML, CSS, JavaScript, PHP, Apache+Ngnix, AWS/GCP, Angular, Node.js, 最后甚至做mobile app. 这门课开始特别轻松,写点简单的HTML和JS. 后面难度陡然上升,第三个作业是写PHP,第四个作业要求用Angular/AngularJS, 并有一个express.js的后台。从纯JS直接上framework我是非常的不知所措,更别说Angular用的还是TypeScript, 最后用AngularJS凑合的。 第五个作业更是直接做iOS或Android的app, 因为我有一点iOS的基础所以不算特别吃力,就是超费时间,吃饭睡觉写代码。无法想像完全没摸过app开发的同学们是怎么从零开始的。

Marco Papa在Ratemyprofessor上评分还很高,我是比较不喜欢这个人。在piazza上问个问题总是得不到想要的答案,讲的内容都是入门级的,作业一下拉高那么多,基本都是自学的。考试也是事无巨细,非常麻烦。Web应该是入门门槛最低的程序员类工作了,但真要深究也是博大精深。我对前端抱有比较复杂的感情。

CSCI-526 Advanced Mobile Devices and Gaming Consoles

组队做一个游戏,虽然说是mobile devices但不是mobile也可以。这就是传说中的水课,只要好歹做出来一点东西别真的啥都没有就能拿成绩了。由Mike Zyda带领,这是Gamepipe的director,也是founder. 超厉害的一位人物,境界太高了。

CSCI-585 Database Systems

可以分成两部分SQL和NoSQL. 前部分是传统的数据库设计,照本宣科,写SQL. 做web当然多多少少写过两句SQL,但是这个真要深入研究起来也是博大精深,怎么把那么复杂的多重query套在一句里面很是费脑子。后半跟前半的画风很不一样,instructor也换人,介绍的是现在流行的NoSQL技术,还介绍了大数据和机器学习,只是大概说一些方法。作业也变成了试用一些软件,用了一下graph database, 最后还写了两句R.

两位instructor Olivera Grujic和Sathyanaraya Raghavachary风格很不一样,Olivera比较正经,Sathetanaraya显得风趣一些。有人说NoSQL的部分感觉都是介绍一下没学到什么真正的东西,我觉得了解一下还可以。

CSCI-576 Multimedia Systems Design

选这门课算是剑走偏锋,跟别的需要排队的课比起来这一门简直就算没人上的了。真的是多媒体,图像音频视频都有。说的是各种媒体的的表达和压缩。还是挺有意思的,因为媒体的最终目的是给人看,所以要从人观察的角度分析,利用人视觉上的特点压缩图像,利用听觉上的特点压缩音频。具体到方法上数学内容也不少。作业也挺有意思,模拟JPEG压缩算法。Final project做视频片段匹配,我很幸运遇到了一个大神,用opencv做各种高端分析,我基本就是给套了个GUI.

值得一提的是最后几堂课还乘车到Institute of Creative Technology参观。这做的可都是真正的高科技,带模拟光源的精细建模,自动补写小说的自然语言处理。当然少不了VR技术,Oculus Rift的创始人Palmer Luckey就在这呆过。因为是由美军出资设立的所以有很多针对美军需求的研究,治疗PTSD的VR,协助学习的软件等等。

Instructor是Parag Havaldar,也是业界有名人物,做过电影特效。用的课本也是他写的Multimedia Systems: Algorithms, Standards, and Industry Practices. 从泛泛的介绍到具体的算法细节都有,挺好的一本书。

Web Projects

CS571: Web Technology Homework

If you are a student currently enrolled in this class, please do homework on your own.

Source on Github

Project 1: Loan

Given a screenshot, create a static html page as close as possible.

Project 2: Airlines

Parse a json file using “vanilla” JavaScript.

Project 3: Stock (php)

Call AlphaVantage API with php to retrieve stock information. Charts of indicators are drawn with HighCharts. No other libraries were allowed.

Project 4: Stock (AngularJS and Node.js)

Similar to project 3 but built with AngularJS as front end and express.js as the back end. MarketOnDemand is used for autocomplete feature. Used Bootstrap to scale to different screen sizes.

 

Jquery Practice

Calendar

A simulated web calendar. Overlapping blocks are not completely resolved.

Slider

A slider containing 4 slides with basic animation.

域名转出花生壳或三五互联始末

现在的这个域名cwf123.com是在2009年底注册的,注册在了花生壳(Oray),实际上的顶级注册商是三五互联(中国频道)。这是多方面原因的结果,第一是当年没有海外支付手段,那时候对网上支付的印象还是跳转到只支持IE的破烂银行网站,插上装了一堆插件才能运行的U盾才能登录。第二是花生壳用了很多年了,大概初一的时候开始接触建站,第一份教程指导的是用花生壳的DDNS,注册个免费的二级域名,然后装IIS,用Front Page做网页。那个年代的免费虚拟主机很不稳定,而收费主机对于一个中学生来说开销太大,再加上本来就是做个网站玩,自家电脑host就完了。当时对中国网络的认识也很懵懂,还觉得大网站下面放个ICP备案号很帅呢。不过现在想想那时候的网络环境也比现在强太多,2010年以前还可以“外事问Google”,上Youtube搜个游戏攻略视频。再看现在,离彻底断网没多远了。

随着时间的推移,花生壳的DDNS当然早就不用了,但是域名的使用上也没有什么问题,最近挂到了AWS的route53上,除了修改DNS记录根本不用登录花生壳。邮箱里会隔三差五收到三五互联发的提醒确认WHOIS信息准确的邮件,也相安无事。第一次收到要求实名验证的是两年前了,要求5天内提交资料,然而完全无视也没问题。今天五月底发现又在要求实名认证,而且没有认证的域名直接停止解析。于是下定决心一定要把域名转出来。坚决不做域名实名制不是因为个人信息的问题,开始上网的时候什么都不懂,个人信息早不知道泄露了多少了。而是因为对工信部这种做法的不适,对政府把手伸向虚拟空间的厌恶,还有说起中国网络环境的一肚子气。不注意个人信息保护在这件事中还帮上忙了,因为WHOIS信息全填的真实信息。如果注册的时候编个假名的话那可真比登天还难了。

之前一直没想着转出是因为感觉会很麻烦,一看果然如此。从花生壳转出要填两个表格。一份是同意书,说的是这件事上海贝锐信息科技股份有限公司(花生壳)没有一点责任,域名持有人负全部责任。第二个是三五互联的申请表,花生壳填了会员号。有个域名持有人章和会员号注册者章,后来才知道花生壳负责盖一个会员号注册者章。当然要附上身份证复印件,复印件上还要签名。也没多想,5月29日第二天就寄出去了。结果5月31日才收到客服回复的详细说明,说可以先发邮件确认一下再邮寄。

第一次邮寄的资料果然不合格了。第一是因为生怕跟Gmail通信会有问题所以接收邮箱写了个126邮箱,得填注册邮箱。第二是上面提到的会员号注册章。第三是要在身份证复印件上补充正楷签字。私以为写字不算潦草了,这要是硬笔书法不过关可怎么办啊。

最后一条是“办理业务需得知您转出的具体原因”。按理说域名持有者有随意处理域名的权力,注册商凭什么过问。但是在这里计较也就没意思了,直接问客服什么理由才能通过。最后得到了填写个人原因即可的回复。

因为出门所以暂时把这件事放了下来。6月5日在都江堰前往成都的火车上,连接自建的VPN失败。一查WHOIS域名已经被停止解析,Serverheld状态。臭名远扬的cn域名相信大家还记得,不过至少真的是CNNIC管理的,只能自认倒霉。合法注册了多年的国际域名被强制停止解析,这发生在2017年,21世纪的中国。

回家以后再填写一次表格,扫描发过去,等客服说审核通过了再邮寄过去。花生壳收到后再寄给三五互联,还提供了圆通的快递号。说是8个工作日以内,结果石沉大海。7月14日收到邮件,终于把授权码发过来了。马上登录GoDaddy开始转入。7月16日收到三五互联的确认邮件,转移成功。之后GoDaddy再确认一次邮箱就完全可以控制了。

总结一下时间线:

5月29日第一次寄出资料

6月9日发扫描件给花生壳

6月12日“预审”通过

6月13日第二次寄出资料

6月15日花生壳寄给三五互联

7月14日收到转出授权码

7月16日完成转移

总共用了48天。三五互联用掉了整整30天的时间。两次顺丰快递花了46元。

那么从GoDaddy和其它文明世界的注册商转出怎么办呢?登录后点击获取授权码,耗时大约3秒。

其实花生壳就算不错了,没有把详细写在网页上是他们的问题,端午假期后能主动联系也还就可以忍了。这次没有直接跟三五互联打交道,不过看他们的办事效率也知道这能看出这是一家什么公司。如果搜索从三五互联转出域名的话可以搜到Slayer的经历,这位菊苣还是USC的学长。因为三五互联阻挠他转出,直接投诉到了ICANN. 要找人撒气的话也不失为一个好方法。

最后,不要用中国的域名注册商,不要用中国的云主机。无论是有形的还是无形的财产,还是放在文明世界比较安全。

Project Fi使用体验

Project Fi是Google推出的虚拟运营商服务,刚推出的时候是邀请制,2016年3月全面开放。从2016年10月使用至今的感受是,不出国的话Project Fi适合平时流量用的不多的人,出国的话绝对是旅游神器。

Project Fi租用的是第二大网T-Mobile和第四大网Sprint的网络,在这两个网络中自动切换。当然这两个加起来也不见得有AT&T的信号好,追求覆盖范围还是AT&T吧。但是只能在Nexus5X以上的亲儿子手机上用,当然还有最新推出的真亲儿子Pixel. 一咬牙订了一台Pixel, 32GB版加上税也有750元。这也是Project Fi的最大入门屏障,只能用Google的手机。正好想换手机的话倒是个不错的选择。

资费可以说是无懈可击。各大实体运营商的话单人plan至少要月费40起,Project Fi的基本资费是20元,无限国内通话和短信。然后1GB流量10元,没有用够1G的话下个月退款,实际上是用多少花多少。普通的计量套餐可比这个贵多了。实际上因为在学校都有Wi-Fi也只有出门的时候用一点流量,基本没有超过100MB的时候。原来AT&T的family plan到最后给免费升级到了15G一个月,然而实际没什么用。如果用流量很多的话可能有点贵了,用的不多的话非常合适。税和杂费还是有的,不过一个月肯定不会超过30元。

除了本机之外还可以开数据专用卡,共享主卡流量。第一张免费,最多可以开9张数据专用卡。其实电话短信功能也用的不多,数据卡放在原来的iPhone里,完全是一个帐号带两台手机。

Project Fi最厉害之处在于海外漫游流量政策跟国内一样,10元1GB,用多少花多少。目前拿着漫游过墨西哥,日本,新加坡,和中国。墨西哥的运营商不太了解,打开是3G,可能LTE制式不一样。日本默认连上了Softbank,可以LTE. 新加坡厉害了,数据副卡居然也可以漫游,其它地方都不可以。中国的话默认连上了移动,只有EGPRS,手动选联通的话可以LTE,电信注册不上。漫游的手机最后出口在本国,查IP的话是T-Mobile出口。在正常国家没有太大的意义,在中国使用相当于可以直连互联网。国际漫游费用之高一直为人所诟病,之前AT&T出国,只能买30元120MB流量包,用的时候都是看一眼地图赶紧关了。T-Mobile虽然有全世界免费漫游,但是限制在2G网,可用性比较低。去日本用了280MB流量,真的只花2.8元,Project Fi真正实现了全世界随处上网的梦想。

至于办卡方面,因为是pre-paid所以不要SSN不要信用记录。携号转网信息预定的时候填好,手机开机几分钟就转好了。因为是family plan里的号码起初还有点担心,结果填上账单上的帐户号码就好了,也没有联系AT&T.

Website Chronology

I created my first website in 2008 with a couple hand-written HTML pages. It was hosted on my home laptop with a free dynamic domain caowenfei.vicp.net provided by Oray.com. I registered cwf123.com in 2009 and used it as a dynamic domain. Since I started to learn ASP in 2010, an ASP website existed briefly. After that the website remained mostly closed until moving to a Digital Ocean server. Before the move my personal website focused on experimenting with techniques, so I did not use any blog systems. The website adopted WordPress for the first time in 2014. However, mysql service on the server kept crashing and I had to reset the VPS several times. I even ditched WordPress for a static framework called Hexo in order to avoid mysql. Finally, I decided to host my website on AWS today. I chose to create a Windows VPS which seems to be more reliable. I hope the website won’t crash constantly this time.