xluo's blog


  • Startseite

  • Über

  • Archiv

  • Tags

2016-04-10-scala

Veröffentlicht am 2016-04-10

单例对象

要点:
在scala当中,不会像java那样提供static的关键字用于创建一个单例对象。但我们可以通过object这个关键字来定义一个单例对象,在object块里面的成员变量与方法都是静态的。但要注意的是:在java当中,static的静态成员变量、静态块是在类加载的时候就被执行了,而在scala当中,只有第一次调用的时候才会执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
object SingletonClass {

private var num = 0;

def getNum = {
num += 1;
num
}

}

object Main {

def main(args: Array[String]) {
println(SingletonClass.getNum)
println(SingletonClass.getNum)
}

}


out :
1
2

伴生对象

概念:
当一个类定义为class A,则对应的object A就是它的伴生对象。它能访问伴问伴生对象当中的任意成员变量,即使是private的也可以。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//伴生对象
object SingletonClass {

private var num = 0;

def getNum = {
num += 1;
num
}

}

//伴生类
class SingletonClass {

private var id = SingletonClass.getNum;
private var num = 0;

def getNum(num : Int) = {
this.num += num
}

}

注意:
伴生对象通常用于作为伴生类的静态成员变量的封装区域。


apply方法讲解

object中:
当使用伴生对象来生成对象时,就会调用其apply方法
class中:
当直接使用new clazz的方式来创建对象的时候是不会调用类当中的apply方法的,只有当使用创建了的对象A,直接调用A()就能调用类当中的apply方法

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
class ArrApply{
def apply() = {
println("print from class")
//new ArrApply()
}

def doSomething() = {
println("doSomething")
}
}

object ArrApply{
def apply() = { //=号不能少,少了doSomethin方法调用的地方会报错,还没找到原因
println("print from object")
new ArrApply()
}
}

object ApplyOps {

def main(args: Array[String]) {
val arr = ArrApply() //通过伴生对象创建一个伴生类对象
arr.doSomething()

val array = new ArrApply()
array() //调用类的apply方法
}

}

scala继承

它的使用方法与java类似,只是在重写的时候要使用override关键字。但在java当中,是在子类的构造器中调用父类的构造器的,而scala中,是在定义子类的时候填满父类的主构造方法

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
40
41
42
43
44
45
46
47
48
49
class ExtendClass(name : String) {

val school = "GDUT"

def showInfo : String = {
school
}

def showName : String = { //当子类没有重写时,即使调用了changeName也返回构造值,因为这里返回的是父类的name,而修改的只是子类的name而已
name
}

override def toString = {
"in gdut"
}

}

class Student(var name : String) extends ExtendClass(name) {

override val school = "gdut"

override def showInfo : String = {
"a boy in " + school
}

def changeName(name : String) = {
this.name = name
}

override def showName : String = {
name
}

}

object ExtendOps {

def main(args: Array[String]) {

val student = new Student("xiaoming")
println(student.toString)
println(student.showInfo)
student.changeName("xiaodong")
println(student.showName)

}

}

抽象类

与java类似,在scala当中也是通过abstract关键字来定义一个抽象类,对于抽象类当中的字段,如果没有赋值则是抽象的成员变量,对于方法如果没有具体的实现则为抽象方法。但要注意的是,在java当中抽象方法是要使用abstract来修饰的,但在scala当中,abstract只能用于修饰class。如果一个类不是抽象类,那么它的成员变量是一定要进行赋值的,可以是具体的值,也可以是一个占位符。而使用占位符只能是成员变量类型为var的情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
abstract class AbstractClass {

var name : String = "xiaoming"
var age : Int
def teach()

}

class MathTeacher extends AbstractClass {

override var age = 22

override def teach() = {
print("math teacher")
}

}

object AbstractOps {
def main(args: Array[String]) {
val teacher = new MathTeacher();
teacher.teach()
}
}

scala当中的接口-trait

在scala当中的trait与java中的interface类似,但trait的功能更为强大,它能够有方法的具体实现(JDK1.8也可以通过default关键字来提供)。在使用triat的实现类的时候,我们还可以通过with关键字来给该对象混入其它的triat实现,这相当于一个动态的extends操作。在java当中多实现是用,来分割的,但scala当中是使用with

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
40
41
42
trait TriatClass {

def log()

}

trait OtherTriat {

def consoleLog(): Unit ={
println("console log...")
}

}

trait TriatClassImpl extends TriatClass{

override def log(): Unit ={
println("triatclassimpl...")
}

}

class ConcreteLog extends TriatClass {

override def log(): Unit ={
print("concretelog...")
}

}

