Pulpcode

捕获,搅碎,拼接,吞咽

0%

上篇关于电影的博客,目的是让你摆脱“简单俗套的故事剧情”和“看个什么电影都要找个意义”的思维陷阱。这篇博客我想聊聊什么才是一个好的电影剧本,或者如何讲一个好故事。

掌握好的节奏

如果你尝试把所有电影的高潮部分都剪辑出来,拼成两个小时,那你的“高潮”也不可能有两个小时,可能十分钟就瞌睡了。前辈们所说的起承转合是有道理的,你无法让一个人,一直集中注意力的看两个小时的高潮。即使你做出再暴力,再色情的画面也不行。人是一个天生就懂得对比,分得清主次的生物。他们记得住开头,记得住转折,记得住高潮,记得住结尾。所以要讲好一个故事,要把握好故事的节奏。把一个好的故事,一层层的拨开给观众看。侦探类电影就是一个最好的例子。比如2016年很火的一部叫《疯狂动物城》的动画片。这部动画片以兔子朱迪为主线。一开始就引入了故事关于食肉与食草动物的主题。并通过朱迪的第一视觉,向观众展现了疯狂动物城的全貌。并逐渐引入狮子市长,羊副市长,水牛警长,狐狸尼克等人物登场。将动物城失踪案件的迷雾一点点的剥离开来。同时带出了狐狸尼克的真实背景故事。小时候曾经欺负兔子的狐狸,在后来帮助到了兔子想到案件的关键。兔子朱迪救到的鼩鼱露露,在后来在大先生面前救下了尼克和朱迪。同时影片带有双高潮。也就是大部分侦探片都有的“第一次破获的案件是错的,真相另有隐情”的套路。最后结局兔子狐狸成为搭档+情侣故事圆满。剧情跌宕起伏,有来有回,可以说节奏把握的相当好。

阅读全文 »

实际上,像我这样堕落在代码,游戏,电影,小说中的男人,早早就被大众贴上了不懂女人,不懂爱情的标签。但是我最终还是尝试来写一篇关于女性,爱情的博客。其实我本来是想写七个短篇小说的。但我现在真的是忙的没有时间折腾这些文艺的东西。所以就采用“偷工减料”的方式,把这些故事,打散成一个个小情节讲给你听。

少女

这里所指的少女并不是说你年少她也年少,你们之间青涩的爱情故事,也不是说这个女人长得可爱,会卖萌,或者声音很嗲,就是少女了。少女的故事一般发生在,一个对生活失去向往的男人和一个初出茅庐的女人身上。我原本想写的小说是这样的:故事发生在我与几个高中同学一起在游戏里打怪升级做任务,在分战果的时候,无意中发现了一个穿着很廉价的装备,等级低,而且技术也不高的玩家妹子在那里被几个怪物这么的死去活来,出于好奇,我上前解决了这几个怪物,然后和这个妹子聊了起来,发现她虽然菜,但是单纯中透着一股勇气。所以我送了她几件装备,带她练级,教她如何释放技能。她是一个叛逆,倔强,又有点聪明,有点天真的女孩。比如很多时候,我告诉她不是这么玩的,她会很生气的说:“不要老是批评我。”然后我们一起聊了很多游戏中的典故和真实生活中的事。从兽人和人类的第一二次战役,一直聊到了她为什么来玩游戏,后来还得知她比我小两个年级,故事的最后,她已经能够在游戏中来去自如,并劝说我不要再玩游戏,好好准备高考,最后高考过后,我登上账号发现她再也没有在线了。

其实我印象最深的少女形象,应该是我带过的一个实习生妹子,她虽然有点笨,还很菜,但是经常一个人专注的写代码很久很久,而且每次调试出一个bug,都很开心的大叫起来。可能是她让我想起了自己刚学会写代码的样子吧。随着时光的流逝,我们早已经被生活磨平了棱角,对生活失去了好奇心。比如让你完成一件事,你要么会平直觉觉得这个事肯定没戏,所以早早的放弃,或者通过你的人生经验推断收益不高,而选择忽略。但是少女不会,无知但是固执的少女会用尽一切办法实现梦想。哪怕这个梦想很小。她的热情会深深感染你重拾儿时的火光。

在电影中有很多少女角色,比如《疯狂动物城》的兔子朱迪,她成功破获了人口失踪大案,同时也让狐狸又回归了儿时那个自己。我记得上高中的时候,有一次我们的一个年级组长被老领导骂道,“你一个二十多岁的人,怎么活成了四十多岁的样子了”。这说明在老一辈的人眼里,年轻人一定要有朝气。要有活力。每次我遇到少女的角色,也不由自主的变得像哥哥一样。守护这份纯真。在我心目中最能代表少女形象的,就是新恒结衣了,因为她的笑容太天真浪漫了,她所出演的 《LEGAL HIGH》,也完美的阐释了少女的形象。作为一个男人,你的妹妹,你的学妹,甚至是你的女儿,都可以以少女的形象出现的。

zgjy

阅读全文 »

回顾

