摘要: 题目 有两个文件A和B,两个文件中都有几百万行数字,现在需要找出A文件和B文件中数字集合的交集、并集、以及A对B的差集。 简单说一下思路: 这个问题关键在于key和value的设计。这里我将文件中的数字设置为key,将文件名称设置为value。这样在reduce阶段很容易就能找出A、B两个文件中数字的交并差集了。 并集就是reduce阶段能输出的全部记录;交集则需要做下过滤,即一个记录中的val...阅读全文
posted @ 2017-09-21 22:18 robin·张 阅读(6) 评论(0) 编辑
摘要: 题目: 需要将MR的执行结果保存到3个文件中,该怎么做。 又是一个送分题。 对于Hadoop的MapReduce来说只需要设置一下reduce任务的数量即可。MR的Job默认reduce数量是1,需要调用job的setNumReduceTasks()方法来调整reduce任务的数量。 对于spark来说,可以调用coalesce方法或repartition方法来调整分区的数量,这样也可以调整最终...阅读全文
posted @ 2017-09-19 22:09 robin·张 阅读(2) 评论(0) 编辑
摘要: 题目: 一个文件,大小约为100G。文件的每一行都是一个数字,要求对文件中的所有数字进行排序。 对于这个题目,了解过Hadoop的同学可以笑而不语了。即使用spark实现也是非常简单的事情。 先说下如何用Hadoop实现。实际上也没什么好说的:Map任务逐行读入数字,而后在Reduce中输出就可以了,简单粗暴到令人发指。 看下代码好了: package com.zhyea.dev; impor...阅读全文
posted @ 2017-09-18 07:07 robin·张 阅读(9) 评论(0) 编辑
摘要: 从今天我们开始学习HBase。希望大家能够通过这个课程对HBase有一个初步的认识,并且能够使用HBase提供的命令行以及Java API完成一些通用的操作。 今天的内容是一些入门性的知识:包括HBase的简单介绍、HBase的逻辑模型以及HBase的物理模型。 HBase简介 HBase是Google BigTable的开源实现。在05年前后,谷歌发布了三篇非常重要的论文,受这三篇论文的启发才有...阅读全文
posted @ 2017-05-04 07:15 robin·张 阅读(54) 评论(0) 编辑
摘要: 这次看一些关于JVM内存分析的内容。 两个程序 程序一 首先来看两个程序,这里是程序一:JVMStackTest,看下代码: package com.zhyea.robin.jvm; public class JVMStackTest { private static int count = 0; private void recur() { ++co...阅读全文
posted @ 2017-04-30 08:08 robin·张 阅读(24) 评论(0) 编辑
摘要: 前面两节我们已经多次接触过case关键字了。case关键字不仅可以用在match/case中来执行模式匹配,也可以用来修饰类。不过用case修饰的类也主要是用来做模式匹配。在上一节曾经提到过match可以是Any类型的所有类,为什么还需要使用case关键字来修饰呢?假定有这样一个场景:我们要接收和处理股票交易信息,买卖消息通常会带有一些信息,诸如股票名称、数量。把这些信息存到对象里会很方便,但是如...阅读全文
posted @ 2016-09-20 22:05 robin·张 阅读(253) 评论(0) 编辑
摘要: 再来看一下之前的一段代码: def process(input: Any) { input match { case (a: Int, b: Int) => println("Processing (int, int)... ") case (a: Double, b: Double) => println("Processing (double, double)... ") ca...阅读全文
posted @ 2016-09-18 22:41 robin·张 阅读(183) 评论(0) 编辑
摘要: 在java中有switch/case这样的模式匹配语句,可以匹配的类型包括int,byte,char,short, enum,在java8又支持了字符串。 在scala中也有类似的模式匹配语句,即match-case。这个好现在之前使用过一次。scala中的match-case匹配的类型更为广泛,它是对Any类型起作用的。 来看个例子: def activity(day: String) { ...阅读全文
posted @ 2016-09-18 21:53 robin·张 阅读(106) 评论(0) 编辑
摘要: 方法命名约定 之前在学习《运算符重载》一节时曾经说过一个方法命名约定:方法的第一个字符决定了方法的优先级。现在再说另一个命名约定:如果方法以冒号(:)结尾,则调用目标是运算符后面的实例。 比如下面这个例子: class Cow { def ^(moon: Moon) = println("Cow jumped over the moon") } class Moon { def ^:(c...阅读全文
posted @ 2016-09-15 22:52 robin·张 阅读(145) 评论(0) 编辑
摘要: 这次统一看一下scala中容器类的几个方法。 Set filter()方法 filter()方法用来从Set中过滤获取含有指定特征的元素。示例代码如下: val colors1 = Set("Blue", "Green", "Red", "yellow") val filteredSet = colors1 filter (_ contains "l") println(filteredSet m...阅读全文
posted @ 2016-09-13 22:11 robin·张 阅读(216) 评论(0) 编辑
摘要: scala的容器包括Set、List和Map。三种容器的特征和Java中一样。scala为每种容器都提供了可变和不可变两种版本,分别位于scala.collection.mutable或scala.collection.immutable包下。scala建议使用尽量使用不可变容器,尤其是在多线程环境下。并且scala默认的容器就是不变的版本。 可变容器没什么好说的,java中的容器就是。来看一个不...阅读全文
posted @ 2016-09-11 22:50 robin·张 阅读(57) 评论(0) 编辑
摘要: 先来看一下下面的内容: 2 days “ago” 5 days “from_now” 如上的内容具体应该是什么呢?不过怎么看也不像是代码。不过既然是在学代码,拿不是代码的东西出来做什么! 非要强说是代码的话,那么执行起来肯定是要报错的——因为scala的Int和RichInt,以及Integer中都没有days这样的方法: 如果说不是代码的话,那么scala中的to或until本来看起来也不像代...阅读全文
posted @ 2016-08-28 08:18 robin·张 阅读(188) 评论(0) 编辑
摘要: trait的方法的延迟绑定就是先混入的trait的方法会后调用。这一点从上一节的实例中也可以看出来。 下面再来看一个类似的例子: abstract class Writer { def write(message: String): String } trait UpperWriter extends Writer { abstract override def write(messag...阅读全文
posted @ 2016-08-15 22:52 robin·张 阅读(155) 评论(0) 编辑
摘要: 在上一节看到了scala的在实例一级的选择性混入就不得不感叹scala在语法上的扩展性。就通过这样一个特性scala简化了很多在java中的编程概念和设计模式。 比如说在java中常用的组合,以及装饰模式。下面看个书中的例子,详细说说如何使用trait进行装饰。 假设我们要对一个人进行检查,包括信用记录、收支记录、犯罪记录和工作记录等。但是我们并不会总是都会用到所有的检查,比如要买房时会检查信用记...阅读全文
posted @ 2016-08-14 10:34 robin·张 阅读(197) 评论(0) 编辑
摘要: 继续上一节。 狗当然是人类的好朋友。但是藏獒呢?这玩意儿又蠢又笨又凶狠,肯定不能算很多人的好朋友了。其实,刚才那句话还可以修正一下下:我们接受的狗才是我们的好朋友。 用程序怎么实现呢?在java里面,可以使用组合来实现这样的逻辑,仅仅使用接口还是有些勉强的。而scala则可以在实例一级混入trait: trait Friend{ val name : String def accompan...阅读全文
posted @ 2016-08-09 22:22 robin·张 阅读(45) 评论(0) 编辑
摘要: 不知道大家对java的接口是如何理解的。在我刚接触到接口这个概念的时候,我将接口理解为一系列规则的集合,认为接口是对类的行为的规范。现在想来,将接口理解为是对类的规范多少有些偏颇,更恰当些的观点应该是:相对于类来说,接口是更深层次的抽象,虽然同时接口也起到了规定类的行为的作用。 和java的接口比起来,scala的Trait可能更具体一些。正如Trait的含义一样,它指的是一种特质,如果认为类有某...阅读全文
posted @ 2016-08-08 22:44 robin·张 阅读(72) 评论(0) 编辑
摘要: 首先要弄白闭包的概念。 教材中的说法是:闭包是一种特殊的函数值,闭包中封闭或绑定了在另一个作用域或上下文中定义的变量。这里说闭包是一种特殊的函数值。 维基百科中的说法是:在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的...阅读全文
posted @ 2016-08-07 12:40 robin·张 阅读(79) 评论(0) 编辑
摘要: 调用函数可以说成是将函数应用于实参。如果传入所有的预期的参数,就完全应用了这个函数。如果只传入几个参数,就会得到一个偏应用函数。 偏应用函数是一个特殊的概念,在scala中它是使用val定义的,但是在使用时它却更像是一个函数。偏应用函数的定义更接近于python中有默认值的函数(scala实在是和python有太多相似的地方了)。 先来看一个例子: import java.util.Date d...阅读全文
posted @ 2016-07-30 22:21 robin·张 阅读(64) 评论(0) 编辑
摘要: 我们访问资源需要关注对资源的锁定、对资源的申请和释放,还有考虑可能遇到的各种异常。这些事项本身与代码的逻辑操作无关,但我们不能遗漏。也就是说进入方法时获取资源,退出方法时释放资源。这种处理就进入了Execute Around模式的范畴。 在scala里可以用函数值实现这种模式。下面是一个示例,使用Resource类演示了事务的开启和释放: class Resource private() { ...阅读全文
posted @ 2016-07-30 10:40 robin·张 阅读(85) 评论(0) 编辑
摘要: 在Scala里,下划线(_)可以表示函数值的参数。如果某个参数在函数里仅使用一次,就可以用下划线表示。每次在函数里用下划线,都表示随后的参数。 val arr = Array(1, 2, 3, 4, 5) println("Sum of all values in array is " + (0 /: arr) { (sum, elem) => sum + elem }) 上面的代码里使用了“/:...阅读全文
posted @ 2016-07-29 07:05 robin·张 阅读(255) 评论(0) 编辑
摘要: 函数值对消除代码重复有很大的帮助。但是像函数值这样直接将一个函数作为另一个函数的参数却不太利于函数值本身的重用。 来看一个例子: class Equipment(val routine: Int => Int) { def simulate(input: Int) = { print("Running simulation...") routine(input) } } 在...阅读全文
posted @ 2016-07-27 22:38 robin·张 阅读(56) 评论(0) 编辑
摘要: 在线广告的核心问题就是广告的三方——广告主、媒体和广告商——之间的博弈。 具体可以参看下图: 在线广告的计算面临的主要挑战: 大规模:媒体数量很多、面向的用户极广、高并发的投放系统、严格的低延迟要求; 动态性:用户的行为和兴趣一直在变; 丰富的查询信息(主要是针对搜索广告而言)阅读全文
posted @ 2016-07-26 22:55 robin·张 阅读(30) 评论(0) 编辑
摘要: curry翻译为中文就是咖喱。意为使用curry可以让代码更有味道。 scala里的curry化可以把函数从接收多个参数转换成接收多个参数列表。也就是说我们要编写的函数不是只有一个参数列表,这个参数列表中有多个参数以逗号分隔;而是一个函数中有多个参数列表,每个参数列表中只有一个参数(当然,也可以有多个参数)。也就是说我们写的函数不再只是这样子的: def foo(a: Int, b: Int, c...阅读全文
posted @ 2016-07-26 22:30 robin·张 阅读(327) 评论(0) 编辑
摘要: 上一节的函数值只有一个参数。函数值当然也是可以有多个参数的。看一下下面的inject方法: def inject(arr: Array[Int], initial: Int, operation: (Int, Int) => Int): Int = { var carryOver = initial arr.foreach(element => carryOver = operation(...阅读全文
posted @ 2016-07-25 23:39 robin·张 阅读(513) 评论(0) 编辑
摘要: scala的一个最主要的特性就是支持函数编程。函数是函数编程中的一等公民:函数可以作为参数传递给其他函数,可以作为其他函数的返回值,甚至可以在其它函数中嵌套。这些高阶函数称为函数值。 举一个简单的例子:从1到某个数求和。使用Java很容易实现: int sum(int max){ int result = 0; for (int i = 0; i Int): In...阅读全文
posted @ 2016-07-24 10:15 robin·张 阅读(70) 评论(0) 编辑
摘要: java 的代码中多少有些不是很严谨的内容,比如下面的这段代码: public class Trouble { public static void main(String[] args) { Integer[] arr1 = new Integer[2]; arr1[0] = new Integer(1); Object[] arr2 = ...阅读全文
posted @ 2016-07-22 07:45 robin·张 阅读(61) 评论(0) 编辑
摘要: Demand:需求方,可以理解为广告主,广义上指的是代表广告主利益的一方; Supply:供应方,可以理解为媒体,广义上指的是代表媒体利益的公司。 上图说明了媒体变现手段: 托管给network(网站); 托管给广告交易市场(ad exchange); 托管给SSP(Supply Side Platform)。 通常前两种方式是同时存在的。通过实时竞价的方式对接到DSP(Demand ...阅读全文
posted @ 2016-07-19 22:11 robin·张 阅读(30) 评论(0) 编辑
摘要: 在线广告的特色: 技术和计算导向; 可以进行准确的衡量(点击率未必是准确的衡量标准,所以出现了效果广告); 技术投放和精准定向促进了广告的标准化; “媒体”概念的差异化(如门户网站、淘宝(靠近转化端)、搜索引擎、比价网站(居中))。 几个重要的行业协会:阅读全文
posted @ 2016-07-17 22:13 robin·张 阅读(32) 评论(0) 编辑
摘要: 在Java中是可以使用变长参数的,如下面的方法: public void check(String ... args){ for(String tmp : args){ System.out.println(tmp); } } 在scala中也可以使用变长参数。和java一样,也是只有最后一个参数可以接收可变长度的参数。使用方式是在...阅读全文
posted @ 2016-07-16 23:00 robin·张 阅读(404) 评论(0) 编辑
摘要: 广告与营销的区别可以参考下图: 广告要reach的用户是潜在用户;营销的目标用户是对自己产品有明确需求的用户。 常见的渠道有硬广、SEM(搜索引擎推广)、导航网站、淘宝直通车、返利网等。 单纯比较不同渠道的ROI(收入回报的比例)意义不大,因为不同渠道在用户购买环节上所处的地位有着本质的区别。越接近demond(需求)的渠道ROI通常会越高,但是接近Supply(供应)的渠道负责的是reach潜...阅读全文
posted @ 2016-07-16 21:59 robin·张 阅读(27) 评论(0) 编辑
摘要: 这张图是一张对于广告过程的解读: 1曝光是广告的天然属性。在第一位决定了广告的效果。 广告策略的结果: 参考文档: http://blog.csdn.net/northstar087/article/details/8365008 http://www.lxway.com/404485181.htm阅读全文
posted @ 2016-07-15 22:26 robin·张 阅读(69) 评论(0) 编辑
摘要: 广告的主体:出资人(sponsor)即广告主(advertiser)、媒介(media)和受众(audience)。 广告的基础功能:借助于某种有广泛受众的媒介的力量,以较低的成本完成用户接触(reach)。 注意:完成接触后是否实现交易或其他转化不是必要条件。 广告有两大类 品牌广告:创造独特良好的品牌或产品形象,目的是提升长期的离线转化率。 效果广告:在短期内明确用户转化行为诉...阅读全文
posted @ 2016-07-14 22:22 robin·张 阅读(30) 评论(0) 编辑
摘要: 除了推演变量的类型,scala也会推演方法的返回类型。不过这里有一处需要注意:方法返回类型的推演依赖于方法的定义方式。如果用等号“=”定义方法,scala就会推演方法返回类型;否则,它就认为方法的返回为void。看一个例子: def printMethodInfo(methodName: String) { println("The return type of " + methodName ...阅读全文
posted @ 2016-06-25 23:52 robin·张 阅读(689) 评论(0) 编辑
摘要: 看到Option类型就知道这本教材应该要说那个了。 使用过guava后,应该知道guava中的Optional类的作用是什么。算了找下原始文档好了: Optional is a way of replacing a nullable T reference with a non-null value. An Optional may either contain a non-null T ref...阅读全文
posted @ 2016-06-23 22:34 robin·张 阅读(79) 评论(0) 编辑
摘要: Any 前面已经有两次提到过:在scala中,Any类是所有类的超类。 Any有两个子类:AnyVal和AnyRef。对应Java直接类型的scala封装类,如Int、Double等,AnyVal是它们的基类;对应引用类型,AnyRef是它们的基类。 scala中,所有类的关系可以用下面这张图大致描述下: Any是一个抽象类,它有如下方法:!=()、==()、asInstanceOf()、equ...阅读全文
posted @ 2016-06-23 21:58 robin·张 阅读(1281) 评论(0) 编辑
摘要: 关于scala的类型推断前面已经提到过多次。再来看一下下面这个例子: import java.util._ var list1: List[Int] = new ArrayList[Int] var list2 = new ArrayList[Int] list2 add 1 list2 add 2 var total = 0 for (index <- 0 until list2.size()...阅读全文
posted @ 2016-06-21 22:51 robin·张 阅读(282) 评论(0) 编辑
摘要: 前面两节学了scala的对象和伴生对象,这两个在使用的时候很有些java的静态成员的意思。 scala中没有静态字段和静态方法。静态成员会破坏scala所支持的完整的面向对象模型。不过可以通过伴生对象实现对scala的类一级的操作。 回过头来再看一遍那个Marker的例子,略做了一些调整: class Marker private(val color: String) { println("C...阅读全文
posted @ 2016-06-20 22:35 robin·张 阅读(2802) 评论(0) 编辑
摘要: 上一节中的单例对象MarkerFactory 就是一个独立对象的例子。尽管它管理着Marker类,但是它并没有关联到任何类上。 scala也可以创建关联到类上的对象。这样的对象同类共享同一个名字,这样的对象称为伴生对象,对应的类就称为伴生类。在scala里,类和伴生对象没有界限,它们互相可以访问彼此的private 方法和private 属性。下面使用伴生对象重写了Marker: class Ma...阅读全文
posted @ 2016-06-19 22:46 robin·张 阅读(146) 评论(0) 编辑
摘要: java中的单例模式都很熟悉了:简单地说就是一个类只能有一个实例。在scala中创建单例对象非常简单,创建类时使用object关键字替换class即可。因为单例类无法初始化,所以不能向它的主构造函数传递参数。 下面是一个单例的示例: class Marker(val color: String) { println("Creating " + this) override def to...阅读全文
posted @ 2016-06-17 22:51 robin·张 阅读(189) 评论(0) 编辑
摘要: 在scala里,类继承有两点限制: 重写方法需要使用override关键字; 只有主构造函数才能往父类构造函数中传参数。 在java1.5中引入了override注解,但不强制使用。不过在scala中要想重写方法必须使用override关键字。如果确实重写了父类的方法又不使用override关键字的话,则会在编译时报错,提示没有使用override修饰符。 scala的副构造函数必须调用主构造函...阅读全文
posted @ 2016-06-16 22:29 robin·张 阅读(194) 评论(0) 编辑