当前位置: 首页 > news >正文

做网站内容岳阳市网页设计人才网

做网站内容,岳阳市网页设计人才网,常熟网站优化,淮安做网站.哪家网络公司好?1.JDK 和 JRE 有什么区别#xff1f; JDK#xff1a;Java Development Kit 的简称#xff0c;java 开发工具包#xff0c;提供了 java 的开发环境和运行环境 JRE#xff1a;Java Runtime Environment 的简称#xff0c;java 运行环境#xff0c;为 java 的运行提供了所需…1.JDK 和 JRE 有什么区别 JDKJava Development Kit 的简称java 开发工具包提供了 java 的开发环境和运行环境 JREJava Runtime Environment 的简称java 运行环境为 java 的运行提供了所需环境 具体来说 JDK 其实包含了 JRE同时还包含了编译 java 源码的编译器 javac还包含了很多 java 程序调试和分析的工具。简单来说如果你需要运行 java 程序只需安装 JRE 就可以了如果你需要编写 java 程序需要安装 JDK。 2.如何理解类 类是对现实生活中一类具有共同属性和行为的事物的抽象 类的特点 •类是对象的数据类型 •类是具有相同属性和行为的一组对家的集合 3.类和对象的关系 4.如何理解封装 封装概述 是面向对象三大特征之一封装继承多态 是面向对象编程语言对客观世界的模拟客观世界里成员变量都是隐藏在对象内部的外界是无法直接操作的封装原则 将类的某些信息隐藏在类内部不允许外部程序直接访问而是通过该类提供的方法来实现对隐藏信息的操作和访问 成员变量private提供对应的getXxx()/setxxx()方法 3.封装好处 通过方法来控制成员变量的操作提高了代码的安全性 把代码用方法进行封装提高了代码的复用性 5.泛型是什么 6.ClassLoad是什么解释一下原理和过程 类加载器是加载class文件到内存中供其他class文件调用。 加载过程是加载-链接验证、准备、解析-初始化-使用-卸载 ClassLoad类加载器是Java虚拟机JVM的一部分它负责将Java字节码编译后的Java源代码加载到内存中并转换成可执行的Java类。类加载器是Java的一个重要概念它允许应用程序在运行时动态加载类这是Java语言的一个重要特性之一也是实现Java的动态扩展和模块化的基础。 类加载器的原理和过程 加载Loading在这个阶段类加载器会查找并读取.class文件Java字节码文件。这些文件可以来自本地文件系统、网络、JAR文件等资源。类加载器会将字节码数据加载到内存中并创建一个代表这个类的java.lang.Class对象。链接Linking类加载过程的链接阶段包括三个步骤 验证Verification在这一步类加载器会验证加载的字节码是否符合Java虚拟机规范以确保它是合法的、安全的。这包括类型检查、字节码验证、符号引用验证等。准备Preparation在这一步类加载器会为类的静态变量分配内存空间并初始化这些变量的默认初始值通常为零值。这些静态变量被存储在类的静态存储区域中。解析Resolution在这一步类加载器会将符号引用替换为直接引用以确保类、方法和字段的引用都能正确地连接到已加载的类或接口。这是一个可选步骤不是所有类都需要解析。 初始化Initialization在这个阶段类加载器会执行类的初始化代码包括执行静态初始化块static块和静态字段初始化。这是类加载过程的最后一步只有在初始化完成后类才会真正准备好使用。 Java虚拟机提供了默认的类加载器但也可以通过编写自定义类加载器来实现更复杂的加载策略。自定义类加载器通常用于实现类隔离、动态加载模块、热部署等功能。 总之类加载器是Java中实现动态加载和运行时扩展的关键部分它确保了Java的灵活性和可扩展性允许应用程序在运行时根据需要加载新的类和资源。 7.常用的网络协议 HTTP协议超文本传输协议是万维网数据通信基础。 TCP协议传输控制协议传送数据需要经过三次握手是一种可靠的传输适用于如文件传输网络数据库分布式高精度计算系统的数据传输 三次握手 客户端发起连接请求 服务器确认连接请求 客户端确认连接请求 8.JVM是什么及原理 JVM (Java Virtual Machine) 是 Java 编程语言的关键组成部分之一它是一个虚拟机用于执行 Java 程序。JVM 的主要任务是将 Java 源代码编译成字节码Bytecode然后在运行时执行这些字节码。以下是 JVM 的一些重要特点和功能 字节码执行JVM 通过解释或即时编译Just-In-Time CompilationJIT方式执行 Java 字节码。即时编译将字节码转换成本地机器代码以提高执行速度。 平台无关性Java 程序编写一次可以在支持 JVM 的任何平台上运行只要有相应的 JVM 实现。这个特性使得 Java 成为跨平台的编程语言。 内存管理JVM 负责内存管理包括分配和回收内存。它具有垃圾回收机制可自动释放不再使用的内存以减少内存泄漏的风险。 安全性JVM 提供了一系列安全性功能如字节码验证以确保代码的合法性和防止恶意代码执行。 多线程支持JVM 具有内置的多线程支持可以轻松创建和管理多线程应用程序。 性能优化现代的 JVM 实现包括各种性能优化技术以提高 Java 程序的执行速度。 异常处理JVM 提供了强大的异常处理机制使开发人员能够有效地处理错误和异常情况。 类加载器JVM 使用类加载器Class Loader来加载类和资源文件它们可以动态地从不同的来源加载类如本地文件系统、网络等。 总的来说JVM 允许开发人员编写一次 Java 代码并在不同的平台上运行同时提供了许多强大的功能包括内存管理、多线程支持和安全性以简化和增强 Java 应用程序的开发和执行。不同的 Java 实现例如Oracle HotSpot、OpenJ9、GraalVM等提供了不同的性能特性和优化以满足不同应用程序的需求。 JVM的生命周期 1.启动。启动一个java程序的时候就产生了一个jvm实例 2.运行。Main方法是程序的入口任何其他线程均有它启动 3.消亡。当程序中所有非守护线程都终止时JVM才退出。若安全管理器允许程序也可以使用Runtime类或者System.exit()来退出程序。 JVM的组成 JVM是由类加载器字节码执行引擎运行时数据区堆栈本地方法栈方法区程序计数器组成的 JVM的优点 一次编写跨平台运行 提供自动内存管理机制 9.Git提交代码命令 用指令 git commit -m [massage] 将暂存区所有文件添加到本地仓库 git branch [branch-name] 创建分支 git fetch 拉取远程分支最新的commit到本地仓库的origin/[branch-name] git pull 从远程仓库拉取代码到工作空间 git branch 查看当前分支 git checkout [branch] 切换分支 git remote 查看远程分支 git revert 版本号 回退到这个版本号 git init 初始化本地库在当前目录创建了一个空的存储库 10.Linux常用命令和基本操作 切换目录 cd 查看目录 ls -l 列出文件详细信息 或者直接ll -a 列出当前目录下所有文件及目录包括隐藏的a(all) 创建目录 mkdir 查看目录大小 du -h /home (带有单位显示目录信息) 查看磁盘大小 df -h (带有单位显示磁盘信息) 查看网络情况 ifconfig 测试网络连通 ping 显示网络状态信息 netstat 创建空文件 touch 复制文件 cp 移动或重命名 mv 删除文件 rm -r 递归删除可删除子目录及文件 -f 强制删除 11.Mysql的默认引擎 在MysqL 5.5之前当您创建表而未明确指定存储引擎时MyISAM是默认存储引擎。从版本5.5开始MysqL使用InnoDB作为默认存储引擎。 数据库的存储引擎决定了表在计算机的存储方式不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能 12.讲讲平时怎么用索引以及联合索引 联合索引又叫复合索引是指两个及两个以上的字段创建索引符合最左原则 13.mybatis-plus比Mybatis相比优点是什么 MyBatis: 所有SQL语句全部自己写 手动解析实体关系映射转换为MyBatis内部对象注入容器 不支持Lambda形式调用 Mybatis Plus: 强大的条件构造器,满足各类使用需求 内置的Mapper,通用的Service,少量配置即可实现单表大部分CRUD操作 支持Lambda形式调用 提供了基本的CRUD功能,连SQL语句都不需要编写 自动解析实体关系映射转换为MyBatis内部对象注入容器 14.Mybatis分页 借助数组进行分页 借助Sql语句进行分页 拦截器分页MybatisPlusInterceptor RowBounds实现分页 15.什么是io 从磁盘读到内存从内存写到磁盘 按功能来分输入流input、输出流output。 按类型来分字节流和字符流。 字节流和字符流的区别是字节流按 8 位传输以字节为单位输入输出数据字符流按 16 位传输以字符为单位输入输出数据。 16.讲一下公平锁和非公平锁 公平锁―是指多个线程按照申请锁的顺序来获取锁类似排队打饭先来后到。 非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序有可能后申请的线程比先申请的线程优先获取锁 17.大量数据并发时怎么解决 18.创建docker镜像命令 Docker pull 19.进入docker命令 docker exec -it 容器名称或容器ID /bin/bash 20.IOC和di的区别 ioc是控制反转是一种思想 di是依赖注入往对象里注入值 21.链表的拓展 22.Java怎么使用PLC通讯 23.Socket通讯技术 24.TCP通讯技术 TCP的三次握手和四次挥手实质就是TCP通信的连接和断开。 三次握手为了对每次发送的数据量进行跟踪与协商确保数据段的发送和接收同步根据所接收到的数据量而确认数据发送、接收完毕后何时撤消联系并建立虚连接。 四次挥手即终止TCP连接就是指断开一个TCP连接时需要客户端和服务端总共发送4个包以确认连接的断开。 原文链接https://blog.csdn.net/m0_38106923/article/details/108292454 25.Mqtt通讯技术 26.List list new ArrayList()和ArrayList list new ArrayList() 第一个是面向接口第二个是面向对象 27.简历一个springboot项目mybatis构建 28.说说面向对象 29.数据库的外键是 30.将list里面的数组里数据过滤只留下偶数 31.集合分类 iMapCollection两大类 Map分为hashMap和TreeMap Collection分为Set和List 32.同步io和异步io 同步IO是指读写IO时代码必须等待数据返回后才继续执行后续代码它的优点是代码编写简单缺点是CPU执行效率低。 而异步IO是指读写IO时仅发出请求然后立刻执行后续代码它的优点是CPU执行效率高缺点是代码编写复杂。 System.out.println(2 32)是多少 是2 HashMap和HashSet的区别 HashMap和HashSet是Java集合框架中的两种不同的数据结构它们有一些重要的区别 数据结构 HashMap是一种键值对key-value映射表用于存储一组键值对每个键都唯一可以用于快速查找和访问值。HashSet是一种集合用于存储一组唯一的元素不允许重复值。 元素类型 HashMap包含键值对其中键和值可以是任意类型的对象。HashSet包含唯一的元素通常是对象但也可以包含基本数据类型的值因为它们会被自动装箱。 存储方式 HashMap使用哈希表来存储键值对通过键的哈希码来定位值的存储位置允许通过键来查找值。HashSet也使用哈希表来存储唯一元素通过元素的哈希码来确定存储位置允许通过元素来查找。 操作 HashMap提供了put(key, value)来插入键值对get(key)来根据键获取值以及其他与键相关的操作。HashSet提供了add(element)来添加元素contains(element)来检查是否包含特定元素以及其他与元素相关的操作。 重复值 HashMap允许不同键对应相同的值但不允许重复的键。HashSet不允许重复的元素如果试图添加重复的元素它将被忽略。 迭代顺序 HashMap不保证键值对的顺序可以通过LinkedHashMap来保持插入顺序。HashSet不保证元素的顺序可以通过LinkedHashSet来保持插入顺序。 线程安全性 HashMap 和 HashSet 都不是线程安全的。如果在多线程环境中使用它们需要采取额外的同步措施或使用线程安全的集合类。 总之HashMap用于存储键值对而HashSet用于存储唯一元素。它们有不同的用途和适用场景因此在选择使用哪个取决于您的需求。如果需要键值对映射HashMap更合适如果需要存储唯一元素的集合HashSet更适合。 synchronized锁住的静态方法和普通方法有什么区别 spring的请求流程 Spring框架是一个广泛用于构建Java企业级应用程序的框架其中Spring MVCModel-View-Controller是Spring框架的一部分用于构建Web应用程序。以下是Spring MVC的请求处理流程 客户端发起请求 客户端通常是浏览器向Web服务器发送HTTP请求请求特定的URL例如http://example.com/myapp/somePage。 前端控制器DispatcherServlet接收请求 在Spring MVC中一个名为DispatcherServlet的前端控制器充当所有请求的入口点。DispatcherServlet会拦截到所有请求然后根据配置将它们路由到适当的处理程序Controller。 处理程序映射 DispatcherServlet 使用处理程序映射器Handler Mapping来确定请求应该由哪个处理程序Controller来处理。处理程序映射器将请求URL映射到一个具体的处理程序。 处理程序执行 一旦确定了请求的处理程序DispatcherServlet调用相应的处理程序方法来执行业务逻辑。处理程序方法通常会访问模型Model来存储和获取数据并返回视图View名称。 业务逻辑执行 处理程序方法执行业务逻辑可能包括从数据库获取数据、处理请求参数、调用服务层等操作。 模型更新 处理程序方法可以将数据添加到模型中以便在视图中显示。模型是一个数据容器通常包含在视图中渲染的数据。 视图解析 DispatcherServlet 使用视图解析器View Resolver来解析处理程序返回的视图名称以确定要使用哪个视图模板来呈现响应。 视图呈现 视图模板负责将模型中的数据渲染到HTML页面或其他响应格式中生成最终的响应内容。 响应发送 DispatcherServlet 将视图生成的响应发送回客户端通常是浏览器。这是通过HTTP响应完成的。 请求生命周期结束 整个请求-响应周期结束后请求生命周期也随之结束。 Spring MVC提供了丰富的配置选项允许您自定义处理程序、拦截器、视图解析器等以适应不同的应用程序需求。这个流程提供了一个清晰的结构使得构建和维护Web应用程序变得更加容易。 以下结果 和 不同 byte c 2;c 1;//合法 相当于c (byte)(c 1);byte a 1;a a 1;//不合法 这里结果是int类型 int g a 1;//合法索引有哪几种 在MySQL中有几种常见的索引类型每种类型都有其特定的用途和性能特点。以下是MySQL中常见的索引类型 B-tree 索引B-tree平衡树索引是MySQL中最常用的索引类型。它适用于各种查询包括等值查询、范围查询和排序。B-tree索引可以用于所有存储引擎包括InnoDB和MyISAM。 哈希索引哈希索引适用于等值查询但不适用于范围查询或排序。它们通常在内存表上使用例如MEMORY存储引擎。InnoDB存储引擎也支持自动创建哈希索引以加速特定类型的查询。 全文索引全文索引用于在文本数据上执行全文搜索。它们主要用于MyISAM存储引擎并且支持全文搜索功能以查找匹配的文本。 空间索引空间索引用于处理空间数据类型例如地理信息系统GIS数据。MySQL支持用于空间索引的特定类型如R-tree。 前缀索引前缀索引允许您只索引列值的一部分。这可以用于减小索引的大小但也会降低查询性能。前缀索引通常用于处理大文本列。 复合索引复合索引是包含多个列的索引。它们用于优化需要多个列的查询例如多列的等值查询或范围查询。复合索引的列顺序非常重要因为它们影响查询性能。 唯一索引唯一索引确保索引列的值是唯一的不允许重复值。这种索引用于实现唯一性约束以确保表中的数据不包含重复记录。 主键索引主键索引是一种特殊的唯一索引它唯一标识表中的每一行并且每个表只能有一个主键索引。主键索引通常与主键列关联用于快速查找和引用表中的特定行。 外键索引外键索引是用于实现外键关系的索引。它们用于维护表之间的引用完整性确保在关联表中的数据一致性。 全列索引全列索引是包含表中所有列的索引。通常它们用于覆盖索引以避免回表操作从而提高性能。 每种索引类型都有其适用场景和性能考虑因素根据您的查询需求和数据模型来选择适当的索引类型非常重要。不正确的索引策略可能会导致性能问题。 B-tree索引怎么使用 B-tree平衡树索引是MySQL中最常用的索引类型之一用于加速各种查询操作包括等值查询、范围查询和排序。下面是如何使用B-tree索引的一些示例 创建B-tree索引 您可以在表的列上创建B-tree索引以加速对该列的查询。例如假设您有一个名为users的表并且要在username列上创建索引 CREATE INDEX idx_username ON users(username);这将在username列上创建一个B-tree索引以加速与username相关的查询。 等值查询 B-tree索引特别适用于等值查询例如 SELECT * FROM users WHERE username john_doe;在这种情况下MySQL可以使用B-tree索引快速查找username等于’john_doe’的行。 范围查询 B-tree索引还可以用于范围查询例如 SELECT * FROM orders WHERE order_date BETWEEN 2023-01-01 AND 2023-12-31;在这种情况下MySQL可以使用B-tree索引快速查找order_date在指定范围内的订单。 排序 B-tree索引也有助于加速排序操作因为它们存储了索引列的数据的有序副本。例如如果您需要按user_id列对用户表进行升序排序 SELECT * FROM users ORDER BY user_id ASC;B-tree索引可以加速这个排序操作。 覆盖索引 如果您的查询只需要从索引中获取数据而不需要回到表中检索其他列的值那么可以使用覆盖索引来提高性能。例如 SELECT username FROM users WHERE user_id 123;如果在user_id列上有一个B-tree索引并且只需获取username列的值MySQL可以完全使用索引而不需要回到表中查找。 请注意创建索引会增加插入、更新和删除操作的开销因此需要根据查询需求和数据库的使用模式仔细考虑索引的创建。同时还要定期维护索引以确保其性能。使用EXPLAIN语句可以帮助您分析查询的执行计划以确定是否有效地使用了B-tree索引。 如何知道正确使用了索引 注意事项 使用索引时有以下一些技巧和注意事项 1.索引不会包含有null值的列 只要列中包含有null值都将不会被包含在索引中复合索引中只要有一列含有null值那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为null。 2.使用短索引 对串列进行索引如果可能应该指定一个前缀长度。例如如果有一个char(255)的列如果在前10个或20个字符内多数值是惟一的那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。 3.索引列排序 查询只使用一个索引因此如果where子句中已经使用了索引的话那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作尽量不要包含多个列的排序如果需要最好给这些列创建复合索引。 4.like语句操作 一般情况下不推荐使用like操作如果非使用不可如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。 5.不要在列上进行运算 这将导致索引失效而进行全表扫描例如 SELECT * FROM table_name WHERE YEAR(column_name)2017; 6.不使用not in和操作 35.索引的缺点 1.虽然索引大大提高了查询速度同时却会降低更新表的速度如对表进行insert、update和delete。因为更新表时不仅要保存数据还要保存一下索引文件。 2.建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重但如果你在一个大表上创建了多种组合索引索引文件的会增长很快。 索引只是提高效率的一个因素如果有大数据量的表就需要花时间研究建立最优秀的索引或优化查询语句。 接口里面可以定义常量吗 可以的 public interface Book {String abc open;Shop getShopName(Shop shop); }public class TestMain {public static void main(String[] args) {System.out.println(Book.abc);} }结果是open 请注意尽管在接口中定义字段是合法的但这种做法通常不被推荐因为接口的主要目的是定义方法签名而不是存储数据。通常情况下应该使用常量类或枚举来定义常量而不是将常量放在接口中。 接口可以实现抽象方法吗 不能 在Java中接口interface和抽象类abstract class是两种不同的概念它们有不同的用途和特性。 接口Interface接口是一种抽象类型它可以包含抽象方法的声明但不能包含方法的实现。接口通常用于定义一组方法签名而不提供具体的实现。类可以实现implements一个或多个接口实现接口的类必须提供接口中声明的所有方法的实现。 抽象类Abstract Class抽象类也是一种抽象类型但它可以包含抽象方法的声明以及方法的实现。抽象类用于定义具有一些通用实现的类但允许派生类覆盖override其中的方法也可以包含非抽象的方法。 接口不能直接实现抽象类因为它们是不同的概念。一个类可以同时实现一个接口并扩展一个抽象类这是允许的。例如 // 接口 interface MyInterface {void methodA(); }// 抽象类 abstract class MyAbstractClass {abstract void methodB(); }// 实现接口并扩展抽象类的类 class MyClass extends MyAbstractClass implements MyInterface {Overridevoid methodB() {// 实现抽象方法}Overridepublic void methodA() {// 实现接口方法} }在上述示例中MyClass类同时实现了MyInterface接口和扩展了MyAbstractClass抽象类。它必须提供抽象类中的抽象方法和接口中的方法的实现。 总之接口和抽象类都有其用途它们可以在Java中用于不同的情景和需求。您可以根据具体的设计需求来选择使用哪个或同时使用两者。 Java中int型的数据能表示汉字吗 不能表示 汉字可以用char类型或者String类型表示 Java中int型数据能表示字母吗 可以表示 char letter A; // 字母字符 A int intValue (int) letter; // 将字母字符 A 转换为 int 值System.out.println(intValue); // 输出 65 Java中的基本数据类型各占几个字节 在Java中基本数据类型的大小是规定的但具体的大小可能因不同的JVM实现和平台而有所不同。通常情况下Java中的基本数据类型的大小如下 byte占用1个字节8位。short占用2个字节16位。int占用4个字节32位。long占用8个字节64位。float占用4个字节32位但请注意浮点数的精度和表示不同于整数。double占用8个字节64位双精度浮点数的精度更高。char占用2个字节16位用于表示Unicode字符。boolean通常不明确规定大小但其存储大小通常是虚拟机和平台相关的。 需要注意的是这些基本数据类型的大小是Java语言规范中定义的标准大小。然而不同的Java虚拟机JVM实现和不同的平台可能会有微小的差异但这些差异通常很小不会对大多数Java程序产生显著影响。 此外Java的基本数据类型在内存中的布局也可以受到虚拟机的实现和平台的影响例如字节对齐等。因此如果需要严格控制内存布局可以考虑使用Java的ByteBuffer等机制。 springmvc的流程是什么 Spring MVC 是 Spring 框架的一个模块用于开发基于模型-视图-控制器MVC设计模式的 Web 应用程序。Spring MVC 的典型工作流程如下 客户端请求当用户通过浏览器或其他客户端发送 HTTP 请求时请求被传递到 Spring MVC 应用程序的前端控制器通常是 DispatcherServlet。 前端控制器处理请求DispatcherServlet 是 Spring MVC 应用程序的中心控制器它接收所有的 HTTP 请求并将它们路由到适当的处理程序Controller。 处理程序映射DispatcherServlet 使用处理程序映射器Handler Mapping来确定请求应该由哪个处理程序来处理。处理程序映射器将请求 URL 映射到一个具体的控制器类和方法。 调用控制器方法一旦确定了请求的处理程序DispatcherServlet 调用相关的控制器方法来执行业务逻辑。控制器方法可以访问模型、调用服务层、处理请求参数等。 处理方法返回控制器方法执行完后它可以返回一个模型和视图名称。模型是要传递给视图的数据视图名称告诉 Spring MVC 哪个视图应该用于呈现响应。 视图解析和呈现DispatcherServlet 使用视图解析器View Resolver来解析视图名称找到实际的视图对象。视图对象负责呈现模型数据通常生成 HTML 页面或其他响应格式。 返回响应视图呈现模型数据后DispatcherServlet 将响应发送回客户端通常是浏览器。这是通过 HTTP 响应完成的可以包括 HTML 页面、JSON 数据等。 渲染视图客户端浏览器接收到响应后会渲染视图并显示在用户界面上。 请求生命周期结束整个请求-响应周期完成后请求生命周期结束。 这是 Spring MVC 的基本工作流程。Spring MVC 提供了丰富的配置选项允许您自定义处理程序、拦截器、视图解析器等以适应不同的应用程序需求。它还提供了强大的支持包括数据绑定、表单处理、国际化、文件上传等功能使得开发 Web 应用程序更加方便和灵活。 36.将本地文件上传到git空仓库 初始化项目 git init 将当前目录下所有需要上传的文件代码等资源添加到缓存区 添加一个或多个文件到暂存区 git add [file1] [file2] 添加指定目录到暂存区包括子目录 git add [dir] 添加当前目录下的所有文件到暂存区 git add . 提交缓存区里面的主要内容到本地仓库 git commit -m “提交说明” 添加一个远程仓库的地址 git remote add origin https://gitee.com/xxxxxxx(远程仓库的地址 将远程仓库进行下拉获取同步 git pull --rebase origin master 提交本地仓库到远程仓库 git push -u origin master 因为第一次提交 所以要加一个 -u 37.Mysql数据库的锁 表锁页锁行锁 表级锁开销小加锁快不会出现死锁锁定粒度大发生锁冲突的概率最高并发度最低使用表级锁定的有MyISAMMEMORYCSV等一些非事务性存储引擎 行级锁开销大加锁慢会出现死锁锁定粒度最小发生锁冲突的概率最低并发度也最高使用行级锁定的主要是InnoDB存储引擎 页面锁开销和加锁时间界于表锁和行锁之间会出现死锁锁定粒度界于表锁和行锁之间并发度一般使用页级锁定的主要是BerkeleyDB存储引擎。 对于UPDATE、DELETE和INSERT语句InnoDB会自动给涉及数据集加排他锁X)对于普通SELECT语句InnoDB不会加任何锁事务可以通过以下语句显示给记录集加共享锁或排他锁。 共享锁SSELECT * FROM table_name WHERE … LOCK IN SHARE MODE 排他锁X)SELECT * FROM table_name WHERE … FOR UPDATE 说两个维度 共享锁(简称S锁)和排他锁(简称X锁) 读锁是共享的可以通过lock in share mode实现这时候只能读不能写。写锁是排他的它会阻塞其他的写锁和读锁。从颗粒度来区分可以分为表锁和行锁两种。 表锁和行锁 表锁会锁定整张表并且阻塞其他用户对该表的所有读写操作比如alter修改表结构的时候会锁表。 行锁又可以分为乐观锁和悲观锁 悲观锁可以通过for update实现 乐观锁则通过版本号实现。 著作权归pdai所有 原文链接https://pdai.tech/md/interview/x-interview.html 38.Mysql缓存 39.线程池什么是线程池为什么要使用线程池 线程池是一种用于管理和复用线程的机制它可以预先创建一组线程然后将任务分配给这些线程执行。通过使用线程池可以避免频繁地创建和销毁线程从而降低线程开销提高系统性能和资源利用率。 40.Java 中如何创建线程池请介绍一下 Executor 和 ExecutorService 接口。 在Java中你可以使用Executor框架来创建线程池以管理和执行多个任务。线程池可以帮助你更有效地使用系统资源并提高多线程应用程序的性能。以下是创建线程池的一些常见方式 使用Executors工厂方法创建线程池 java.util.concurrent.Executors类提供了一些工厂方法用于创建不同类型的线程池。以下是一些示例 创建一个固定大小的线程池 ExecutorService executor Executors.newFixedThreadPool(5); // 创建一个包含5个线程的固定大小线程池创建一个单线程的线程池 ExecutorService executor Executors.newSingleThreadExecutor(); // 创建一个单线程的线程池创建一个缓存线程池 ExecutorService executor Executors.newCachedThreadPool(); // 创建一个根据需求自动调整线程数的线程池手动创建线程池 你也可以手动创建一个ThreadPoolExecutor以更精细地控制线程池的属性如核心线程数、最大线程数、线程空闲时间等。以下是一个示例 int corePoolSize 5; int maxPoolSize 10; long keepAliveTime 5000; // 5秒 TimeUnit unit TimeUnit.MILLISECONDS; BlockingQueueRunnable workQueue new LinkedBlockingQueue();ExecutorService executor new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue);执行任务 无论你选择哪种方式创建线程池一旦创建完成你可以使用execute()方法提交任务供线程池执行或者使用submit()方法提交任务并获取Future对象以便跟踪任务的执行进度和结果。 executor.execute(() - {// 在这里执行你的任务逻辑 });关闭线程池 最后不要忘记在程序结束时关闭线程池以释放资源。 executor.shutdown(); // 关闭线程池以上是创建和使用线程池的基本步骤。你可以根据自己的需求和项目的复杂性来选择不同类型的线程池并配置线程池的属性以优化性能。确保在使用完线程池后关闭它以避免资源泄漏。 41.常见的线程池实现有哪些比较它们的区别。 42.线程池中的核心线程数、最大线程数、队列等参数的作用是什么 核心线程数线程池中保持的活动线程数量即使它们是空闲的。 最大线程数线程池能容纳的最大线程数量包括核心线程和非核心线程。 队列存储待执行任务的队列可以是无界队列如LinkedBlockingQueue或有界队列如ArrayBlockingQueue。 43.线程池的工作原理是怎样的线程池是如何管理线程的生命周期的 44.线程池中的任务队列有哪些类型它们的特点和适用场景是什么 45.什么是线程池的拒绝策略请列举一些内置的拒绝策略。 46.在什么情况下会使用自定义的线程池和拒绝策略可以举例说明吗 47.如何优雅地关闭线程池 48.在使用线程池时有哪些需要注意的问题如避免死锁、线程安全等 49.你有没有遇到过线程池使用不当导致的问题如何解决的 50.线程池与并发集合有何区别什么时候选择使用线程池而不是并发集合 51.如何评估线程池的性能和效率有哪些衡量指标 52.在使用线程池的过程中有哪些常见的线程安全问题如何避免 53.什么是线程池的线程复用和线程复用的优势 54.线程池的线程数量怎样选择过多或过少的线程数量会有什么问题 55.在 Java 中线程池是否会自动回收闲置的线程如果不会怎么解决 56.Springboot创建定时任务几种写法 在Spring Boot中创建定时任务有多种写法其中最常用的是使用Scheduled注解和实现SchedulingConfigurer接口。以下是几种创建定时任务的写法 使用Scheduled注解 使用Scheduled注解是最简单的方式之一它可以直接标注在需要定时执行的方法上。您可以在方法上设置定时任务的触发时间、周期、延迟等属性。 import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component;Component public class MyScheduledTasks {Scheduled(fixedRate 5000) // 每5秒执行一次public void myTask() {// 定时任务的逻辑} }使用Cron表达式 使用Cron表达式可以更灵活地定义定时任务的执行时间例如每天凌晨执行、每周某一天的某个时间执行等。 import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component;Component public class MyScheduledTasks {Scheduled(cron 0 0 0 * * ?) // 每天凌晨执行public void myTask() {// 定时任务的逻辑} }实现SchedulingConfigurer接口 通过实现SchedulingConfigurer接口您可以更灵活地配置定时任务。这种方式适用于需要动态配置定时任务的情况。 import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar;Configuration EnableScheduling public class MySchedulingConfig implements SchedulingConfigurer {Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {taskRegistrar.addCronTask(() - {// 定时任务的逻辑}, 0 0 0 * * ?); // 每天凌晨执行} }4.使用Quartz Scheduler 5.单利线程池 如果需要更高级的调度功能可以集成Quartz Scheduler。Quartz提供了更复杂的调度和任务管理功能适用于大型和复杂的定时任务需求。 以上是几种在Spring Boot中创建定时任务的常见写法。您可以根据项目的需求和复杂度选择适合的方式。 57.Mysql的数据库事务四大特性 Atomicity原子性一个事务transaction中的所有操作要么全部完成要么全部不完成不会结束在中间某个环节。事务在执行过程中发生错误会被恢复Rollback到事务开始前的状态就像这个事务从来没有执行过一样。 Consistency一致性在事务开始之前和事务结束以后数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。 Isolation隔离性数据库允许多个并发事务同时对其数据进行读写和修改的能力隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别包括读未提交Read uncommitted、读提交read committed、可重复读repeatable read和串行化Serializable。 Durability持久性事务处理结束后对数据的修改就是永久的即便系统故障也不会丢失 58.Autowired与Resource注解的区别 Autowired注解由Spring提供只按照byType注入resource注解由J2EE提供默认按照byName自动注入。 Autowired功能虽说非常强大但是也有些不足之处。比如比如它跟spring强耦合了如果换成了JFinal等其他框架功能就会失效。而Resource是JSR-250提供的它是Java标准绝大部分框架都支持。 除此之外有些场景使用Autowired无法满足的要求改成Resource却能解决问题。接下来我们重点看看Autowired和Resource的区别。 Autowired默认按byType自动装配而Resource默认byName自动装配。 Autowired只包含一个参数required表示是否开启自动准入默认是true。而Resource包含七个参数其中最重要的两个参数是name 和 type。 Autowired如果要使用byName需要使用Qualifier一起配合。而Resource如果指定了name则用byName自动装配如果指定了type则用byType自动装配。 Autowired能够用在构造器、方法、参数、成员变量和注解上而Resource能用在类、成员变量和方法上。 59.什么是Redis为什么用Redis Redis是一种支持key-value等多种数据结构的存储系统。可用于缓存事件发布或订阅高速队列等场景。支持网络提供字符串哈希列表队列集合结构直接存取基于内存可持久化。 读写性能优异 Redis能读的速度是110000次/s,写的速度是81000次/s 测试条件见下一节。 数据类型丰富 Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。 原子性 Redis的所有操作都是原子性的同时Redis还支持对几个操作全并后的原子性执行。 丰富的特性 Redis支持 publish/subscribe, 通知, key 过期等特性。 持久化 Redis支持RDB, AOF等持久化方式 发布订阅 Redis支持发布/订阅模式 分布式 Redis Cluster 60.暂定Redis 一般有哪些使用场景 热点数据的缓存缓存是Redis最常见的应用场景之所有这么使用主要是因为Redis读写性能优异。而且逐渐有取代memcached成为首选服务端缓存的组件。而且Redis内部是支持事务的在使用时候能有效保证数据的一致性。 限时业务的运用redis中可以使用expire命令设置一个键的生存时间到时间后redis会删除它。利用这一特性可以运用在限时的优惠活动信息、手机验证码等业务场景。 计数器相关问题redis由于incrby命令可以实现原子性的递增所以可以运用于高并发的秒杀活动、分布式序列号的生成、具体业务还体现在比如限制一个手机号发多少条短信、一个接口一分钟限制多少请求、一个接口一天限制调用多少次等等。 分布式锁这个主要利用redis的setnx命令进行setnxset if not exists就是如果不存在则成功设置缓存同时返回1否则返回0 这个特性在俞你奔远方的后台中有所运用因为我们服务器是集群的定时任务可能在两台机器上都会运行所以在定时任务中首先 通过setnx设置一个lock如果成功设置则执行如果没有成功设置则表明该定时任务已执行。 当然结合具体业务我们可以给这个lock加一个过期时间比如说30分钟执行一次的定时任务那么这个过期时间设置为小于30分钟的一个时间就可以这个与定时任务的周期以及定时任务执行消耗时间相关。 61.Spring注入bean的值有几种方式 Set方法注入 构造器注入 静态工厂注入 实例工厂注入 62.Springboot的注入bean有几种方式 63.Value的用法 在使用上述配置文件时可以直接Value“${user.userName}”等等。 可以注入基本类型 64.实体字段有数据库没有的字段用哪些注解 TableField(exist false)表示该属性不为数据库表字段但又是必须使用的。 TableField(exist true)表示该属性为数据库表字段。 65.Springboot的主要注解是哪个有哪些注解组成 SpringBootApplication 这是 Spring Boot 最最最核心的注解用在 Spring Boot 主类上标识这是一个 Spring Boot 应用用来开启 Spring Boot 的各项能力。 三个注解的组合也可以用这三个注解来代替 SpringBootApplication 注解。 SpringBootConfigurationSpringBootConfiguration继承自Configuration二者功能也一致标注当前类是配置类。 EnableAutoConfiguration启用Spring的自动加载配置。 ComponentScan该注解定义了Spring将自动扫描包主类所在包及其子包下的bean 如果你项目中所有的类都定义在主类包及其子包下那你不需要做任何事如果有别的类不在需要注解后面配置当前包位置和主类包位置 66.Spring定义bean的注解和装配bean的注解 定义 Component Bean Controller Service Repository 装备 Autowire只按照类型 Resources默认按照名称找找不到按照类型找 67.Java规范 类名要大写 包名要小写 方法名驼峰式命名第一个单词用动词 一个方法不能超过50行 复杂功能要写注释 格式化对其 抽取公共方法 数据库连接的表不能超过五个 68.ComponentScan和MapperScan的区别 首先ComponentScan是组件扫描注解用来扫描Controller Service Repository这类,主要就是定义扫描的路径从中找出标志了需要装配的类到Spring容器中 其次MapperScan 是扫描mapper类的注解,配置包的路径就不用在每个mapper类上加Mapper 69.反射的理解 将一个类的组成部分封装成其他对象可以在程序运行的时候操控这些对象有三种方式 第一种Class.forName(“全类名”)将字节码加载进缓存返回class对象多用于配置文件 第二种类名.class通过类名的属性class获取多用于参数的传递 第三种对象.getClass():getClass方法在Object类中定义着多用于对象的获取字节码方式 70.多线程 71.TCP协议 72.并行和并发有什么区别 并行是指两个或者多个事件在同一时刻发生而并发是指两个或多个事件在同一时间间隔发生。 并行是在不同实体上的多个事件并发是在同一实体上的多个事件。 在一台处理器上“同时”处理多个任务在多台处理器上同时处理多个任务。如hadoop分布式集群。 所以并发编程的目标是充分的利用处理器的每一个核以达到最高的处理性能。 73.线程和进程的区别 进程是资源分配的最小单位线程是CPU调度的最小单位。一个进程包含多个线程一个线程只能属于一个进程。进程在执行过程中拥有内存单元。进程比线程消耗更多的资源。 74.暂定守护线程是什么 守护线程即daemon thread准确地来说就是服务其他的线程。 75.创建线程有哪几种方式 ①. 继承Thread类创建线程类 定义Thread类的子类并重写该类的run方法该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。 创建Thread子类的实例即创建了线程对象。 调用线程对象的start()方法来启动该线程。 ②. 通过Runnable接口创建线程类 定义runnable接口的实现类并重写该接口的run()方法该run()方法的方法体同样是该线程的线程执行体。 创建 Runnable实现类的实例并依此实例作为Thread的target来创建Thread对象该Thread对象才是真正的线程对象。 调用线程对象的start()方法来启动该线程。 ③. 通过Callable和Future创建线程 创建Callable接口的实现类并实现call()方法该call()方法将作为线程执行体并且有返回值。 创建Callable实现类的实例使用FutureTask类来包装Callable对象该FutureTask对象封装了该Callable对象的call()方法的返回值。 使用FutureTask对象作为Thread对象的target创建并启动新线程。 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。 76.说一下 runnable 和 callable 有什么区别 Runnable接口中的run()方法的返回值是void它做的事情只是纯粹地去执行run()方法中的代码而已 Callable接口中的call()方法是有返回值的是一个泛型和Future、FutureTask配合可以用来获取异步执行的结果。 77.线程有哪些状态 线程通常都有五种状态创建、就绪、运行、阻塞和死亡。 创建状态。在生成线程对象并没有调用该对象的start方法这是线程处于创建状态。 就绪状态。当调用了线程对象的start方法之后该线程就进入了就绪状态但是此时线程调度程序还没有把该线程设置为当前线程此时处于就绪状态。在线程运行之后从等待或者睡眠中回来之后也会处于就绪状态。 运行状态。线程调度程序将处于就绪状态的线程设置为当前线程此时线程就进入了运行状态开始运行run函数当中的代码。 阻塞状态。线程正在运行的时候被暂停通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspendwait等方法都可以导致线程阻塞。 死亡状态。如果一个线程的run方法执行结束或者调用stop方法后该线程就会死亡。对于已经死亡的线程无法再使用start方法令其进入就绪 78.sleep() 和 wait() 有什么区别 sleep()方法是线程类Thread的静态方法让调用线程进入睡眠状态让出执行机会给其他线程等到休眠时间结束后线程进入就绪状态和其他线程一起竞争cpu的执行时间。因为sleep() 是static静态的方法他不能改变对象的机锁当一个synchronized块中调用了sleep() 方法线程虽然进入休眠但是对象的机锁没有被释放其他线程依然无法访问这个对象。 wait()wait()是Object类的方法当一个线程执行到wait方法时它就进入到一个和该对象相关的等待池同时释放对象的机锁使得其他线程能够访问可以通过notifynotifyAll方法来唤醒等待的线程 79.notify()和 notifyAll()有什么区别 如果线程调用了对象的 wait()方法那么线程便会处于该对象的等待池中等待池中的线程不会去竞争该对象的锁。 当有线程调用了对象的 notifyAll()方法唤醒所有 wait 线程或 notify()方法只随机唤醒一个 wait 线程被唤醒的的线程便会进入该对象的锁池中锁池中的线程会去竞争该对象锁。也就是说调用了notify后只要一个线程会由等待池进入锁池而notifyAll会将该对象等待池内的所有线程移动到锁池中等待锁竞争。 优先级高的线程竞争到对象锁的概率大假若某线程没有竞争到该对象锁它还会留在锁池中唯有线程再次调用 wait()方法它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行直到执行完了 synchronized 代码块它会释放掉该对象锁这时锁池中的线程会继续竞争该对象锁。 80.线程的 run()和 start()有什么区别 每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的方法run()称为线程体。通过调用Thread类的start()方法来启动一个线程。 start()方法来启动一个线程真正实现了多线程运行。这时无需等待run方法体代码执行完毕可以直接继续执行下面的代码 这时此线程是处于就绪状态 并没有运行。 然后通过此Thread类调用方法run()来完成其运行状态 这里方法run()称为线程体它包含了要执行的这个线程的内容 Run方法运行结束 此线程终止。然后CPU再调度其它线程。 run()方法是在本线程里的只是线程里的一个函数,而不是多线程的。 如果直接调用run(),其实就相当于是调用了一个普通函数而已直接待用run()方法必须等待run()方法执行完毕才能执行下面的代码所以执行路径还是只有一条根本就没有线程的特征所以在多线程执行时要使用start()方法而不是run()方法。 81.建线程池有哪几种方式 ①. newFixedThreadPool(int nThreads) 创建一个固定长度的线程池每当提交一个任务就创建一个线程直到达到线程池的最大数量这时线程规模将不再变化当线程发生未预期的错误而结束时线程池会补充一个新的线程。 ②. newCachedThreadPool() 创建一个可缓存的线程池如果线程池的规模超过了处理需求将自动回收空闲线程而当需求增加时则可以自动添加新线程线程池的规模不存在任何限制。 ③. newSingleThreadExecutor() 这是一个单线程的Executor它创建单个工作线程来执行任务如果这个线程异常结束会创建一个新的来替代它它的特点是能确保依照任务在队列中的顺序来串行执行。 ④. newScheduledThreadPool(int corePoolSize) 创建了一个固定长度的线程池而且以延迟或定时的方式来执行任务类似于Timer。 线程池的作用 降低资源消耗 高效管理线程 82.线程池的几种状态 线程池有5种状态Running、ShutDown、Stop、Tidying、Terminated。 83.线程池的submit()和execute()有什么区别 execute()只能执行 Runnable 类型的任务。 submit()可以执行 Runnable 和 Callable 类型的任务。 Callable 类型的任务可以获取执行的返回值而 Runnable 执行无返回值。 84.Synchronized在 java 程序中怎么保证多线程的运行安全 线程安全在三个方面体现 原子性提供互斥访问同一时刻只能有一个线程对数据进行操作atomic,synchronized 可见性一个线程对主内存的修改可以及时地被其他线程看到synchronized,volatile 有序性一个线程观察其他线程中的指令执行顺序由于指令重排序该观察结果一般杂乱无序happens-before原则。 85.多线程锁的升级原理是什么 在Java中锁共有4种状态级别从低到高依次为无状态锁偏向锁轻量级锁和重量级锁状态这几个状态会随着竞争情况逐渐升级。锁可以升级但不能降级。 Java SE 1.6 为了减少获得锁和释放锁带来的性能消耗引入了 “偏向锁” 和 “轻量级锁”锁一共有 4 种状态级别从低到高依次是无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态。锁可以升级但不能降级。 偏向锁大多数情况下锁不仅不存在多线程竞争而且总是由同一线程多次获得为了让线程获得锁的代价更低而引入了偏向锁。当一个线程访问同步块并获取锁时会在对象头和栈帧中记录存储锁偏向的线程ID以后该线程在进入同步块时先判断对象头的Mark Word里是否存储着指向当前线程的偏向锁如果存在就直接获取锁。 轻量级锁当其他线程尝试竞争偏向锁时锁升级为轻量级锁。线程在执行同步块之前JVM会先在当前线程的栈帧中创建用于存储锁记录的空间并将对象头中的MarkWord替换为指向锁记录的指针。如果成功当前线程获得锁如果失败标识其他线程竞争锁当前线程便尝试使用自旋来获取锁。 重量级锁锁在原地循环等待的时候是会消耗CPU资源的。所以自旋必须要有一定的条件控制否则如果一个线程执行同步代码块的时间很长那么等待锁的线程会不断的循环反而会消耗CPU资源。默认情况下锁自旋的次数是10 次可以使用-XX:PreBlockSpin参数来设置自旋锁等待的次数。10次后如果还没获取锁则升级为重量级锁。 86.什么是死锁 死锁是指两个或两个以上的进程在执行过程中由于竞争资源或者由于彼此通信而造成的一种阻塞的现象若无外力作用它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁这些永远在互相等待的进程称为死锁进程。 87.怎么防止死锁 死锁的四个必要条件 互斥条件进程对所分配到的资源不允许其他进程进行访问若其他进程访问该资源只能等待直至占有该资源的进程使用完成后释放该资源 请求和保持条件进程获得一定的资源之后又对其他资源发出请求但是该资源可能被其他进程占有此事请求阻塞但又对自己获得的资源保持不放 不可剥夺条件是指进程已获得的资源在未完成使用之前不可被剥夺只能在使用完后自己释放 环路等待条件是指进程发生死锁后若干进程之间形成一种头尾相接的循环等待资源关系 这四个条件是死锁的必要条件只要系统发生死锁这些条件必然成立而只要上述条件之 一不满足就不会发生死锁。 理解了死锁的原因尤其是产生死锁的四个必要条件就可以最大可能地避免、预防和 解除死锁。 所以在系统设计、进程调度等方面注意如何不让这四个必要条件成立如何确 定资源的合理分配算法避免进程永久占据系统资源。 此外也要防止进程在处于等待状态的情况下占用资源。因此对资源的分配要给予合理的规划。 88.ThreadLocal 是什么有哪些使用场景 线程局部变量是局限于线程内部的变量属于线程自身所有不在多个线程间共享。 经典的使用场景是为每个线程分配一个 JDBC 连接 Connection。这样就可以保证每个线程的都在各自的 Connection 上进行数据库的操作不会出现 A 线程关了 B线程正在使用的 Connection 还有 Session 管理 等问题。 89.说一下 synchronized 底层实现原理 synchronized 用的锁是存在 Java 对象头里的。在 JVM 中对象在内存中的布局分为三块区域对象头、实例数据和对齐填充。 同步方法通过ACC_SYNCHRONIZED 关键字隐式的对方法进行加锁。当线程要执行的方法被标注上ACC_SYNCHRONIZED时需要先获得锁才能执行该方法。 同步代码块通过monitorenter和monitorexit执行来进行加锁。当线程执行到monitorenter的时候要先获得锁才能执行后面的方法。当线程执行到monitorexit的时候则要释放锁。每个对象自身维护着一个被加锁次数的计数器当计数器不为0时只有获得锁的线程才能再次获得锁。 Java中的每个对象都可以作为锁锁的是当前实例对象。具体表现为以下三种方式 对于普通方法锁的是当前对象 对于静态同步方法锁的是当前类的class对象 对于同步方法块锁住的是synchronized里括号里配置的内容 synchronized关键字可以保证并发编程的三大特性原子性、可见性、有序性而volatile关键字只能保证可见性和有序性不能保证原子性也称为是轻量级的synchronized。   原子性一个或多个操作全部执行成功或者全部执行失败。synchronized关键字可以保证只有一个线程拿到锁访问共享资源。   可见性当一个线程对共享变量进行修改后其他线程可以立刻看到。       执行synchronized时会对应执行lock、unlock原子操作保证可见性。 有序性程序的执行顺序会按照代码的先后顺序执行。 synchronized关键字可以实现什么类型的锁   悲观锁synchronized关键字实现的是悲观锁每次访问共享资源时都会上锁。   非公平锁synchronized关键字实现的是非公平锁即线程获取锁的顺序并不一定是按照线程阻塞的顺序。   可重入锁synchronized关键字实现的是可重入锁即已经获取锁的线程可以再次获取锁。   独占锁或者排他锁synchronized关键字实现的是独占锁即该锁只能被一个线程所持有其他线程均被阻塞。 为什么说Synchronized是一个重量级锁 Synchronized 是通过对象内部的一个叫做监视器锁monitor来实现的监视器锁本质又是依赖于底层的操作系统的 Mutex Lock互斥锁来实现的。而操作系统实现线程之间的切换需要从用户态转换到核心态这个成本非常高状态之间的转换需要相对比较长的时间这就是为什么 Synchronized 效率低的原因。因此这种依赖于操作系统 Mutex Lock 所实现的锁我们称之为 “重量级锁”。 90.synchronized 和 volatile 的区别是什么 1作用的位置不同 synchronized是修饰方法代码块。 volatile是修饰变量。 2作用不同 synchronized可以保证变量修改的可见性及原子性可能会造成线程的阻塞synchronized在锁释放的时候会将数据写入主内存保证可见性 volatile仅能实现变量修改的可见性但无法保证原子性不会造成线程的阻塞volatile修饰变量后每次读取都是去主内存进行读取保证可见性 synchronized是修饰方法代码块。 volatile是修饰变量。 91.synchronized 和 Lock 有什么区别 首先synchronized是java内置关键字在jvm层面Lock是个java类 synchronized无法判断是否获取锁的状态Lock可以判断是否获取到锁 synchronized会自动释放锁(a 线程执行完同步代码会释放锁 b 线程执行过程中发生异常会释放锁)Lock需在finally中手工释放锁unlock()方法释放锁否则容易造成线程死锁 用synchronized关键字的两个线程1和线程2如果当前线程1获得锁线程2线程等待。如果线程1阻塞线程2则会一直等待下去而Lock锁就不一定会等待下去如果尝试获取不到锁线程可以不用一直等待就结束了 synchronized的锁可重入、不可中断、非公平而Lock锁可重入、可判断、可公平两者皆可 Lock锁适合大量同步的代码的同步问题synchronized锁适合代码少量的同步问题。 92.synchronized 和 ReentrantLock 区别是什么 Synchronized是关键字ReentrantLock是类 ReentrantLock可以替代synchronized进行同步 ReentrantLock获取锁更安全不会无限等待造成死锁 必须先获取到锁再进入try {…}代码块最后使用finallyunlock()保证释放锁 93.说一下 atomic 的原理 Atomic包中的类基本的特性就是在多线程环境下当有多个线程同时对单个包括基本类型及引用类型变量进行操作时具有排他性即当多个线程同时对该变量的值进行更新时仅有一个线程能成功而未成功的线程可以向自旋锁一样继续尝试一直等到执行成功。 Atomic系列的类中的核心方法都会调用unsafe类中的几个本地方法。我们需要先知道一个东西就是Unsafe类全名为sun.misc.Unsafe这个类包含了大量的对C代码的操作包括很多直接内存分配以及原子操作的调用而它之所以标记为非安全的是告诉你这个里面大量的方法调用都会存在安全隐患需要小心使用否则会导致严重的后果例如在通过unsafe分配内存的时候如果自己指定某些区域可能会导致一些类似C一样的指针越界到其他进程的问题。 SpringBoot 94.什么是docker docker是一个用Go语言实现的开源项目可以让我们方便的创建和使用容器docker将程序以及程序所有的依赖都打包到docker container这样你的程序可以在任何环境都会有一致的表现这里程序运行的依赖也就是容器就好比集装箱容器所处的操作系统环境就好比货船或港口程序的表现只和集装箱有关系(容器)和集装箱放在哪个货船或者哪个港口(操作系统)没有关系。docker可以屏蔽环境差异也就是说只要你的程序打包到了docker中那么无论运行在什么环境下程序的行为都是一致的 95.Docker常用命令 查看正在运行容器列表 docker ps1 查看所有容器 -----包含正在运行 和已停止的 docker ps -a 停止容器 docker stop 容器ID/容器名 重启容器 docker restart 容器ID/容器名 启动容器 docker start 容器ID/容器名 查看容器日志 docker logs -f --tail要查看末尾多少行 默认all 容器ID docker logs 容器ID或名称查看容器的日志输出。 docker exec -it 容器ID或名称 /bin/bash进入容器的shell或命令行。 docker pull 镜像名称从Docker仓库中拉取一个镜像。 docker images 或 docker image ls列出本地已经下载的镜像。 docker rmi 镜像ID或名称删除本地的一个或多个镜像。 96.什么是规则引擎Drools 97.什么是spring Spring是一种轻量级框架旨在提高开发人员的开发效率以及系统的可维护性。 98.Spring由几大模块组成 1、 Core Container(核心容器) Spring的核心容器是其他模块建立的基础它主要由Beans模块、Core模块、Context模块、Context-support模块和SpEL(Spring Expression LanguageSpring表达式语言)模块组成具体介绍如下。 ·Beans模块提供了BeanFactory是工厂模式的经典实现Spring将管理对象称为Bean。 ·Core核心模块提供了Spring框架的基本组成部分可以说spring的其他所有功能都依赖该类库。包括控制反转IoC和DI功能。 ·Context上下文模块建立在Core和Beans模块的基础之上它是访问定义和配置的任何对象的媒介。其中ApplicationContext接口是上下文模块的焦点。 ·Context-support 模块提供了对第三方库嵌入 Spring 应用的集成支持比如缓存(EhCache、Guava、JCache)、邮件服务(JavaMail)、任务调度(CommonJ、Quartz)和模板引擎(FreeMarker、JasperReports、速率)。 ·SpEL模块是Spring 3.0后新增的模块它提供了Spring Expression Language支持是运行时查询和操作对象图的强大的表达式语言。 2、 Data Access/Integration(数据访问/集成) 数据访问/集成层包括JDBC、ORM、OXM、JMS和Transactions模块具体介绍如下。 ·JDBC模块提供了一个JDBC的抽象层大幅度地减少了在开发过程中对数据库操作的编码。 ·ORM模块对流行的对象关系映射API包括JPA、JDO和Hibernate提供了集成层支持。 ·OXM模块提供了一个支持对象/ XML映射的抽象层实现如JAXB、Castor、XMLBeans、JiBX和XStream。 ·JMS 模块指 Java 消息传递服务包含使用和产生信息的特性自 4.1 版本后支持与Spring-message模块的集成。 ·Transactions事务模块支持对实现特殊接口以及所有POJO类的编程和声明式的事务管理。 3、 Web Spring的Web层包括WebSocket、Servlet、Web和Portlet模块具体介绍如下。 ·WebSocket模块Spring 4.0以后新增的模块它提供了WebSocket 和SockJS的实现以及对STOMP的支持。 ·Servlet模块也称为Spring-webmvc模块包含了Spring的模型—视图—控制器(MVC)和REST Web Services实现的Web应用程序。 ·Web模块提供了基本的Web开发集成特性例如多文件上传功能、使用Servlet***来初始化IoC容器以及Web应用上下文。 ·Portlet模块提供了在Portlet环境中使用MVC实现类似Servlet模块的功能。 4、 其他模块 Spring的其他模块还有AOP、Aspects、Instrumentation以及Test模块具体介绍如下。 ·AOP 模块提供了面向切面编程实现允许定义方法拦截器和切入点将代码按照功能进行分离以降低耦合性。 ·Aspects 模块提供了与AspectJ的集成功能AspectJ是一个功能强大且成熟的面向切面编程(AOP)框架。 ·Instrumentation 模块提供了类工具的支持和类加载器的实现可以在特定的应用服务器中使用。 ·Messaging模块Spring 4.0以后新增的模块它提供了对消息传递体系结构和协议的支持。 ·Test模块提供了对单元测试和集成测试的支持。 99.DIDependency Injection和IoCInversion of Control是两个相关但不同的概念它们通常一起使用但它们的焦点和作用不同。 DIDependency Injection依赖注入 DI 是一种设计模式用于管理组件之间的依赖关系。在DI中一个组件通常是一个类或对象不再负责创建或查找它所依赖的其他组件而是通过外部的机制将这些依赖项注入到它内部。DI有助于降低组件之间的耦合度使代码更易于测试、维护和扩展。DI可以通过构造函数注入、setter方法注入或接口注入等方式实现。 IoCInversion of Control控制反转 IoC是一种设计原则强调将控制权从应用程序代码转移到框架或容器中。在IoC中应用程序不再控制组件的创建和生命周期而是将这些控制权委托给IoC容器容器负责创建、配置和管理组件。IoC的目标是解耦应用程序的各个组件使其更灵活、可维护和可测试。DI是IoC的一种具体实现方式它是IoC的一部分用于实现依赖注入。 总结 IoC是一种更广泛的概念它描述了应用程序的控制权的转移和组件之间的松耦合。DI是IoC的一种具体实现方式它关注如何管理组件之间的依赖关系以实现IoC的原则。使用DI依赖关系是通过注入而不是硬编码在组件内部实现的这使得组件更容易被替换和测试。Spring框架是一个典型的IoC容器它提供了依赖注入的功能帮助开发者实现IoC原则。 100.IOC是什么 IOCInversion Of Controll控制反转又叫依赖注入是一种设计思想就是将原本在程序中手动创建对象的控制权交给IOC容器来管理并由IOC容器完成对象的注入。这样可以很大程度上简化应用的开发把应用从复杂的依赖关系中解放出来。IOC容器就像是一个工厂一样当我们需要创建一个对象的时候只需要配置好配置文件/注解即可完全不用考虑对象是如何被创建出来的。 Spring 中的 IoC 的实现原理就是工厂模式加反射机制。 101.Aop是什么 AOPAspect-Oriented Programming面向切面编程AOPAspect-Oriented Programming面向切面编程是一种编程范式用于增强和扩展应用程序的功能。 能够将那些与业务无关却为业务模块所共同调用的逻辑或责任例如事务处理、日志管理、权限控制等封装起来便于减少系统的重复代码降低模块间的耦合度并有利于未来的可扩展性和可维护性。 Spring AOP是基于动态代理的如果要代理的对象实现了某个接口那么Spring AOP就会使用JDK动态代理去创建代理对象而对于没有实现接口的对象就无法使用JDK动态代理转而使用CGlib动态代理生成一个被代理对象的子类来作为代理。 当然也可以使用AspectJSpring AOP中已经集成了AspectJAspectJ应该算得上是Java生态系统中最完整的AOP框架了。使用AOP之后我们可以把一些通用功能抽象出来在需要用到的地方直接使用即可这样可以大大简化代码量。我们需要增加新功能也方便提高了系统的扩展性。日志功能、事务管理和权限管理等场景都用到了AOP。 102.Aop包含的几个概念 Jointpoint连接点具体的切面点点抽象概念可以是在字段、方法上Spring中具体表现形式是PointCut切入点仅作用在方法上。 Advice通知: 在连接点进行的具体操作如何进行增强处理的分为前置、后置、异常、最终、环绕五种情况。 目标对象被AOP框架进行增强处理的对象也被称为被增强的对象。 AOP代理AOP框架创建的对象简单的说代理就是对目标对象的加强。Spring中的AOP代理可以是JDK动态代理也可以是CGLIB代理。 Weaving织入将增强处理添加到目标对象中创建一个被增强的对象的过程 总结为一句话就是在目标对象target object的某些方法jointpoint添加不同种类的操作通知、增强操处理最后通过某些方法weaving、织入操作实现一个新的代理目标对象。 103.Aop有哪些应用场景 记录日志权限控制事务管理监控性能 104.有哪些aop的Advice通知类型 特定 JoinPoint 处的 Aspect 所采取的动作称为 Advice。Spring AOP 使用一个 Advice 作为拦截器在 JoinPoint “周围”维护一系列的拦截器。 前置通知Before advice 这些类型的 Advice 在 joinpoint 方法之前执行并使用 Before 注解标记进行配置。 后置通知After advice 这些类型的 Advice 在连接点方法之后执行无论方法退出是正常还是异常返回并使用 After 注解标记进行配置。 返回后通知After return advice 这些类型的 Advice 在连接点方法正常执行后执行并使用AfterReturning 注解标记进行配置。 环绕通知Around advice 这些类型的 Advice 在连接点之前和之后执行并使用 Around 注解标记进行配置。 抛出异常后通知After throwing advice 仅在 joinpoint 方法通过抛出异常退出并使用 AfterThrowing 注解标记配置时执行。 105.Aop有哪些实现方式 实现 AOP 的技术主要分为两大类 静态代理 - 指使用 AOP 框架提供的命令进行编译从而在编译阶段就可生成 AOP 代理类因此也称为编译时增强 编译时编织特殊编译器实现 类加载时编织特殊的类加载器实现。 动态代理 - 在运行时在内存中“临时”生成 AOP 动态代理类因此也被称为运行时增强。 JDK 动态代理 JDK Proxy 是 Java 语言自带的功能无需通过加载第三方类实现 Java 对 JDK Proxy 提供了稳定的支持并且会持续的升级和更新Java 8 版本中的 JDK Proxy 性能相比于之前版本提升了很多 JDK Proxy 是通过拦截器加反射的方式实现的 JDK Proxy 只能代理实现接口的类 JDK Proxy 实现和调用起来比较简单 CGLIB CGLib 是第三方提供的工具基于 ASM 实现的性能比较高 CGLib 无需通过接口来实现它是针对类实现代理主要是对指定的类生成一个子类它是通过实现子类的方式来完成调用的。 106.谈谈对cgLIB的理解 JDK 动态代理机制只能代理实现接口的类一般没有实现接口的类不能进行代理。使用 CGLib 实现动态代理完全不受代理类必须实现接口的限制。 CGLib 的原理是对指定目标类生成一个子类并覆盖其中方法实现增强但因为采用的是继承所以不能对 final 修饰的类进行代理。 107.Spring aop和aspectJ aop有什么区别 Spring AOP是属于运行时增强而AspectJ是编译时增强。Spring AOP基于代理Proxying而AspectJ基于字节码操作Bytecode Manipulation。 Spring AOP已经集成了AspectJAspectJ应该算得上是Java生态系统中最完整的AOP框架了。AspectJ相比于Spring AOP功能更加强大但是Spring AOP相对来说更简单。 如果我们的切面比较少那么两者性能差异不大。但是当切面太多的话最好选择AspectJ它比SpringAOP快很多。 108.SpringBean的作用域 singleton唯一bean实例Spring中的bean默认都是单例的。 prototype每次请求都会创建一个新的bean实例。 request每一次HTTP请求都会产生一个新的bean该bean仅在当前HTTP request内有效。 session每一次HTTP请求都会产生一个新的bean该bean仅在当前HTTP session内有效。 109.Bean的生命周期 分为四个阶段 实例化属性设置初始化销毁 实例化对于beanFactory容器会调用createBean进行实例化 对于applicationContext容器当容器启动后会实例化所有bean 设置属性(依赖注入)实例化后的对象放在beanWrapper中spring会根据beanDefinition的信息进行依赖注入 在Spring框架中Bean即Spring容器管理的对象的生命周期通常包括以下阶段 实例化Instantiation在这个阶段Spring容器创建Bean的实例。这通常是通过构造函数或工厂方法进行的。Bean的定义信息通常在XML配置文件中指定。属性注入Property Injection一旦Bean实例化完成Spring容器会将相关的属性注入到Bean中。这可以通过属性注入、构造函数注入或方法注入例如Autowired注解来实现。Bean的初始化方法调用Initialization在Bean实例化和属性注入之后容器会调用Bean的初始化方法如果有定义的话。可以使用PostConstruct注解或XML配置中的init-method属性来指定初始化方法。Bean的使用In Use在Bean初始化完成后它可以被其他Bean或应用程序组件使用。Bean的销毁方法调用Destruction在Bean不再需要时容器可以调用Bean的销毁方法来释放资源。可以使用PreDestroy注解或XML配置中的destroy-method属性来指定销毁方法。Bean的销毁Disposal在销毁方法调用后Bean会被销毁从Spring容器中移除。这时Bean的实例将被垃圾回收。 请注意Bean的生命周期可以受到Spring配置、注解和XML文件的影响。您可以选择使用合适的方法和注解来管理Bean的生命周期以满足应用程序的需求。 110.Spring用了哪些设计模式 1.工厂设计模式Spring使用工厂模式通过BeanFactory和ApplicationContext创建bean对象。 2.代理设计模式Spring AOP功能的实现。 3.单例设计模式Spring中的bean默认都是单例的。 4.模板方法模式Spring中的jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类它们就使用到了模板模式。 5.包装器设计模式我们的项目需要连接多个数据库而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。 6.观察者模式Spring事件驱动模型就是观察者模式很经典的一个应用。 7.适配器模式Spring AOP的增强或通知Advice使用到了适配器模式、Spring MVC中也是用到了适配器模式适配Controller。 111.Component和Bean的区别是什么 作用对象不同。Component注解作用于类而Bean注解作用于方法。 112.将一个类声明为spring的bean注解有哪些 我们一般使用Autowired注解去自动装配bean。而想要把一个类标识为可以用Autowired注解自动装配的bean可以采用以下的注解实现 1.Component注解。通用的注解可标注任意类为Spring组件。如果一个Bean不知道属于哪一个层可以使用Component注解标注。 2.Repository注解。对应持久层即Dao层主要用于数据库相关操作。 3.Service注解。对应服务层即Service层主要涉及一些复杂的逻辑需要用到Dao层注入。 4.Controller注解。对应Spring MVC的控制层即Controller层主要用于接受用户请求并调用Service层的方法返回数据给前端页面。 113.Spring事务管理的方式有几种 1.编程式事务在代码中硬编码不推荐使用。 2.声明式事务在配置文件中配置推荐使用分为基于XML的声明式事务和基于注解的声明式事务。 114.Spring事务中的隔离级别有哪几种 115.Spring中Bean Factory和ApplicationContext有什么区别 116.可以通过多少种方式完成依赖注入 构造函数注入 Setter注入 接口注入 117.说说对spring Mvc的工作原理 1.客户端浏览器发送请求直接请求到DispatcherServlet。 2.DispatcherServlet根据请求信息调用HandlerMapping解析请求对应的Handler。 3.解析到对应的Handler也就是我们平常说的Controller控制器。 4.HandlerAdapter会根据Handler来调用真正的处理器来处理请求和执行相对应的业务逻辑。 5.处理器处理完业务后会返回一个ModelAndView对象Model是返回的数据对象View是逻辑上的View。 6.ViewResolver会根据逻辑View去查找实际的View。 7.DispatcherServlet把返回的Model传给View视图渲染。 8.把View返回给请求者浏览器。 118.什么是spring boot Spring Boot 是 Spring 开源组织下的子项目是 Spring 组件一站式解决方案主要是简化了使用 Spring 的难度简省了繁重的配置提供了各种启动器开发者能快速上手。 用来简化Spring应用的初始搭建以及开发过程使用特定的方式来进行配置 创建独立的Spring引用程序main方法运行 嵌入的tomcat无需部署war文件 简化maven配置 自动配置Spring添加对应的功能starter自动化配置 SpringBoot来简化Spring应用开发约定大于配置去繁化简 119.Springboot的原理 120.为什么使用spring boot(优点) 独立运行 Spring Boot 而且内嵌了各种 servlet 容器Tomcat、Jetty 等现在不再需要打成war 包部署到容器中Spring Boot 只要打成一个可执行的 jar 包就能独立运行所有的依赖包都在一个 jar 包内。 简化配置 spring-boot-starter-web 启动器自动依赖其他组件简少了 maven 的配置。 自动配置 Spring Boot 能根据当前类路径下的类、jar 包来自动配置 bean如添加一个 spring boot-starter-web 启动器就能拥有 web 的功能无需其他配置。 无代码生成和XML配置 Spring Boot 配置过程中无代码生成也无需 XML 配置文件就能完成所有配置工作这一切都是借助于条件注解完成的这也是 Spring4.x 的核心功能之一。 应用监控 Spring Boot 提供一系列端点可以监控服务及应用做健康检测。 121.请解释一下工厂模式 工厂模式将目的将创建对象的具体过程屏蔽隔离起来从而达到更高的灵活性工厂模式可以分为三类 简单工厂模式Simple Factory 简单工厂模式的核心是定义一个创建对象的接口将对象的创建和本身的业务逻辑分离降低系统的耦合度使得两个修改起来相对容易些当以后实现改变时只需要修改工厂类即可。 优缺点 简单工厂模式提供专门的工厂类用于创建对象实现了对象创建和使用的职责分离客户端不需知道所创建的具体产品类的类名以及创建过程只需知道具体产品类所对应的参数即可通过引入配置文件可以在不修改任何客户端代码的情况下更换和增加新的具体产品类在一定程度上提高了系统的灵活性。 但缺点在于不符合“开闭原则”每次添加新产品就需要修改工厂类。在产品类型较多时有可能造成工厂逻辑过于复杂不利于系统的扩展维护并且工厂类集中了所有产品创建逻辑一旦不能正常工作整个系统都要受到影响。 工厂方法模式Factory Method 工厂方法模式将工厂抽象化并定义一个创建对象的接口。每增加新产品只需增加该产品以及对应的具体实现工厂类由具体工厂类决定要实例化的产品是哪个将对象的创建与实例化延迟到子类这样工厂的设计就符合“开闭原则”了扩展时不必去修改原来的代码。在使用时用于只需知道产品对应的具体工厂关注具体的创建过程甚至不需要知道具体产品类的类名当我们选择哪个具体工厂时就已经决定了实际创建的产品是哪个了。 但缺点在于每增加一个产品都需要增加一个具体产品类和实现工厂类使得系统中类的个数成倍增加在一定程度上增加了系统的复杂度同时也增加了系统具体类的依赖。 抽象工厂模式Abstract Factory 抽象工厂模式主要用于创建相关对象的家族通过抽象工厂模式所有的具体工厂都实现了抽象工厂中定义的公共接口因此只需要改变具体工厂的实例就可以在某程度上改变整个行为。 但该模式的缺点在于添加新的行为时比较麻烦如果需要添加一个新产品族对象时需要更改接口及其下所有子类这必然会带来很大的麻烦。 工厂模式小结 工厂方法模式与抽象工厂模式的区别在于 1工厂方法只有一个抽象产品类和一个抽象工厂类但可以派生出多个具体产品类和具体工厂类每个具体工厂类只能创建一个具体产品类的实例。 2抽象工厂模式拥有多个抽象产品类产品族和一个抽象工厂类每个抽象产品类可以派生出多个具体产品类抽象工厂类也可以派生出多个具体工厂类同时每个具体工厂类可以创建多个具体产品类的实例 122.请解释一下单例模式 懒汉模式在第一次调用的时候实例 饿汉模式饿汉就是类一旦加载就把单例初始化完成保证getInstance的时候单例是已经存在的了。 123.请解释一下代理模式 结构型设计模式 代理模式是常见的设计模式之一顾名思义代理模式就是代理对象具备真实对象的功能并代替真实对象完成相应操作并能够在操作执行的前后对操作进行增强处理。为真实对象提供代理然后供其他对象通过代理访问真实对象 静态代理 动态代理: 124.简单说下Redis 125.消息队列 126.单元测试 127.zpl语言 ZPLZebra Programming Language是一种专门用于打印标签和条形码的标签打印机编程语言。ZPL是由斑马技术Zebra Technologies开发的并且广泛用于各种标签打印机和条形码打印机上。 ZPL语言的主要目的是控制标签打印机的行为包括文本、条形码、图像、位置和格式等方面。通过编写ZPL命令用户可以自定义标签的外观和内容并将这些命令发送给标签打印机以在标签上生成所需的标识信息。 以下是一些常见的ZPL语言元素和命令 ^XA // 标签开始 ^XZ // 标签结束 128.Redis
http://www.hkea.cn/news/14293626/

