资源来自《第一行代码》(第三版)第二章

网络试读: https://www.ituring.com.cn/book/tupubarticle/30209

以下为笔记

转存失败重新上传取消正在上传…重新上传取消

1、变量

val(value的简写)用来声明一个不可变的变量,这种变量在初始赋值之后就再也不能重新赋值,对应Java中的final变量。

var(variable的简写)用来声明一个可变的变量,这种变量在初始赋值之后仍然可以再被重新赋值,对应Java中的非final变量。

val a = 10

var b = 20

变量类型通过类型推导机制来判断,但也可以显式地声明变量类型

val a: Int = 10

Kotlin完全抛弃了Java中的基本数据类型,全部使用了对象数据类型。在Java中int是关键字,而在Kotlin中Int变成了一个类,它拥有自己的方法和继承结构。

fun main() { var a: Int = 10 a = a * 10 println("a = " + a) }

2、函数(函数==方法)

fun largerNumber(num1: Int, num2: Int): Int { return max(num1, num2) }

① fun(function的简写)是定义函数的关键字,无论你定义什么函数,都一定要使用fun来声明。

② 括号里面可以声明该函数接收什么参数,参数的数量可以是任意多个

③ 参数括号后面的部分是可选的,用于声明该函数会返回什么类型的数据。如果你的函数不需要返回任何数据,这部分可以直接不写。

特别注意:当一个函数中只有一行代码时,Kotlin允许我们不必编写函数体,可以直接将唯一的一行代码写在函数定义的尾部,中间用等号连接即可。

fun largerNumber(num1: Int, num2: Int): Int = max(num1, num2)

通过类型推导机制,可以进一步简化

fun largerNumber(num1: Int, num2: Int) = max(num1, num2)

3、逻辑控制

3.1 if 条件语句

fun largerNumber(num1: Int, num2: Int): Int { var value = 0 if (num1 > num2) { value = num1 } else { value = num2 } return value }

特别注意:Kotlin 中的 if 语句相比于 Java 有一个额外的功能,它是可以有返回值的,返回值就是 if 语句每一个条件中最后一行代码的返回值。

所以可以精简为:

fun largerNumber(num1: Int, num2: Int): Int { val value = if (num1 > num2) { num1 } else { num2 } return value } //因为 value 值只等于返回值,没有变化。所以可以用 val 关键字来声明 value 变量

可以再次精简:

fun largerNumber(num1: Int, num2: Int): Int { return if (num1 > num2) { num1 } else { num2 } }

虽然此函数不止只有一行代码,但是它和只有一行代码的作用是相同的,只是返回了一下 if 语句的返回值。所以可以用语法糖再次精简:

fun largerNumber(num1: Int, num2: Int) = if (num1 > num2) { num1 } else { num2 }

还可以再精简:

fun largerNumber(num1: Int, num2: Int) = if (num1 > num2) num1 else num2

3.2 when 条件语句

当判断条件非常多的时候,就应该考虑使用when语句

when语句也可以接收返回值