object TriatOps {
def main(args: Array[String]) {
val log = new ConcreteLog
log.log()
val logger = new ConcreteLog with TriatClassImpl
logger.log()
val console = new ConcreteLog with OtherTriat //混入其它triat
console.log()
console.consoleLog()
}

}

2016-04-09-macutil

Veröffentlicht am 2016-04-09

2016-04-09-scala

Veröffentlicht am 2016-04-09

构造方法

默认情形:(主构造方法)

1
2
3
class Teacher {

}

它的等价形式:

1
2
3
class Teacher(){

}

私有形式:

1
2
3
class Teacher private {

}

由此可以看到scala与java类型都会有一个默认的无参构造方法,但有一点不同的是,在java当中,当对构造方法进行重载时,那么jvm就不会再添加默认的构造方法。辅助构造方法也只需写自己的实现即可,而在scala当中,所有的辅助构造方法都要调用其它的辅助构造方法或主构造方法,而且在最终形态上体现对主构造方法的调用。
例如下面的这个例子,当没有使用this对主构造方法进行调用时,则会报错:

1
2
3
4
5
6
7
8
9
10
class Teacher {

private var name : String = _

def this(name : String){ //这里相当于重载一个构造方法
//this 注释掉则会报错
this.name = name;
}

}

有参的主构造方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Teacher private (name : String){

private var age : Integer = 0

def this(name : String, age : Integer){
this(name)
this.age = age
}

def showInfo(): Unit ={
println(this.name + " " + this.age)
}

}


内部类

1
2
3
4
5
6
7
8
9
10
11
class OuterAndInter(name : String) { outer => //outer相当于外部类的别名,用于让内部类访问外部类的内容
class Inter(name : String){
println("wrong outer: " + name + " inner: " + this.name)
println("outer: " + outer.name + " inner: " + this.name)
}

class Inter2(name : String){
println("outer: " + outer.name + " inner2: " + this.name)

}
}
1
2
3
4
5
6
7
object OuterAndInterTest{
def main(args: Array[String]) {
val outer = new OuterAndInter("outer")
val inner = new outer.Inter("inner")
val inner2 = new outer.Inter2("inner2")
}
}

注意:
在创建内部类A对象的时候要注意,内部类A是依附于外部类B的实例上的,因而如果内部类中有一个方法的参数类型为A,那么当调用该方法时要注意只能传递用于调用该方法的对象的引用或者与其类型相同的引用,否是会报错。

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
class OuterAndInter(name : String) { outer => //outer相当于外部类的别名,用于让内部类访问外部类的内容
class Inter(name : String){
println("wrong outer: " + name + " inner: " + this.name)
println("outer: " + outer.name + " inner: " + this.name)
}

/*
class Inter2(name : String){
println("outer: " + outer.name + " inner2: " + this.name)
}
*/

class Inter2(val name : String){
def showName(inter2: Inter2): Unit ={
println("showName : " + inter2.name)
}
}
}

object OuterAndInterTest{
def main(args: Array[String]) {
val outer = new OuterAndInter("outer")
val outer2 = new OuterAndInter("outer2")
val inner = new outer.Inter2("inner")
val inner2 = new outer2.Inter2("inner2")
inner2.showName(inner2) //这里的类型是outer2.Inter2,报错信息为:Type mismatch, expected: outer2.Inter2 actual: outer.Inter2
inner2.showName(inner2)
}
}

2016-04-08-面试总结:阿里、蘑菇街

Veröffentlicht am 2016-04-08

阿里

内推 -> 一面 -> 二面 -> 三面(交叉面) -> hr面 -> offer

题目整理

一面

1、说一下哪个项目对自己的成长最大(说了三个项目,分别是对自己技术PA\管理 PB\设计PC的影响)
2、PA项目介绍、难点
3、使用了webservice,那么当传递数据时,网络中断会不会导致保存两条相同的数据,因为发送端会因为传送失败而重传
4、简历上有写成为PA项目负责人后,提高系统稳定性。问:具体是怎样提高
5、PB项目使你的管理能力得到提升,具体说说
6、PC项目对你的设计能力有所影响,说说
7、项目中有没有遇到死锁的情况,是怎么解决的


总结

面试官:

在最后问了面试官对自己的评价,总体来说表现还不错,做过的东西也还行。但是,有一个不足就是在回答问题的时候太过详细,应当要学会提炼自己的观点,这样别人才能抓到重点,才能更好地考察你,在回答问题的过程中,发现一面的面试官有一个特点,就是他喜欢把我的答案再经过自己的理解总结、提炼,由此也可以看出,平时总结的重要性

我:

整个过程觉得表现还好,在遇到不会的问题的时候会跟面试官讨论一些类似的问题,其实一开始的意图是想要避开那个问题的,后来发现真的很难很难…反正宝宝没有成功,最后还是回到了那个问题,后来是通过联系类似的东西得到了答案,其实有时候会发现,有些东西它们的思想实际上都是一样的,只不过是通过不同的方式来体现而已。

二面

1、是否读研
2、描述一下之前难点比较多的项目
3、项目难点
4、描述其中一个难点
5、项目是基于ssh的,当时是怎么确定使用这套框架的
6、项目经历了多长时间
7、有什么缺点,是如何克服的
8、Spring bean有多少种形态,它底层是怎么实现的


总结

面试官:

因为整个面试的过程时间只有17min,所以最后没有问面试官自己的表现如何。

三面

1、操作系统的职责、内存分配用到哪些算法?详说一下其中的一个算法?
2、操作系统如何解决内存分配碎片问题?系统运行的程序是怎么知道地址发生变化的?(这里回答了利用地址变换机制,不知道对不对)。
3、数据结构用过哪些排序算法,堆排的实现?
4、设计模式用过哪些,观察者模式的使用例子,哪些是观察者,哪些是被观察者?自己实现怎么实现,被观察者应该有哪些与观察者交互的方法?
5、自己实现hashmap怎么实现,java是怎么实现的。自己如何实现hash算法(这里一直听不明白他的问题。。哭),知道的hash函数算法有哪些?
6、哪个项目最深刻,有哪些难点,讲一下它的功能,项目多大规模
7、讲一下其中一个难点你是怎么解决的。这里说到了缓存,然后问是什么级别的缓存(答了内存级别的),然后问服务器有多少台,(一台,然后沉默了一下,估计想问多台主机问怎么同步缓存问题吧。)
8、最近看什么书,说下深入理解jvm每一章主要讲什么的。

hr面

1、自己有什么优势?
2、自己的一些实践经验?(上面回答了自己的项目优势)
3、这个项目有多少人在做,然后自己的角色是什么?
4、学校技术水平可以排什么位置?为什么?
5、topview工作室的性质?技术上是不是比较领先的工作室?
6、这个阶段需要提升什么地方?
7、以后的职业规则?
8、什么时候可以实习?

蘑菇街

(一面后跪了,几天难以释怀...)

1、快排的思路与时间复杂分析
2、描述一下所用的框架的作用,一个请求到哪里到哪里。(我是从三层架构回答各个框架的作用)
3、http请求到达服务器端会经历哪些阶段
4、有了解过分布式的相关技术
5、做这么多的项目的原因(兴趣)
6、Java里面有哪些集合是线程安全的
7、前端掌握了哪些js框架
8、Angularjs与jquery的区别,为什么要选择angularjs
9、垃圾回收是在什么情况下会触发
10、泛型机制的看法与了解
11、泛型擦除是运行期还是编译期
12、如何创建一个泛型的实例(反射)
13、还通过反射做过什么事情
14、是否用过java开发过多线程的业务(面试官的问答是排除了web的方向的,宝宝没意识到,反问了一句所有的web应用不都是多线程的吗?然后,他问你只做过web项目 对吧。坑!!)
15、Web中如何保证线程安全
16、多消费者多生产者模式能不能做成线程安全?
17、平时用锁多不多(用得不多,大部分逻辑都是做成线程封闭性的。。。回答用得不多是不是会印象不好啊)
18、对分布式框架是否有了解(项目还没有这个需求,没学)
19、Mysql索引的实现原理
20、Mysql多级索引怎么处理(多个单列索引,只会用可能性最高的那个)
21、有没有考虑过分布式相关东西
22、如果有机会接触分布式这些,是愿意继续开发web还是去学分布式的内容

cvte

网申 -> 线上笔试 -> 现场一面 -> 现场二面 -> offer

题目整理

一面

1、手写查找0-100的素数
2、说一下项目的业务、难点
3、数据库引擎myisam、innodb的不同

二面

1、一直在聊项目
2、将来是想做管理还是技术

待续

2016-04-08-plan

Veröffentlicht am 2016-04-08

数据结构与算法

1、常用算法要经常练习,理解
2、多刷题

JDK基础

1、看JDK源码,从熟悉的类看起
2、熟悉JDK的一些设计模式与缺陷

Web应用开发

1、spring掌握还不够全面,要继续深入学习 - 看spring核心内幕那本书
2、学习netty、mina
3、Jvm还要继续保持了解,学习
4、学习osgi

网络

1、看计算机网络那本书

大数据、云计算

1、学习scala
2、学习spark
3、看一些与分布式相关的书籍

其他

1、搭建github个人主页 完成
2、坚持总结、写博客

xluo

xluo

厚积薄发

5 Artikel
1 Tags
© 2016 xluo
github