12.24-Spring IOC底层运行原理?
“控制反转(IoC)”也称为“依赖注入(DI)”,是一个定义对象依赖的过程,对象只和构造参数,工厂方法参数,对象实例属性或工厂方法返回相关。容器在创建这些 bean 的时 候注入这些依赖。这个过程是一个反向的过程,所以命名为依赖反转,对象实例的创建由其 提供的构造方法或服务定位机制来实现。
IOC底层原理使用技术
- xml配置文件
- dom4j解析配置的xml文件
- 工厂、策略、委托等设计模式
- 反射
- 动态代理(JDK自带动态代理(实现了接口的类)、CGLib(未实现接口的类))
那么这几种技术是怎么用到IOC里面的呢?
第一步:创建xml配置文件,配置要创建对象类
第二步:创建工厂类,使用dom4j解析配置文件+反射
如果类的路径或类名发生了变化,只需更改配置文件即可,降低了类之间的耦合度。
12.23-讲讲Spring事务的传播属性?
事务的传播属性(Propagation)
1) REQUIRED ,这个是默认的属性
Support a current transaction, create a new one if none exists.
如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
被设置成这个级别时,会为每一个被调用的方法创建一个逻辑事务域。如果前面的方法已经创建了事务,那么后面的方法支持当前的事务,如果当前没有事务会重新建立事务。
如图所示:
2) MANDATORY
Support a current transaction, throw an exception if none exists.支持当前事务,如果当前没有事务,就抛出异常。
3) NEVER
Execute non-transactionally, throw an exception if a transaction exists.
以非事务方式执行,如果当前存在事务,则抛出异常。
4) NOT_SUPPORTED
Execute non-transactionally, suspend the current transaction if one exists.
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
5) REQUIRES_NEW
Create a new transaction, suspend the current transaction if one exists.
新建事务,如果当前存在事务,把当前事务挂起。
如图所示:
6) SUPPORTS
Support a current transaction, execute non-transactionally if none exists.
支持当前事务,如果当前没有事务,就以非事务方式执行。
7) NESTED
Execute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else.
支持当前事务,新增Savepoint点,与当前事务同步提交或回滚。
嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。
注: PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区别
它们非常 类似,都像一个嵌套事务,如果不存在一个活动的事务,都会开启一个新的事务。使用PROPAGATION_REQUIRES_NEW时,内层事务与外层事务就像两个独立的事务一样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。两个事务互不影响。两个事务不是一个真正的嵌套事务。同时它需要JTA 事务管理器的支持。
使用PROPAGATION_NESTED时,外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚,它是一个真正的嵌套事务。
12.15-假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以某个固定的已知的前缀开头的,如果将它们全部找出来?如果这个 redis 正在给线上的业务提供服务,那使用 keys 指令会有什么问题?
使用keys指令可以扫出指定模式的key列表。
如果这个redis正在给线上的业务提供服务,那使用keys指令会有什么问题:
redis是 单线程的,keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用scan指令,scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长。
12.14-Redis 最适合的场景?
Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢?
如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:
1 、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
2 、Redis支持数据的备份,即master-slave模式的数据备份。
3 、Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
1. 会话缓存(Session Cache)
最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?
幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。
2. 全页缓存(FPC)
除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。
再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。
此外,对WordPress的用户来说,Pantheon有一个非常好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。
3. 队列
Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。
如果你快速的在Google中搜索“Redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用Redis创建非常好的后端工具,以满足各种队列需求。例如,Celery有一个后台就是使用Redis作为broker,你可以从这里去查看。
4. 排行榜/计数器
Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:
当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行:
ZRANGE user_scores 0 10 WITHSCORES
Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你可以在这里看到。
5. 发布/订阅
发布/订阅的使用场景确实非常多。人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统。
12.14-Redis 的持久化机制是什么?各自的优缺点?
Redis 提供两种持久化机制 RDB 和 AOF 机制:
1、RDB(Redis DataBase)持久化方式:是指用数据集快照的方式半持久化模式) 记录 redis 数据库的所有键值对,在某个时间点将数据写入一个临时文件。
持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。
优点:
- 只有一个文件 dump.rdb,方便持久化。
- 容灾性好,一个文件可以保存到安全的磁盘。
- 性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能)
- 相对于数据集大时,比 AOF 的启动效率更高。
缺点:
- 数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候)
2、AOF(Append-only file)持久化方式:是指所有的命令行记录以 redis 命令请求协议的格式完全持久化存储)保存为 aof 文件。
优点:
- 数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次命令操作就记录到 aof 文件中一次。
- 通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。
- AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作的 flushall)
缺点:
- AOF 文件比 RDB 文件大,且恢复速度慢。
- 数据集大的时候,比 rdb 启动效率低
12.9-数据库引入连接池的好处
1. 资源重用
由于数据库连接得到重用,避免了频繁创建、释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增进了系统运行环境的平稳性(减少内存碎片以及数据库临时进程/线程的数量)。
2. 更快的系统响应速度
数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间。
3. 新的资源分配手段
对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接的配置,实现数据库连接技术。某一应用最大可用数据库连接数的限制,避免某一应用独占所有数据库资源。
4. 统一的连接管理,避免数据库连接泄漏
在较为完备的数据库连接池实现中,可根据预先的连接占用超时设定,强制收回被占用连接。从而避免了常规数据库连接操作中可能出现的资源泄漏。一个最小化的数据库连接池实现.
12.8-JSP九大内置对象是哪些,作用是什么?
JSP中一共预先定义了9个这样的对象,分别为:request、response、session、application、out、pagecontext、config、page、exception
request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。(包括头信息、系统信息、请求方式以及请求参数等)。request对象的作用域为一次请求。
response 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。response对象也具有作用域,它只在JSP页面内有效。
session 对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。session对象内部使用Map类来保存数据,因此保存数据的格式为 “Key/value”。 session对象的value可以使复杂的对象类型,而不仅仅局限于字符串类型。
application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。与session对象相比,application对象生命周期更长,类似于系统的“全局变量”。
out 对象用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。在使用 out 对象输出数据时,可以对数据缓冲区进行操作,及时清除缓冲区中的残余数据,为其他的输出让出缓冲空间。待数据输出完毕后,要及时关闭输出流。
pageContext 对象的作用是取得任何范围的参数,通过它可以获取 JSP页面的out、request、reponse、session、application 等对象。pageContext对象的创建和初始化都是由容器来完成的,在JSP页面中可以直接使用 pageContext对象。
config 对象的主要作用是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() 方法可以获取一个config对象。当一个Servlet 初始化时,容器把某些信息通过 config对象传递给这个 Servlet。 开发者可以在web.xml 文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数。
page 对象代表JSP本身,只有在JSP页面内才是合法的。 page隐含对象本质上包含当前 Servlet接口引用的变量,类似于Java编程中的 this 指针。
exception 对象的作用是显示异常信息,只有在包含 isErrorPage="true" 的页面中才可以被使用,在一般的JSP页面中使用该对象将无法编译JSP文件。excepation对象和Java的所有对象一样,都具有系统提供的继承结构。exception 对象几乎定义了所有异常情况。在Java程序中,可以使用try/catch关键字来处理异常情况; 如果在JSP页面中出现没有捕获到的异常,就会生成 exception 对象,并把 exception 对象传送到在page指令中设定的错误页面中,然后在错误页面中处理相应的 exception 对象。
12.7-sql语句分为哪几种?
SQL语言按照实现的功能不同,主要分为3类:数据操纵语言(DML),数据定义语言(DDL),数据控制语言(DCL)。
- 数据操纵语言(DML):主要用来处理数据库中的数据内容。允许用户对数据库中的数据进行查询 ,插入,更新和删除等操作
- 数据定义语言(DDL):是一组SQL命令,用于创建和定义数据库对象,并且将对这些对象的定义保存到数据字典中。通过DDL语句可以创建数据库对象,修改数据库对象和删除数据库对象等。
- 数据控制语言(DCL):数据控制语言用于修改数据库结构的操作权限。
11.23-说一说servlet的生命周期
servlet的生命周期分为四个阶段:1:实例化 2:初始化 3:处理请求服务 4:对象销毁
servlet在第一次被访问就会实例化一个servlet对象,然后立即调用init方法初始化对象,创建后的servlet对象会一直留在服务器内部,为后续的访问提供服务,当有请求访问servlet,服务就会调用service方法处理请求,当服务器关闭或web项目被移除,随着web应用的销毁,servlet也就被销毁,在销毁之前会调用destroy方法进行处理。
11.20-说一说MySQL数据库的四类索引
mysql索引的四种类型:主键索引
、唯一索引
、普通索引
和全文索引
。通过给字段添加索引
可以提高数据的读取速度
,提高项目的并发能力和抗压能力。
主键索引:
主键是一种唯一性索引,但它必须指定为PRIMARY KEY
,每个表只能有一个主键。
唯一索引:
索引列的所有值都只能出现一次,即必须唯一
,值可以为空
。
普通索引 :
基本
的索引类型,值可以为空,没有唯一性的限制。
全文索引:
全文索引的索引类型为FULLTEXT
。全文索引可以在varchar、char、text
类型的列上创建。可以通过ALTER TABLE
或CREATE INDEX命令创建。对于大规模的数据集,通过ALTER TABLE(或者CREATE INDEX)命令创建全文索引要比把记录插入带有全文索引的空表更快。MyISAM
支持全文索引,InnoDB
在mysql5.6之后支持了全文索引
。
11.19-说一说MySQL的事务隔离级别有哪些
·未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
·提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
·可重复读(Repeated Read):在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
·串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
11.17-讲述一下事务的四大特性
1、原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,要么全部完成,要么均不执行。
2、一致性(Consistency):几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致。
3、隔离性(Isolation):事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的。
4、持久性(Durability):对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障。
11.13-描述一下数据库三范式
1.第一范式(确保每列保持原子性)
第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。
2.第二范式(确保表中的每列都和主键相关)
第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
比如要设计一个订单信息表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键
3.第三范式(确保每列都和主键列直接相关,而不是间接相关)
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段
11.12-数据库的左连接、右连接、中连接、全连接有什么区别
- left join (左连接):返回包括左表中的所有记录和右表中连接字段相等的记录。
- right join (右连接):返回包括右表中的所有记录和左表中连接字段相等的记录。
- inner join (等值连接或者叫内连接):只返回两个表中连接字段相等的行。
- full join (全外连接):返回左右表中所有的记录和左右表中连接字段相等的记录。
11.11-HashMap的get()方法的工作原理
首先根据对象的Hash值进行数组方面的寻找,然后找到这个数组之后,判断key是不是唯一,如果key唯一,则直接返回,如果不唯一,则使用equals进行值的判断,最后返回数据。
11.10-什么是事务控制
在MySql中,默认的事务是自动提交的,如果想要事务不自动提交,需要明确的做事务控制,MySQL通过SET AUTOCOMMIT, START TRANSACTION, COMMIT 和 ROLLBACK等等语句对事务进行控制。
语法:
START TRANSACTION | BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO]RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO]RELEASE]
SET AUTOCOMMIT={0 | 1}
- START TRANSACTION 或 BEGIN开始一项事务。
- COMMIT提交事务,ROLLBACK回滚事务。
- CHAIN和RELEASE用于定义在事务提交或回滚后的操作,CHAIN会开始一个新的事务,与刚才的事务完全处于隔离,
- 而RELEASE则表示事物提交或回滚后断开与客户端的连接。
- SET AUTOCOMMIT修改当前连接的方式,0代表需要手动提交事务,需要使用明确的命令提交事务,1代表自动提交事务。
11.9-MySQL中in和exists区别
MySQL中的in语句是把外表和内表作join连接,而exists语句是对外表作nest loop循环,每次loop循环再对内表进行查询。
1、如果查询的两个表大小相当,那么用in和exists差别不大。
2、如果两个表中一个表大,另一个是表小,那么IN适合于外表大而子查询表小的情况。
3、如果两个表中一个表大,另一个是表小,EXISTS适合于外表小而子查询表大的情况。
11.6-Mysql常用的引擎
InnoDB:支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、删除操作的数据库,也可以选择InnoDB,因为支持事务的提交(commit)和回滚(rollback)。
MyISAM:插入数据快,空间和内存使用比较低。如果表主要是用于插入新记录和读出记录,那么选择MyISAM能实现处理高效率。如果应用的完整性、并发性要求比较低,也可以使用。如果数据表主要用来插入和查询记录,则MyISAM引擎能提供较高的处理效率。
MEMORY:所有的数据都在内存中,数据的处理速度快,但是安全性不高。如果需要很快的读写速度,对数据的安全性要求较低,可以选择MEMOEY。它对表的大小有要求,不能建立太大的表。所以,这类数据库只使用在相对较小的数据库表。如果只是临时存放数据,数据量不大,并且不需要较高的数据安全性,可以选择将数据保存在内存中的Memory引擎,MySQL中使用该引擎作为临时表,存放查询的中间结果。
11.5-Jquery的html()和text()有什么区别
- text()只能返回文本内容,而html()可以返回元素的全部内容
- text(str)设置元素内容时,只有文本内容有效,其余内容无效;而html(str)设置元素内容时,所有内容有效(包括标签)
- text()返回所有匹配元素的内容,叠加;而html()只返回第一个匹配元素的内容
11.4-比较一下String,StringBuilder和StringBuffer
- 在执行速度方面运行速度快慢为:StringBuilder > StringBuffer > String
String为字符串常量,String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。而StringBuilder和StringBuffer均为字符串变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。
- 在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。
11.3-使用JQuery如何获取和设置某元素属性的值?
attr() 获取或修改标签的属性值
//获取id为p的标签的属性值
$('#p').attr('class')
//如果存在就是修改,如果不存在就是添加
$('#p').attr('class','red')
11.2-使用Treemap为什么对作为键的类实现自然排序接口?
在TreeMap中,如果自定义一个类作为key值,不告知排序规则的话,运行就会报错,因为内部会对Key进行排序,所以,需要通过:
- 在类中实现Comparable,重写compareTo方法
- 在构造函数中new Comparator 匿名内部类,重写compare 方法
10.30-PrintStream、BufferedWriter、PrintWriter 的比较?
1. PrintStream类的输出功能非常强大,通常如果需要输出文本内容,都应该将输出流包装成PrintStream后进行输出。与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的内部标志。另外,为了自动刷新,可以创建一个 PrintStream
2. BufferedWriter:将文本写入字符输出流,缓冲各个字符从而提供单个字符,数组和字符串的高效写入。通过write()方法可以将获取到的字符输出,然后通过newLine()进行换行操作。BufferedWriter中的字符流必须通过调用flush方法才能将其刷新出去。并且BufferedWriter只能对字符流进行操作。如果要对字节流操作,则使用BufferedInputStream
3. PrintWriter的println方法自动添加换行,不会抛异常,若关心异常,需要调用checkError方法看是否有异常发生,PrintWriter构造方法可指定参数,实现自动刷新缓存(autoflush);PrintStream主要操作byte流,而PrintWriter用来操作字符流。读取文本文件时一般用后者。
10.29-JQuery常用选择器有哪些?
1、jquery的基本选择器
基本选择器是JQuery最常用的选择器,也是最简单的选择器,它通过元素id、class和标签名来查找DOM元素。
2、jquery层次选择器
层次选择器通过DOM元素间的层次关系来获取元素,主要的层次关系包括父子、后代、相邻、兄弟关系。
3、jquery过滤选择器
过滤选择器主要是通过特定的过滤规则来筛选出所需的DOM元素,过滤规则与CSS中的伪类选择器语法相同,即选择器都以一个冒号(:)开头。按照不同的过滤规则,过滤选择器可以分为基本过滤,内容过滤,可见性过滤,属性过滤,子元素过滤和表单对象属性过滤选择器共六种选择器。
4、jquery表单选择器
利用表单选择器我们可以极其方便地获取表单的某个或某类型的元素。
10.28-在JavaScript中,this关键字有什么含义?
在JavaScript中this的含义可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript中函数的调用有以下几种方式:
- 作为对象方法调用,这种调用方式属于全局调用,这里的this就成了全局对象;
- 作为函数调用,这时this就指这个上级对象;
- 作为构造函数调用,所谓构造函数,就是通过这个函数生成一个新对象(object),这时this就指这个新对象;
- 使用apply或call调用,apply()是函数对象的一个方法,它应用某一对象的一个方法,用另一个对象替换当前对象。
10.27-讲述一下CSS有哪些常用选择器
- 标签选择器(如:body, div, p, ul, li)
- 类选择器(如:class="head", class="head_logo")
- ID选择器(如:id="name", id="name_txt")
- 全局选择器(如:*号)
- 组合选择器(如:.head .head_logo,注意两选择器用空格键分开)
- 继承选择器(如:div p,注意两选择器用空格键分开)
- 伪类选择器(如:就是链接样式,a元素的伪类,4种不同的状态:link、visited、active、hover。)
- 字符串匹配的属性选择符(^ $ *三种,分别对应开始、结尾、包含)
10.26-HTML中导入JavaScript有几种方式
在HTML中导入JavaScript有两种方法,一种是在页面中直接嵌入JavaScript代码,另一种是链接外部JavaScript文件。
1、Html5 页面中使用 <script> 标签容纳 JavaScript 代码;
2、Html5 页面中使用 <script src="xxx.js"></script> 引入同路径下的 xxx.js 文件中的 JavaScript 代码;
3、直接在HTML标签中插入js代码
<input name="btn" type="button" value="弹出消息框" οnclick="javascript:alert('欢迎你');"/>
10.23-Java和JavaScript区别?
- Java的源代码在执行之前必须经过编译,而JavaScript的代码不需要,可以由浏览器直接解释执行。
- Java变量在使用之前必须声明,而JavaScript不需要。
- JavaScript 的面向对象是基于原型的(prototype-based)实现的,Java 是基于类(class-based)的。
- JavaScript是动态类型语言,而Java是静态类型语言。Java在定义了一个数组的长度以后就不能再改变了,JavaScript却可以。
- java主要在服务端运行;javascript主要运行在客户端浏览器中。
10-16-什么叫做线程死锁,如何防止发生死锁?
当线程A持有独占锁a,并尝试去获取独占锁b的同时,线程B持有独占锁b,并尝试获取独占锁a的情况下,就会发生AB两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称为死锁。
- 互斥条件:一个资源每次只能被一个进程使用。
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
- 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
- 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
10.15-线程有两种创建方式,都是如何创建的?
- 继承Thread类创建线程类
- 定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。
- 创建Thread子类的实例,即创建了线程对象。
- 调用线程对象的start()方法来启动该线程。
- 实现Runnable接口
- 定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
- 创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
- 调用线程对象的start()方法来启动该线程。
10.14-要让一个类能够被序列化要怎么做?如何让类中的某个成员变量不被序列化?如何保证类文件被改动后仍可以读出之前序列化好的对象?
- 要让一个类支持序列化,只需要让这个类实现接口java.io.Serializable,Serializable没有定义任何方法,只是一个标记接口。
- 一个类中可能有很多的成员变量,如果有些不想进行序列化(保存)。可以使用transient(临时,不需要保存)关键字声明不需要序列化的成员变量。
- Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。为了保证类文件被改动后仍可以读出之前序列号的对象,用static final关键字修饰serialVersionUID即可。
10.13-Comparable 和 Comparator 接口的区别
相同点
- Comparable和Comparator都是用来实现对象的比较、排序
- 要想对象比较、排序,都需要实现Comparable或Comparator接口
- Comparable和Comparator都是Java的接口
不同点
- Comparator位于java.util包下,而Comparable位于java.lang包下
- Comparable接口的实现是在类的内部(如 String、Integer已经实现了Comparable接口,自己就可以完成比较大小操作),Comparator接口的实现是在类的外部(可以理解为一个是自已完成比较,一个是外部程序实现比较)
- 实现Comparable接口要重写compareTo方法, 在compareTo方法里面实现比较
public class Student implements Comparable {
String name;
int age
public int compareTo(Student another) {
int i = 0;
i = name.compareTo(another.name);
if(i == 0) {
return age - another.age;
} else {
return i;
}
}
}
这时我们可以直接用 Collections.sort( StudentList ) 对其排序了.(
**只需传入要排序的列表**)
- 实现Comparator需要重写 compare 方法
public class Student{
String name;
int age
}
class StudentComparator implements Comparator {
public int compare(Student one, Student another) {
int i = 0;
i = one.name.compareTo(another.name);
if(i == 0) {
return one.age - another.age;
} else {
return i; }
}
}
Collections.sort( StudentList , new StudentComparator()) 可以对其排序(
**不仅要传入待排序的列表,还要传入实现了Comparator的类的对象**)
10.12-在输出流中使用的.flush()方法有什么作用
.flush()方法的作用是强制将缓存中的输出流(字节流,字符流等)输出;因为输出流在进行输出时,比如像某个文件中写入内容,其实是先将输出流写入到缓冲区,当缓冲区写满后才将缓冲区的内容输出到文件中。但是当主机完成输出流的输出后,有可能缓冲区这个时候还没有被填满,这样的话,就会一直等待主机发送内容,这时候,就可以使用flush将缓冲区的内容强制输出到文件中,清空缓冲区。
所以,一般在关闭输出流之前,要先调用flush方法强制缓冲区中的内容输出,并清空缓冲区。
10.10-HashMap与HashTable区别
- HashMap 不是线程安全的HashTable 是线程安全 Collection。
- HashMap 允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。
- HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsValue 和 containsKey。因为 contains 方法容易让人引起误解。
- HashTable 继承自 Dictionary 类,而 HashMap 是 Java1.2 引进的 Map interface 的一个实现。
- HashTable 的方法是 Synchronize 的,而 HashMap 不是,在多个线程访问 Hashtable 时,不需要自己为它的方法实现同步,而 HashMap 就必须为之提供外同步。
10.9-ArrayList、LinkedList、Vector三者的相同和不同点
ArrayList、Vector和LinkedList类均在java.util包下
ArrayList和Vector都是基于存储元素的Object[] array来实现的,它们会在内存中开辟一块连续的空间来存储,因为数据存储是连续的,所以它们支持用下标来访问元素,索引数据的速度比较快。
1)ArrayList和Vector都有一个初始化的容量大小,当里面存储的元素超过初始的大小时就需要动态地扩充它们的存储空间,Vector默认扩充为原来的两倍(每次扩充空间的大小可以设置),ArrayList默认扩充为原来的1.5倍(没有提供方法来设置空间扩充的方法)。
2)ArrayList和Vector最大的区别就是synchronization的使用,没有一个ArrayList的方法是同步的,而Vector的绝大多数方法(如add,insert,remove,set,equals,hashcode)都是直接或间接同步的,所以Vector是线程安全的,ArrayList不是线程安全的。正是由于Vector提供了线程安全的机制,其性能上也要稍逊于ArrayList;
LinkedList是采用双向列表来实现的,对数据的索引需要从列表头开始遍历,因此用于随机访问则效率比较低,但是插入元素时不需要对数据进行移动,因此插入效率较高。同时,LinkedList是非线程安全的容器。当对数据的主要操作是索引或只在集合的末端增加、删除元素时,使用ArrayList或Vector效率比较高,当对数据的操作主要为指定位置或删除操作时,使用LikedList效率比较高;当在多线程中选用Vector较为安全。
9.30-Calender,Date,long三种类型如何表示时间,以及互相之间的转换
Calendar通过get instance()方法创建对象,然后用它的set方法设置时间;Date表示时间是直接new Date(),可以获取当前时间。Long类型可以表示为时间的毫秒数表达,可以进行除法运算获得具体时间。
Date对象可以通过calendar的getTime()方法获得(Date currentDate = calendar.getTime();),然后进一步Long类型具体毫秒数可以再通过Date对象的getTime()方法获取。反过来,Long类型的毫秒数转化为Date对象可以通过new Date()创建Date对象时传入毫秒数,然后Calendar对象可以再通过Calendar.getInstance()创建的对象的setTime()方法传入Date对象即可转换。
9.29-重载和重写的区别
重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准。
重写方法的规则:
- 参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。
- 返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。
- 访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
- 重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。例如:父类的一个方法申明了一个检查异常IOException,在重写这个方法是就不能抛出Exception,只能抛出IOException的子类异常,可以抛出非检查异常。
而重载的规则:
- 必须具有不同的参数列表;
- 可以有不同的返回类型,只要参数列表不同就可以了;
- 可以有不同的访问修饰符;
- 可以抛出不同的异常;
9.28-多态的两种表现形式
多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。多态的两种形式:重写和重载
重写:在继承过程中,子类定义了与父类中名称相同,参数相同,返回值相同的方法称为重写,重写时,子类不能比父类的访问权限更严格
重载:在同一个类中,定义了多个名称相同,参数不同的方法称为重载,跟返回值无关。
9.27-Java的三大特性详解
1. 封装
封装是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系。系统的其他对象只能通过数据外面的公开的方法来与这个对象进行交互,也就是说用户是无需知道对象内部的细节,但可以通过该对象对外的提供的接口来访问该对象。
对于封装而言,一个对象它所封装的是自己的属性和方法,所以它是不需要依赖其他对象就可以完成自己的操作。
使用封装下面几个好处:
1、良好的封装能够减少耦合。
2、类内部的结构可以自由修改。
3、可以对成员进行更精确的控制。
4、隐藏信息,实现细节。
2. 继承
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。可以理解成是“is-a”的关系,如果有两个对象A和B,若可以描述为“A是B”,则可以表示 A 继承 B。
特点:
1. 继承关系是传递的。若类C继承类B,类B继承类A(多层继承),则类C既有从类B那里继承下来的属性与方法,也有从类A那里继承下来的属性与方法,还可以有自己新定义的属性和方法。继承来的属性和方法尽管是隐式的,但仍是类C的属性和方法。继承是在一些比较一般的类的基础上构造、建立和扩充新类的最有效的手段。
2. 提供多重继承机制。从理论上说,一个类可以是多个一般类的特殊类,它可以从多个一般类中继承属性与方法,这便是多重继承。Java出于安全性和可靠性的考虑,仅支持单重继承,而通过使用接口机制来实现多重继承。
3. 提高代码的复用性。若类B继承类A,那么建立类B时只需要再描述与基类(类A)不同的少量特征(数据成员和成员方法)即可。这种做法能减小代码和数据的冗余度,大大增加程序的重用性。
4. Java只支持单继承,不支持多继承。也就是一个类只能有一个父类,不可以有多个父类。
3. 多态
面向对象的多态性,即“一个接口,多个方法”。多态性体现在父类中定义的属性和方法被子类继承后,可以具有不同的属性或表现方式。多态性允许一个接口被多个同类使用,弥补了单继承的不足。方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。
多态存在的三个必要条件:
- 继承
- 重写
- 父类引用指向子类对象
9.25-什么是驼峰命名法?类,方法,变量,常量应该如何命名?
驼峰命名法分为:小驼峰式:(little camel-case) 和大驼峰式:(big camel-case)
1. 小驼峰式:第一个单词首字母小写,后面其他单词首字母大写
比如string firstName = string.Empty;
方法名、参数名、成员变量、局部变量都统一使用都使用小驼峰式命名法。
2. 大驼峰式:每个单词的第一个字母都大写
比如string FirstName = string.Empty;
类名使用大驼峰式命名法。
持此之外,常量命名全部大写,单词间用下划线隔开。
9.24-Java中4种权限修饰符及其作用范围
Java中四种权限修饰符:public(公共的)、protected(受保护的)、default(默认的)、private(私有的)
作用范围如图:
1. public:可以被所有其他类所访问。
2. protected:子类及同一个包中类都可以访问。
3. default(默认):同一包中的类可以访问
4. private:只能被自己访问和修改。
9.23-类和对象之间的区别和联系
类的概念:类是具有相同属性和服务的一组对象的集合。它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和服务两个主要部分。在面向对象的编程语言中,类是一个独立的程序单位,它应该有一个类名并包括属性说明和服务说明两个主要部分。
对象的概念:对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组服务组成。从更抽象的角度来说,对象是问题域或实现域中某些事物的一个抽象,它反映该事物在系统中需要保存的信息和发挥的作用;它是一组属性和有权对这些属性进行操作的一组服务的封装体。客观世界是由对象和对象之间的联系组成的。
类与对象的关系就如模具和铸件的关系,类的实例化结果就是对象,而对一类对象的抽象就是类.类描述了一组有相同特性(属性)和相同行为(方法)的对象。
9.22-描述一下Java的垃圾回收GC
是用于回收内存空间的,当程序员创建对象时,GC就开始监控对象的地址大小以及使用情况。通常GC采用有效图的方式记录和管理对中的所有对象通过这种方式确确定哪些对象是可达的,哪些对象是不可达的。如果当继续确定某些对象不能访问,他就会回收这些内存空间。同时也可以通过手动执行System.gc通知GC执行,但是不一定能保证一定能执行。
详细介绍可看参考书籍《深入理解 Java 虚拟机》或网上相关链接:
https://www.infoq.cn/article/ZOYqRI4c-BFKmUBmzmKN
https://juejin.im/post/6854573218934554638