在我上学的时候,一聊到设计模式都是很有格调的话题,仿佛设计模式就是解决软件开发的精髓,但是很长一段时间,我从骨子里是排斥设计模式的,因为我觉得自己连面向对象的知识都没有领悟,谈论设计模式还为时尚早,我尤其排斥那本被吹到爆炸的《大话设计模式》,那本设计模式看上去给你用形象的比喻讲明白了一个东西,但实际上你真正开始写代码的时候,发现自己什么都写不出来。

这篇博客是想退一步思考,总结一些面向对象的知识,比如思考“对象与对象的关系”到底是怎样的。

和大部分人一样,初学面向对象的时候,都会铺天盖地的听到一些词汇,比如“面向对象的三大特性是继承,封装,多态。”,再比如一切都是对象。但如果你仅仅记住这几句话,真的很难领悟面向对象这件事。我记得自己真正对面向对象有过一次深入体会是在读完《c++编程思想》,这本书的第一章是关于介绍oop的,作者通过一个面向过程的c代码到c++的oop书写方式,引出了面向对象的一些精髓,比如面向对象其实是一种思想,早期在用c的时候,也可以用面向对象的思路去写(struct+函数),但这种代码是单向绑定的,支持面向对象的代码的好处是完成方法与数据的双向绑定。而不像struct那样,不知道谁使用了此数据结构。

这些关于封装的知识理论上被称为基于对象,但说句实在的,对于很多人而言,能在系统中用封装的思想将系统建模就已经很不容易了,这可能听上去有点夸张,但仔细想想,对于一个人,一个苹果,一张订单让你去建模,你可能很容易就建了,但如果是类似Controller,Action,Execute这些看上去像是动作的对象呢?

再比如一些复杂的系统,如何抽象出领域模型,让系统能够清晰的交互,这些都不是那么容易的。再说继承与多态,其实继承本身和多态不像是处于同一平行线的概念。这个继承,在java中其实分继承接口和继承类,而继承类则主要是为了代码复用,只不过这种复用是静态的,而多态更像是动态的复用。

在c++中没有这么分类,c++提供的oop看上去更像是为数学公式准备的,所有只有继承类这么一说,只不过你定义一个只有虚函数的类,这个类就成接口了。而且c++的继承还包括公有继承,保护继承,私有继承等等继承权限,还有友元和多重继承。这些东西不是没用,而是一般人用不来,所以在java中都选择了精简。

阅读全文 »

如果要让我列举出自己曾经做过哪些浪费时间的事,我觉得“折腾编辑器”必须算其中之一。但是我为什么还要写这样一篇博客来聊编辑器呢?因为我报着“来都来了xxx”的态度,觉得总要总结点什么东西出来,否则不白浪费这么多时间。来写这样一篇博客。

这篇博客我会主要提及linux的两种重要的编辑器vim, emacs还有现在大多数平台被大多数人接受使用的sublime。还有其它的一些ide比如IDEA, visual studio。

从IDE到编辑器

其实大部分人开始写代码的时候,都是使用IDE进行开发的,那些写c++的可能最先使用的vc9.0,写java的最先使用Eclipse,还有一些像是php,python这样的动态语言,也都有IDE。然后这些人大部分最后都转战到编辑器上了,可能是Editplus,或者是sublime。甚至是古老的notepad++。这大部分原因都出自一句叫:“IDE会害了你,会用编辑器写代码的人才真正的懂代码。”等你以后写了几年代码,你会觉得这话真的是扯淡。但是很神奇的是就在当年大家都不会写代码的时候,这话仿佛真的像什么“箴言”一般,让大部分同学卸了ide改用编辑器甚至是记事本写代码。而后来有一部分人转战vim和emacs,把这两个编辑器的配置写的越来越大。让它们变得越来越像一个IDE。他们说用vim或者emacs的快捷键写代码是最快的,还称一个是编辑器之神和神之编辑器。不过你写了几年代码再想想这句话还是经不起推敲,什么时候写代码快,成了衡量程序员的指标了?再说大部分快速移动的功能是个编辑器都有啊。后来有一部分开始觉得这些东西很蠢,开始转战使用IDE。还有另一部分人仍然使用编辑器开发代码。不愿意的换的人大部分是因为已经都熟练了。好不容易折腾这么多日子,突然转战了,这不就白折腾了么,所以迟迟不愿意放弃,当然你说这是“沉没成本”,但是“沉没成本”真的只是理性的说法,大部分人都不会简单的接受“沉没成本”这一事实的。就像我不愿意接受“折腾编辑器是白折腾”这一事实,而去写一篇博客一样。

阅读全文 »

据说如果你问一个人,他有什么爱好,如果他说是看电影的话,那么他很可能是一个无趣,low爆了的人,真的没啥爱好了。比较正确的回答应该是打网球,画画,攀岩之类的。
但实际上我的爱好之一就是看电影,low就low吧。之所以写这样一篇博客,算是对这么多年来观影的一次总结,也是我很久就想写的一篇博客。简单来说,这篇博客就好比,你和我坐在一家咖啡馆或者是餐厅之类的地方。然后你突然兴致勃勃的对我说,“听说你对电影挺感兴趣的,可以给我推荐几部电影,或者给我讲一讲电影的事吗?”然后我给你我都倒了一点喝的东西闲聊了起来。