fun getScore(name: String) = when (name) { "Tom" -> 86 // 匹配值 -> { 执行逻辑 } "Jim" -> 77 "Jack" -> 95 "Lily" -> 100 else -> 0 }

when语句还允许进行类型匹配,这个函数就可以使用类型匹配来判断传入的参数到底属于什么类型。

fun checkNumber(num: Number) { when (num) { is Int -> println("number is Int") is Double -> println("number is Double") else -> println("number not support") } }

fun main() { val num = 10 checkNumber(num) }

is关键字就是类型匹配的核心,它相当于 Java 中的 instanceof 关键字。checkNumber()函数接收一个Number类型的参数。Number 是 Kotlin 内置的一个抽象类,像 Int、Long、Float、Double 等与数字相关的类都是它的子类。

不带参数的用法:(Kotlin中判断字符串或对象是否相等可以直接使用==关键字)

fun getScore(name: String) = when { name.startsWith("Tom") -> 86 // 当一个分支的条件为真时则执行该分支 name == "Jim" -> 77 name == "Jack" -> 95 name == "Lily" -> 100 else -> 0 }

3.3 循环语句 for

创建一个 0 到 10 的闭区间 [0, 10]

val range = 0..10 // 0-10

使用 until 关键字来创建一个左闭右开的区间 [0, 10)

val range = 0 until 10 // 0-9

使用downTo关键字创建一个降序的区间

有了区间之后,就可以通过for-in循环来遍历这个区间:

fun main() { for (i in 0..10) { println(i) } }

fun main() { for (i in 0 until 10 step 2) { // step 2 相当于 i = i + 2 println(i) } }

fun main() { for (i in 10 downTo 1) { // 打印 10 到 1,也是可以结合step关键字跳过区间中的一些元素 println(i) } }

3.4 循环语句 while

和 Java、C 等类似

4、类与对象

Kotlin中也是使用class关键字来声明一个类

class Person { var name = "" // 使用 val 关键字的话,初始化之后就不能再重新赋值了 var age = 0 fun eat() { println(name + " is eating. He is " + age + " years old.") } }

fun main() { val p = Person() // 对这个类进行实例化: p.name = "Jack" p.age = 19 p.eat() }

当一个类中没有任何代码时,还可以将尾部的大括号省略。

5、继承

在Kotlin中非抽象类,默认是不可以被继承的

第①步: 先让父类可以被继承

open class Person { ... }

第②步: 让子类继承父类

class Student : Person() { var sno = "" var grade = 0 }

(一)Kotlin将构造函数分成了两种:主构造函数和次构造函数。

每个类默认都会有一个不带参数的主构造函数(也可以显式地给它指明参数)

class Student(val sno: String, val grade: Int) : Person() { } // 这里子类的主构造函数有两个参数 sno、grade

在对类进行实例化的时候,必须传入构造函数中要求的所有参数。比如:

val student = Student("a123", 5) // 可以将参数声明成 val,是因为构造函数中的参数是在创建实例的时候传入的,不需要重新赋值。

如果想在主构造函数中编写一些逻辑,Kotlin 给我们提供了一个 init 结构体,所有主构造函数中的逻辑都可以写在里面:

class Student(val sno: String, val grade: Int) : Person() { init { println("sno is " + sno) println("grade is " + grade) } }

(注意:Java、Kotlin 都有一个原则:子类的构造函数必须调用父类的构造函数。)

(二)Kotlin 中,子类的主构造函数,调用父类中的哪个构造函数,在继承的时候通过括号的内容来指定。

class Student(val sno: String, val grade: Int) : Person() { // 调用的是父类的默认无参构造函数 }

如果父类构造函数是有参数的

open class Person(val name: String, val age: Int) { ... }

子类就需要传入这两个字段

class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name, age) { ... }

实际使用

val student = Student("a123", 5, "Jack", 19)

(三)任何一个类只能有一个主构造函数,但可以有多个次构造函数。当一个类既有主构造函数又有次构造函数时,所有的次构造函数都必须调用主构造函数(包括间接调用)

次构造函数是通过constructor关键字来定义的

class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name, age) { constructor(name: String, age: Int) : this("", 0, name, age) { } constructor() : this("", 0) { } }

第一个次构造函数接收 name 和 age 参数,然后通过 this 关键字调用了主构造函数,并初始化 sno("")和 grade(0)这两个参数

第二个次构造函数不接收任何参数,它通过 this 关键字调用了第一个次构造函数,并初始化 name("")和 age(0)这两个参数,由于第二个次构造函数间接调用了主构造函数(第一个次构造函数直接调用了主构造函数),因此这仍然是合法的。

实际使用

val student3 = Student("a123", 5, "Jack", 19) // 通过主构造函数

val student2 = Student("Jack", 19) // 通过第一个次构造函数

val student1 = Student() // 通过第二个次构造函数

(三)特殊情况

当一个类没有显式地定义主构造函数,且定义了次构造函数时,它就是没有主构造函数的。

class Student : Person { // 既然没有主构造函数,继承 Person 类的时候就不需要加括号 constructor(name: String, age: Int) : super(name, age) { } }

由于没有主构造函数,次构造函数只能直接调用父类的构造函数,上述代码也是将 this 关键字换成了 super 关键字。

6、接口

(New→Kotlin File/Class,在弹出的对话框中输入“Study”,创建类型选择“Interface”。)

Java 中继承使用的关键字是 extends,实现接口使用的关键字是 implements;Kotlin 中统一使用冒号,中间用逗号进行分隔。

Student 类继承了 Person 类,同时还实现了 Study 接口:

interface Study { fun readBooks() fun doHomework() }

class Student(name: String, age: Int) : Person(name, age), Study { // 接口的后面不用加括号,因为没有构造函数去调用。 override fun readBooks() { println(name + " is reading.") } override fun doHomework() { println(name + " is doing homework.") } }

Study 接口中定义了 readBooks() 和 doHomework() 这两个待实现函数,因此 Student 类必须实现这两个函数。Kotlin中 使用 override 关键字来重写父类或者实现接口中的函数

fun main() { val student = Student("Jack", 19) // 创建了一个 Student 类的实例 doStudy(student) // 将它传入到了 doStudy() 函数中 } fun doStudy(study: Study) { // doStudy() 函数接收一个 Study 类型的参数,由于 Student 类实现了 Study 接口,因此 Student 类的实例是可以传递给 doStudy() 函数的。 study.readBooks() study.doHomework() // 调用了 Study 接口的 readBooks() 和 doHomework() 函数,这种就叫作面向接口编程,也可以称为多态。 }

特殊:对接口中的函数进行默认实现

interface Study { fun readBooks() fun doHomework() { println("do homework default implementation.") } }

如果接口中的一个函数拥有了函数体,这个函数体中的内容就是它的默认实现。现在当一个类去实现 Study 接口时,只会强制要求实现 readBooks() 函数,而 doHomework() 函数则可以自由选择实现或者不实现,不实现时就会自动使用默认的实现逻辑。

转存失败重新上传取消转存失败重新上传取消

Kotlin中public修饰符是默认项,而在Java中default才是默认项

Kotlin抛弃了Java中的default可见性(同一包路径下的类可见),引入了一种新的可见性概念,只对同一模块中的类可见,使用的是internal修饰符。比如我们开发了一个模块给别人使用,但是有一些函数只允许在模块内部调用,不想暴露给外部,就可以将这些函数声明成internal。

数据类:

当在一个类前面声明了 data 关键字时,就表明你希望这个类是一个数据类。Kotlin 会根据主构造函数中的参数帮你将 equals()、hashCode()、toString() 等固定且无实际逻辑意义的方法自动生成,从而大大减少了开发的工作量。

data class Cellphone(val brand: String, val price: Double)

实际应用:

fun main() { val cellphone1 = Cellphone("Samsung", 1299.99) val cellphone2 = Cellphone("Samsung", 1299.99) println(cellphone1) println("cellphone1 equals cellphone2 " + (cellphone1 == cellphone2)) // 判断这两个对象是否相等,返回 true }

单例类:

Java 中:

public class Singleton { private static Singleton instance; private Singleton() {} public synchronized static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } public void singletonTest() { System.out.println("singletonTest is called."); } }

在 getInstance() 方法中,我们判断如果当前缓存的 Singleton 实例为 null,就创建一个新的实例,否则直接返回缓存的实例即可,这就是单例模式的工作机制。

实际应用:

Singleton singleton = Singleton.getInstance(); singleton.singletonTest();

Kotlin 中:

(New→Kotlin File/Class,在弹出的对话框中输入“Singleton”,创建类型选择“Object”)

object Singleton { fun singletonTest() { println("singletonTest is called.") } }

实际应用:

Singleton.singletonTest()

这种写法虽然看上去像是静态方法的调用,但其实Kotlin在背后自动帮我们创建了一个Singleton类的实例,并且保证全局只会存在一个Singleton实例。

7、Lambda编程

7.1 集合的创建与遍历

List、Set、Map 在 Java 中都是接口,List 的主要实现类是 ArrayList 和 LinkedList,Set 的主要实现类是 HashSet,Map 的主要实现类是 HashMap

(一)List 集合

listOf()函数创建的是一个不可变的集合,只能读取,不能添加、修改、删除。

创建:

val list = ArrayList<String>() list.add("Apple") list.add("Banana") list.add("Orange") list.add("Pear") list.add("Grape")

val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")

mutableListOf()函数创建的是可变的集合。

fun main() { val list = mutableListOf("Apple", "Banana", "Orange", "Pear", "Grape") // 创建 list.add("Watermelon") // 增加 for (fruit in list) { // 遍历 println(fruit) } }

(三)Set 集合:用法几乎与 List 集合一模一样,只是将创建集合的方式换成了setOf() 和 mutableSetOf() 函数。Set 集合底层是使用 hash 映射机制来存放数据的,因此集合中的元素无法保证有序,这是和 List 集合最大的不同之处。

创建:

val set = setOf("Apple", "Banana", "Orange", "Pear", "Grape")

遍历:

for (fruit in set) { println(fruit) }

(四)Map集合:mapOf() 和 mutableMapOf() 函数

创建:

val map = HashMap<String, Int>() map["Apple"] = 1 map["Banana"] = 2 map["Orange"] = 3 map["Pear"] = 4 map["Grape"] = 5

val map = mapOf("Apple" to 1, "Banana" to 2, "Orange" to 3, "Pear" to 4, "Grape" to 5)

// to 不是关键字,而是一个 infix 函数

读取:

val number = map["Apple"]

遍历:

fun main() { val map = mapOf("Apple" to 1, "Banana" to 2, "Orange" to 3, "Pear" to 4, "Grape" to 5) for ((fruit, number) in map) { println("fruit is " + fruit + ", number is " + number) } }

7.2 集合的函数式 API

Lambda表达式的语法结构:

{参数名1: 参数类型, 参数名2: 参数类型 -> 函数体}

参数列表的结尾使用一个->符号,表示参数列表的结束以及函数体的开始。

函数体中可以编写任意行代码(虽然不建议编写太长的代码),并且最后一行代码会自动作为Lambda表达式的返回值。

举例:在一个水果集合里面找到单词最长的那个水果

第一步:

val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon") var maxLengthFruit = "" for (fruit in list) { if (fruit.length > maxLengthFruit.length) { maxLengthFruit = fruit } } println("max length fruit is " + maxLengthFruit)

第二步:

val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon") val lambda = { fruit: String -> fruit.length } val maxLengthFruit = list.maxBy(lambda)

// maxBy 函数的工作原理是根据我们传入的条件来遍历集合,从而找到该条件下的最大值。比如说想要找到单词最长的水果,那么条件自然就应该是单词的长度了。

// maxBy 接收的是一个 Lambda 类型的参数,并且会在遍历集合时,将每次遍历的值作为参数传递给 Lambda 表达式

第二、三行可简化为:

val maxLengthFruit = list.maxBy({ fruit: String -> fruit.length })

Kotlin 规定,当 Lambda 参数是函数的最后一个参数时,可以将 Lambda 表达式移到函数括号的外面,继续简化:

val maxLengthFruit = list.maxBy() { fruit: String -> fruit.length }

Kotlin 规定,当 Lambda 参数是函数的唯一一个参数的话,还可以将函数的括号省略,继续简化:

val maxLengthFruit = list.maxBy { fruit: String -> fruit.length }

Kotlin 有出色的类型推导机制,Lambda 表达式中的参数列表在大多数情况下不必声明参数类型,继续简化:

val maxLengthFruit = list.maxBy { fruit -> fruit.length }

当Lambda表达式的参数列表中只有一个参数时,也不必声明参数名,可以使用it关键字来代替,继续简化:

val maxLengthFruit = list.maxBy { it.length }

第三步:

val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon") val maxLengthFruit = list.maxBy { it.length } println("max length fruit is " + maxLengthFruit)

举例2:所有的水果名都变成大写模式

fun main() { val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon") val newList = list.map { it.toUpperCase() } for (fruit in newList) { println(fruit) } }

// map函数的功能非常强大,它可以按照我们的需求对集合中的元素进行任意的映射转换。你还可以将水果名全部转换成小写,或者是只取单词的首字母,甚至是转换成单词长度这样一个数字集合,只要在Lambda表示式中编写你需要的逻辑即可。

举例3:只想保留5个字母以内的水果(借助 filter 函数实现)

fun main() { val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon") val newList = list.filter { it.length <= 5 } .map { it.toUpperCase() } for (fruit in newList) { println(fruit) } }

举例3:any和all函数,其中any函数用于判断集合中是否至少存在一个元素满足指定条件,all函数用于判断集合中是否所有元素都满足指定条件。

fun main() { val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon") val anyResult = list.any { it.length <= 5 } val allResult = list.all { it.length <= 5 } println("anyResult is " + anyResult + ", allResult is " + allResult) }

// any函数就表示集合中是否存在5个字母以内的单词,而all函数就表示集合中是否所有单词都在5个字母以内。打印结果是 true 和 false

集合中还有许多其他函数式API,可查阅文档掌握。

7.3 Java函数式API的使用

如果我们在Kotlin代码中调用了一个Java方法,并且该方法接收一个Java单抽象方法接口参数,就可以使用函数式API。

Java单抽象方法接口指的是接口中只有一个待实现方法,如果接口中有多个待实现方法,则无法使用函数式API。

8 空指针检查

8.1 常规写法

用 Java 写:

public void doStudy(Study study) { study.readBooks(); study.doHomework(); }

这段代码安全吗?不一定,因为这要取决于调用方传入的参数是什么,如果我们向doStudy()方法传入了一个null参数,那么毫无疑问这里就会发生空指针异常。因此,更加稳妥的做法是在调用参数的方法之前先进行一个判空处理,如下所示:

public void doStudy(Study study) { if (study != null) { study.readBooks(); study.doHomework(); } }

这样就能保证不管传入的参数是什么,这段代码始终都是安全的。

用 Kotlin 写:

fun doStudy(study: Study) { study.readBooks() study.doHomework() }

Kotlin默认所有的参数和变量都不可为空,所以这里传入的Study参数也一定不会为空,我们可以放心地调用它的任何函数。

如果我们就是需要某个参数或者变量为空,就需要使用可为空的类型系统:在类名的后面加上一个问号。比如,Int 表示不可为空的整型,而 Int? 就表示可为空的整型;String 表示不可为空的字符串,而 String? 就表示可为空的字符串。

fun doStudy(study: Study?) { if (study != null) { study.readBooks() study.doHomework() } }

8.2 判空辅助工具

1、 ?.

fun doStudy(study: Study?) { study?.readBooks() study?.doHomework() }

// 当对象不为空时,正常调用相应的方法;当对象为空时,则什么都不做。

2、?:

举例:获得一段文本的长度

fun getTextLength(text: String?): Int { if (text != null) { return text.length } return 0 }

简化为:

fun getTextLength(text: String?) = text?.length ?: 0

3、!! (非空断言工具)慎用

这是一种有风险的写法,意在告诉 Kotlin,我非常确信这里的对象不会为空,所以不用你来帮我做空指针检查了,如果出现问题,你可以直接抛出空指针异常,后果由我自己承担。

4、 let 函数

fun doStudy(study: Study?) { study?.readBooks() study?.doHomework() }

可以少打几个 ?. 简化为:

fun doStudy(study: Study?) { study?.let { stu -> stu.readBooks() stu.doHomework() } }

当Lambda表达式的参数列表中只有一个参数时,可以不用声明参数名,直接使用it关键字来代替即可:

fun doStudy(study: Study?) { study?.let { it.readBooks() it.doHomework() } }

9、Kotlin 小技巧

9.1 字符串内嵌表达式

"hello, ${obj.name}. nice to meet you!"

当表达式中仅有一个变量的时候,还可以将两边的大括号省略

"hello, $name. nice to meet you!"

举例:

val brand = "Samsung" val price = 1299.99 println("Cellphone(brand=" + brand + ", price=" + price + ")")

简化为:

val brand = "Samsung" val price = 1299.99 println("Cellphone(brand=$brand, price=$price)")

9.2 给函数设定参数默认值

第一种情况:

fun printParams(num: Int, str: String = "hello") { // 第二个参数有默认值,应用是可传可不传 println("num is $num , str is $str") } fun main() { printParams(123) }

第二种情况:

fun printParams(num: Int = 100, str: String) { println("num is $num , str is $str") }

fun main() { printParams(str = "world") // Kotlin 可以通过键值对的方式来传参,顺序无所谓

// printParams(str = "world", num = 123) // 也可以这么写 }

之前的例子

class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name, age) { constructor(name: String, age: Int) : this("", 0, name, age) { } constructor() : this("", 0) { } }

可简化为:(这种主构造函数包括了两个次构造函数的范围)

class Student(val sno: String = "", val grade: Int = 0, name: String = "", age: Int = 0) : Person(name, age) { }

Kotlin 基础语法(《第一行代码(第三版)》第二章读书笔记)相关推荐

  1. 第一行代码-android-第三版-pdf扫描-思维导图-课件-源码

    第一行代码-android-第三版-pdf扫描-思维导图-课件-源码 一帮公众号各种要你关注, 各种压缩包层层套娃要密码, 还要进群, 真他妈日了gou了,找了半天 分享给大家, 毫无套路! pdf扫 ...

  2. 第一行代码第三版笔记

    第3章 Activity 主acitivity:程序运行起来首先启动的activity manifest <?xml version="1.0" encoding=" ...

  3. 第一行代码 (第三版) 第八,九,十章

    一: 泛型和委托 1.泛型 泛型类: class MyClass<T>{ fun method(param: T) : T { return param } } 泛型方法: class M ...

  4. 第一行代码 第三版 第11章网络技术 11.6.1 Retrofit 应用 报错:android.system.ErrnoException: isConnected failed: ECONNRE

    在学习第11章 11.6.1Retrofit用法,这节的时候发生的报错:书上关于这个地方并没有说. 我搜索问题的关键语句是: java.net.ConnectException: Failed to ...

  5. 第一行代码Android第二章读书笔记

    第一行代码Android第二章读书笔记 Activity 1.1 手动创建活动 1.2 Toast和Menu/销毁活动 Intent 2.1 显示/隐式 2.2 传递/返回数据 活动的生命周期 3.1 ...

  6. 算法导论第三版第二章思考题答案

    算法导论第三版第二章思考题答案 第二章思考题 算法导论第三版第二章思考题答案 2.1 2.2 2.3 2.4 汇总传送门 2.1 #include<iostream> using name ...

  7. 温习Android基础知识——《第一行代码(第三版)》读书笔记 Chapter 2 Kotlin语法

    第二章:探究新语言,快速入门Kotlin编程 Google在2017年的I/O大会上宣布Kotlin为Android的一级开发语言,之后又在2019年的I/O大会上宣布其成为Android第一开发语言 ...

  8. 安卓第一行代码第3版pdf_SPECFEM2D用户手册——第3章 网格生成——3.1 如何使用SPECFEM2D...

    参考资料 manual_SPECFEM2D.pdf 数值实现 Julia 1.4.2/MATLAB 2019a 备用系统 Ubuntu 64 地球物理局 地震波动力学实验室 谱元组 译# 声明 # 欢 ...

  9. 《算法帝国》第一章第二章读书笔记

    heeeeeeeeeeeeeeeeeeeeello! 好像有半个月都没好好写笔记了,经历了两次面试,一次败在单面,一次败在群面,哈啊-说明还完全有待努力! 稍微研究了一下,这本书好像并不需要什么代码记 ...

最新文章

  1. 跳过51单片机,直接学STM32有什么严重后果?
  2. optee的RPC设计(模型)详解
  3. 【PAT】A1060 Are They Equal *
  4. 谷歌浏览器修复工具_奇安信代码卫士协助谷歌修复漏洞 获官方致谢
  5. html浮动跟随鼠标,jQuery 图片跟随鼠标浮动
  6. Acwing第 34 场周赛
  7. [讨论] 全新首发WIN7 3264 WINSXS进一步精简批处理公测
  8. 【PTA L2-012】关于堆的判断(堆的建立和特殊字符串的读入)
  9. JAVA中日期格式格式化
  10. 为啥淘宝网,拍拍网上的windows7激…
  11. 2022BUAA数据结构期末大作业的一些想法
  12. ChucK初步(8)
  13. Redis集群和应用——02
  14. 安装rpm 树莓派4_树莓派3上安装使用centos 7.4
  15. Typescript 2+迷你书 :从入门到不放弃
  16. 谈谈最近管理情绪和时间的心得:真的是破心中贼难
  17. 恢复计算机什么意思,Win10重置此电脑是什么意思数据会全部丢失吗
  18. Jupyter Notebook 修改默认打开的文件夹的位置 jupyter_notebook_config.py改不了默认配置文件更改
  19. 计算机应用基础 本科类 第二阶段b201609,江南大学。计算机应用基础(本科类)第一阶段B201609.doc...
  20. 12306.cn网站挂了”好文章收藏,引发的技术架构问题讨论。

热门文章

  1. [编程题] 困兽之斗
  2. 防止登录成功后重复刷新页面跳回登录页面
  3. 通常所说微型计算机的奔3,求江西省2011年计算机等级一级考试试题
  4. Linux系统ISO镜像文件下载地址
  5. 镁客网每周硬科技领域投融资汇总(12.16-12.22),第四范式成“五大行”联合投资唯一创企...
  6. Java的System.currentTimeMillis()的性能问题
  7. 基于SpringBoot前后端分离的众筹系统(附源码)
  8. android 消息推送方法,一种基于Android系统的消息推送方法技术方案
  9. 为什么抖音张同学这么火爆?用 Python 分析 1w+条评论数据,我发现了其中的秘密
  10. 子进程child_process的spawn模块使用