1、什么是单例模式?使用单例模式有什么好处?有哪些常用的单例模式实现方式?各自的应用场景是什么?请你举例说明哪些地方用到了单例模式?
单例是一种设计模式,应用该模式的类只会生成一个实例 ,单例模式保证了在程序的不同位置都可以且仅可以取到同一个对象实例,并提供一个访问它的全局访问点。
单列模式好处:
由于类只有一个实例,因此可以避免在多个地方创建多个实例,从而减少内存使用。
可以提供一个全局访问点,使得整个应用程序可以方便地访问该实例。
单例模式的实现方式:
饿汉式:在类加载时就创建了唯一的实例,因此线程安全,但可能会导致内存浪费。
懒汉式:只有在第一次调用时才会创建实例,避免了内存浪费,但需要考虑线程安全问题。
双重检查锁定(Double-Checked Locking):结合了饿汉式和懒汉式的优点,线程安全且避免了内存浪费。
枚举:在枚举类中只有一个枚举值,也就是唯一的实例。
单例模式的不足:
单例类如果使用继承,子类实例化可能会出现问题
单例类不是特别好扩展,因为一般没有抽象层
适用场景:
单例模式只允许创建一个对象,因此节省内存,加快对象访问速度,因此对象需要被公用的场合适合使用,如多个模块使用同一个数据源连接对象等等。如:
需要频繁实例化然后销毁的对象。
创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
有状态的工具类对象。
频繁访问数据库或文件的对象。
资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。
控制资源的情况下,方便资源之间的互相通信。如线程池等。
应用场景举例:
外部资源:每台计算机有若干个打印机,但只能有一个PrinterSpooler,以避免两个打印作业同时输出到打印机。内部资源:大多数软件都有一个(或多个)属性文件存放系统配置,这样的系统应该有一个对象管理这些属性文件
Windows的Task Manager(任务管理器)就是很典型的单例模式(这个很熟悉吧),不能打开两个windows task manager
windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。
网站的计数器,一般也是采用单例模式实现,否则难以同步。
应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。
数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,因为何用单例模式来维护,就可以大大降低这种损耗。
多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。
操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统。
HttpApplication 也是单位例的典型应用。熟悉ASP.Net(IIS)的整个请求生命周期的人应该知道HttpApplication也是单例模式,所有的HttpModule都共享一个HttpApplication实例.
2、什么是云原生?它有哪些优缺点?
云原生是一种开发和运行应用程序的方法,旨在利用云计算的弹性、可扩展性、可靠性和高可用性等优势。它通过将应用程序打包到容器中,使用容器编排工具进行管理,实现了应用程序在不同环境中的快速部署、弹性伸缩和高可用性。
云原生的优点包括:
灵活性和可扩展性:容器可以快速部署和扩展,以满足不同的负载要求。
高可用性:容器编排工具可以自动检测和恢复容器故障,提供高可用性。
效率和成本优化:使用容器可以节省资源和成本,提高应用程序的运行效率。
安全性:容器隔离应用程序的运行环境,减少了安全漏洞的风险。
云原生的缺点包括:
学习曲线较陡峭:云原生技术较为复杂,需要学习一些新的技术和工具。
可能存在依赖问题:应用程序可能依赖于某些特定的云原生技术或工具,这可能导致一些限制或局限性。
管理和维护难度:容器编排工具可能需要额外的管理和维护,需要更多的操作和维护成本。
云原生的应用场景包括:
微服务架构:云原生技术非常适合构建微服务架构,将应用程序拆分为小型、自治的服务。
弹性伸缩:云原生技术可以根据应用程序的负载自动扩展或缩小容器的数量,以适应不同的负载要求。
快速部署:使用云原生技术,可以快速地部署和更新应用程序,提高开发和部署效率。
多云部署:云原生技术可以在多个云环境中运行,方便应用程序在不同云环境中的部署和迁移。
数据处理和分析:云原生技术可以处理大规模的数据处理和分析任务,提高数据处理效率。
3、什么是 MySQL 执行计划?如何获取执行计划并对其进行分析?
MySQL 执行计划是指 MySQL 查询优化器生成的一份详细的查询执行计划,它展示了 MySQL 在执行查询时所采取的具体执行计划,包括表的访问顺序、数据读取方式、使用的索引、使用的排序方式等等。通过分析执行计划,可以帮助我们找出查询性能瓶颈所在,进而进行优化,提高查询效率。
要获取执行计划,可以在执行 SQL 语句时在前面添加 explain 关键字,例如:
要获取执行计划,可以在执行 SQL 语句时在前面添加 explain 关键字,例如:
explain select * from table where id = 1;
这样,MySQL 会输出该查询语句的执行计划。 执行计划中的各个字段含义如下:
id:每个 Select 子句或者是一个操作符或者是一个查询语句。
select_type:查询类型,表示查询的类型(简单查询、联合查询、子查询等等)。
table:查询涉及的表。
partitions:匹配的分区。
type:访问类型,表示 MySQL 在表中找到所需行的方式。
possible_keys:表示查询可能使用到的索引。
key:实际使用到的索引。
key_len:使用的索引长度。
ref:列与索引的比较。
rows:根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数。
filtered:返回结果的行数占总行数的比例。
Extra:包含 MySQL 解决查询的详细信息。
分析执行计划时,需要注意以下几个方面:
扫描行数:rows 字段,表示查询所需扫描的行数,如果该值过大,说明查询效率不高,需要优化。
使用索引:key 字段,表示查询所使用的索引,如果没有使用索引或者使用的不是最优索引,需要考虑优化。
排序:Extra 字段,如果查询需要使用 filesort 排序,说明查询效率不高,需要优化。
嵌套循环:如果查询类型是 nested loop,说明查询中包含嵌套循环,也需要考虑优化。
通过分析执行计划,可以确定查询优化的方向和方法,提高查询效率。
3、Vue Router 的 $route 和 $router 对象有什么区别?
$route 对象代表当前激活的路由信息,包含了当前 URL 解析得到的路由参数、查询参数和 hash 值等信息。可以通过 $route 对象获取当前路由的各种信息,如 $route.params 获取路由参数,$route.query 获取查询参数等。$route 对象是只读的,即不允许直接修改 $route 对象。
$router 对象则是 Vue Router 全局路由的实例本身,是router构造方法的实例,它提供了一些方法用于编程式地操作路由,如 $router.push、$router.replace、$router.go 等。通过 $router 对象可以实现在代码中进行路由的跳转、修改 URL 等操作。
因此,$route 和 $router 的主要区别在于:
$route 是只读的,用于获取当前路由信息;而 $router 是可读写的,用于编程式地操作路由。
$route 是路由组件的属性,可以通过 this.$route 访问;而 $router 是全局的 Vue Router 实例,可以通过 this.$router 访问。