不过我一直在纠结怎么跟你聊电影这件事,如果我直接分别从“剪辑,分镜,剧情,角色,场面调度”跟你聊电影,放出一堆演员和导演的名字,再跟你拽几个电影专业词汇,那完全是自我陶醉的装逼。后来我曾打算通过自己的观影史,根据自己对电影的不断深入了解,来给你层层的剥开看电影这件事,通过我自己的眼光,来让你一层一层的理解电影。从看过渡到欣赏,然后到分析。不过我又害怕你对我的观影经历也不怎么感兴趣。冥思苦想之后,我突然有了这样一个灵感,既然我看了这么多电影,也看了这么多影评,拉片分析电影的书籍。不如我给你假设这样一个场景吧,“如果我筹到足够的钱,我会拍些什么电影呢?怎么拍?”。所以就有了这个系列博客,我估算了一下,大概会有四到五篇。

阅读全文 »

其实我一直想写一篇博客总结git的使用。但是却又没想好怎么写,即使我知道这篇博客的题目应该叫《性价比学习git》,我也没有想好如何性价比的学习git,我不可能把《pro git》上大段的git底层知识贴过来我用自己的话再描述一遍,也不能给你讲一些你这辈子都不会用到的git命令。直到最近我才有了灵感,所以在这篇博客里,我将试图先假设一个场景,并描述清楚你所遇到的问题,然后再告诉你要用git如何解决,最后我才可能会提到这背后的原理是啥,即-“为什么git可以这么玩?”,所以我所指的性价比学习git是说如何通过真实的使用场景学习git。不过我举得例子绝对都是自己开发真正遇到过的问题,同时也有一点点难度,而不是诸如“我想开发一个新功能”这样的简单例子。所以这篇博客也假设你已经学会了git的基本操作,而不会教你一些基础简单的命令,比如什么是分支?如何创建一个分支?BTW,这种写作方式,像极了《xxx cookbook系列丛书》

开发前忘记checkout一个分支

你打算为你的项目开发一个新功能,原本你应该在你的master分支上checkout出来一个feature-xxx-xxx,然后在测试完成后合并到你的master分支上。然而当你开发到一半的时候,发现你根本没有checkout一个分支,你的开发都是在master上完成的,这个时候你要怎么办?

实际上,如果你只是忘记从master分支checkout出来一个新分支feature-xxx-xxx这么简单的话,那么你只需要现在checkout就行了,你会发现你现在已经有了feature-xxx-xxx,并且你所修改的文件都被标记为:“M(odify)”,那现在你就当自己就是在新分支上做的开发就行了。不过还有一些棘手的时候,就是你本来想在feature-1上做开发,但是却错误的在feature-2上做了开发。现在你要如何让这些修改放到feature-1上?其实问题的本质还是feature-2的这些修改直接平移到feature-1会不会产生冲突,如果你修改的某个文件,两个分支已经提交的部分就不同,那你根本不能checkout成功:

阅读全文 »

很长一段时间我只知道java的泛型使用了被成为“类型擦除”的技术,但是具体的原因和实现细节一直不清楚,最近仔细“研究”了一下,发现了许多有趣的地方。其实有关泛型的知识我已经在组内做过一次分享。但我还是觉得有些地方讲的不够透彻,所以我打算把分享的一部分内容提取出来写成博客,串讲清楚其中的几个知识点,所以就有了这篇:《java为什么要用类型擦除实现泛型? 》

为什么需要泛型?

试想你需要一个简单的容器类,或者说句柄类,比如要存放一个苹果的篮子,那你可以这样简单的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Fruit{}
class Apple extends Fruit{}

class Bucket{
private Apple apple;

public void set(Apple apple){
this.apple = apple;
}

public Apple get(){
return this.apple;
}
}

这样一个简单的篮子就实现了,但问题是它只能存放苹果,之后又出现了另外的一大堆水果类,那你就不得不为这些水果类分别实现容器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Fruit{}
class Apple extends Fruit{}
class Banana extends Fruit{}
class Orange extends Fruit{}

class BucketApple{
private Apple apple;

public void set(Apple apple){
this.apple = apple;
}

public Apple get(){
return this.apple;
}
}

class BucketBanana{
private Banana banana;

public void set(Banana banana){
this.banana = banana;
}

public Banana get(){
return this.banana;
}
}
class BucketOrange{
private Orange orange;

public void set(Orange orange){
this.orange = orange;
}

public Orange get(){
return this.orange;
}
}

然后你发现你其实在做大量的重复劳动。所以你幻想你的语言编译器要是支持某一种功能,能够帮你自动生成这些代码就好了。

不过在祈求让编译器帮你生成这些代码之前,你突然想到了Object能够引用任何类型的对象,所以你只要写一个Object类型的Bucket就可以存放任何类型了。

阅读全文 »