相关文章:

  • 国外比较有名的设计工作室网站asp.net网站安装顺序
  • 山东众德建设项目管理公司网站专业网架加工
  • 手绘风网站揭阳建设网站
  • wordpress投稿上传图片泽成杭州seo网站推广排名
  • 几台服务器做集群网站紫金论坛最新新闻事件
  • 做网站的公司跑了台州椒江找人做网站
  • 大兴网站建设优化seo惠济郑州网站建设
  • 网站建设售后服务方案免费公司网站模板
  • 手机建站源码巩义企业网站托管代运营公司
  • 免费网站封装apphtml网站建设中
  • 南京溧水城市建设集团网站wordpress更改固定链接后无法登陆
  • 做网站需要多大的显存石家庄网站托管
  • 建设网站的主要流程有哪些内容互联网行业都有哪些专业
  • 青海做高端网站建设的公司WordPress导航条之间得跳转
  • 南昌网站建设 南昌做网站公司图文广告设计公司
  • 注册 网站开发 公司深圳 网站建设设计
  • wordpress网站和微信公众号广东省网站设计与开发
  • 您有新信息 建设招标网官方网站临汾推广型网站开发
  • 途牛网站开发需求360渠道推广系统
  • 最好的网站设计重庆网站建设 夹夹虫
  • 网站出租建设做同业业务一般关注哪些网站
  • 做一个app成本济南网站优化收费标准
  • 佛山网站设计培训深圳品牌型网站建设
  • 网站建设图片怎么调网站开发计划书网站技术解决方案
  • 网站开发的背景是指什么软件沈阳小程序开发报价
  • 卖域名的网站要怎么做兼容性视图中显示所有网站
  • 受欢迎的建网站哪家好怎么从网上找客户
  • 网站建设与管理专业工资高吗tcn短网址在线生成
  • 有没关于做动画设计师的网站网站欣赏公司网站案例
  • 网站对于企业的好处网站建设 公司新闻