1.java的特性
-
封装
封装具有一下优点:便于使用者正确、方便的使用系统,防止使用者错误修改系统属性;
有助于建立各个系统之间的松耦合关系;
提高软件的可重用性;
降低了大型系统的风险,即便整个系统不成功,个别独立的子系统有可能还有价值。 -
继承
子类和父类之间的继承关系,子类可以获取到父类的属性和方法。 -
多态
java语言允许某个类型的引用变量引用子类的实例,而且可以对这个引用变量进行类型转换。 -
抽象
现实生活中的事物被抽象成对象,把具有相同属性和行为的对象被抽象成类,再从具有相同属性和行为的类中抽象出父类。
2.HashMap和Hashtable的区别
HashMap 不是线程安全的
HashMap 是 map 接口的实现类,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值。HashMap 允许 null key 和 null value,而 HashTable 不允许。
HashTable 是线程安全 Collection。
都完成了Map 接口
区别
HashMap允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。
HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsValue 和 containsKey。因为 contains 方法容易让人引起误解。
HashTable 继承自 Dictionary 类,而 HashMap 是 Java1.2 引进的 Map interface 的一个实现。
HashTable 的方法是 Synchronize 的,而 HashMap 不是,在多个线程访问 Hashtable 时,不需要自己为它的方法实现同步,而 HashMap 就必须为之提供外同步。
Hashtable 和 HashMap 采用的 hash/rehash 算法都大概一样,所以性能不会有很大的差异。
3.list和array的区别
list和array都可以根据索引来取其中的元素。
list是列表,list中的元素的数据类型可以不一样。array是数组,数组中的元素的数据类型必须一样。
list不可以进行四则运算,array可以进行四则运算。
4.redis的常用命令
一、全局命令
1、查询键
keys * 查询所有的键,会遍历所有的键值,复杂度O(n)
2、键总数
dbsize 查询键总数,直接获取redis内置的键总数变量,复杂度O(1)
3、检查键是否存在
exists key 存在返回1,不存在返回0
4、删除键O(k)
del key [key…] 返回结果为成功删除键的个数
5、键过期
expire key seconds 当超过过期时间,会自动删除,key在seconds秒后过期
expireat key timestamp 键在秒级时间戳timestamp后过期
pexpire key milliseconds 当超过过期时间,会自动删除,key在milliseconds毫秒后过期
pexpireat key milliseconds-timestamp key在豪秒级时间戳timestamp后过期
ttl 命令可以查看键hello的剩余过期时间,单位:秒(>0剩余过期时间;-1没设置过期时间;-2键不存在)
pttl是毫秒
6、键的数据结构类型
type key 如果键hello是字符串类型,则返回string;如果键不存在,则返回none
7、键重命名
rename key newkey
renamenx key newkey 只有newkey不存在时才会被覆盖
数据库管理
1、切换数据库
select dbIndex
默认16个数据库:0-15,进入redis后默认是0库。不建议使用多个数据库
2、flushdb / flushall
用于清除数据库,flushdb只清除当前数据库,flushall清除所有数据库。
redis的数据存储方式
redis 提供持久化功能,把数据以文件的方式持久化到硬盘中,但是目前大多都是redis配合关系数据库使用,持久化仍然由关系数据完成,redis自身的持久化用于保证数据的安全性,以保证存放在redis的内存数据在没有被全部被持久化到关系中如果redis服务器发生灾难数据的完整性。
1.Snapshotting即快照方式,存储方式在redis.conf中的配置为 save 900 1 #当有一条Keys数据被改变时,900秒刷新到Disk一次
save 300 10 #当有10条Keys数据被改变时,300秒刷新到Disk一次
save 60 10000 #当有10000条Keys数据被改变时,60秒刷新到Disk一次 可根据需求修改,当内存数据的变动满足如上配置时,redis会给但是内存数据做snapshot,完整保存当时内存数据状态,文件存储在dump.rdb中,当做一次新的snapshot时,进程会把此时的内存的snapshot写在一个临时文件中,当临时文件写完,用新写的临时文件替换原有的dump.rdb文件,并删除旧的 RDB 文件。。每次快照持久化都是将内存数据完整写入到磁盘一次,并不是增量的只同步脏数据。如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘io操作,可能会严重影响性能。
另外由于快照方式是在一定间隔时间做一次的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。
2.aof方式,aof方式是以日志的方式来存储数据,即它将记录每次对于redis的操作,每一次操作都有一条相应的记录,因此aof方式产生的文件比snapshot方式要大。比如set test 1然后调用 100次 incr test,则aof方式会存储这100次操作,但是对于客户端有用的却只是最后一次修改后的值,如果此时做了snapshot,则dump.rdb文件只是保存了最后一次操作后的值,而appendonly.aof则保存了每一次操作的记录。aof方式在配置文件中的体现
appendonly yes #打开aof方式
appendfsync always //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
- string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
- Hash(哈希)是一个键值(key=>value)对集合。
127.0.0.1:6379> HMSET myhash name "yzl" age "20"
OK
127.0.0.1:6379> HGET myhash name
"yzl"
127.0.0.1:6379> HGET myhash age
"20"
- List(列表)
127.0.0.1:6379> LPUSH fruitlist apple
(integer) 1
127.0.0.1:6379> LPUSH fruitlist banana
(integer) 2
127.0.0.1:6379> LPUSH fruitlist orange
(integer) 3
127.0.0.1:6379> LRANGE fruitlist 1 2
1) "banana"
2) "apple"
- Set(集合)
Redis的Set是string类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 - zset(sorted set:有序集合)
zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
127.0.0.1:6379> zadd price 3 pen
(integer) 1
127.0.0.1:6379> zadd price 5 apple
(integer) 1
127.0.0.1:6379> zadd price 50 dinner
(integer) 1
127.0.0.1:6379> zadd price 100 basketball
(integer) 1
127.0.0.1:6379> zrangebyscore price 10 200
1) "dinner"
2) "basketball"
进程与线程的基础区别:
1、进程是资源分配的最小单位,线程是程序执行的最小单位(资源调度的最小单位)
2、进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。
而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。
3、线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。
4、但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。