1.MyBatis与MyBatis-Plus的区别?
MyBatis和MyBatis-Plus都是Java语言中非常常用的ORM框架,二者有以下区别:
1.实现方式不同
MyBatis是基于XML或注解方式进行数据库操作的持久化框架,它提供了简单的CRUD操作及动态SQL生成等功能。
而MyBatis-Plus是在MyBatis框架上的封装,通过对于增强简化后的API更加方便地进行开发,并且在性能、效率和易用性上都有一定的优化。
2.功能支持不同
MyBatis-Plus相比于MyBatis提供了很多额外的功能,例如像条件构造器、代码生成器、分页插件、性能分析拦截器等实用的组件,使得开发者可以轻松快速完成业务逻辑的开发。
而MyBatis相对较为原始,需要手写大量的SQL以完成各种功能的实现。
3.编程风格有所差异
MyBatis的编程风格更加传统,需要定义mapper.xml文件并根据传入的参数使用相应的SQL查询语句,需要实现 Mybatis 提供的各种方法;
而MyBatis-Plus具有许多针对CRUD进行的简化方法,通过继承BaseMapper以及使用Lambda表达式,可以让我们像SpringDataJPA类似地使用接口编程方式进行数据库操作。
下面通过代码示例来演示一下MyBatis和MyBatis-Plus的区别:
-
MyBatis的实现
首先在Mybatis中需要配置sql mapper映射文件,如下所示:
<!-- userMapper.xml -->
<mapper namespace="com.demo.dao.UserMapper">
<select id="getUserById" parameterType="java.lang.Integer" resultType="com.demo.entity.User">
select * from t_user where id=#{id}
</select>
</mapper>
然后通过Mybatis的SqlSession执行相关方法实现数据查询:
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(configuration);
SqlSession sqlSession = sessionFactory.openSession();
User user = sqlSession.selectOne("com.demo.dao.UserMapper.getUserById", 1);
sqlSession.close();
-
MyBatis-Plus的实现
在MyBatis-Plus中则要比上述方式简单得多,并且提供了更加方便的CRUD操作。例如我们可以定义一个接口继承BaseMapper接口并调用其中提供的方法来操作数据库,如下所示:
public interface UserMapper extends BaseMapper<User> {
}
以下是从数据库中根据ID查询数据时,可以在Service层直接调用BaseMapper中提供的selectById()方法:
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override
public User getUserById(Long id) {
return baseMapper.selectById(id);
}
}
2.对称加密和非对称加密的区别
在Java中,对称加密和非对称加密是实现数据加密的两种主要方法,它们在安全性、速度和使用场景上有着本质的区别。下面是对这两种加密方法的基本区别的详细解释:
对称加密
1. **密钥使用**:对称加密使用相同的密钥进行加密和解密。这意味着发送方和接收方都必须拥有这个密钥,并且保持密钥的安全性。
2. **速度**:对称加密算法通常比非对称加密算法要快,因为它们使用的算法比较简单,适合对大量数据进行加密。
3. **安全性**:虽然对称加密算法本身可以非常安全,但密钥管理(尤其是密钥的分发和存储)可能会成为安全性的弱点。
4. **常见算法**:AES(高级加密标准)、DES(数据加密标准)、3DES(三重数据加密算法)等。
非对称加密
1. **密钥使用**:非对称加密使用一对密钥,一个是公开密钥(公钥),另一个是私有密钥(私钥)。公钥用于加密数据,而私钥用于解密数据。公钥可以公开,但私钥必须保密。
2. **速度**:非对称加密算法通常比对称加密慢,因为它们使用的算法更复杂,适用于小块数据的加密,如密钥交换、数字签名等。
3. **安全性**:非对称加密提供了更高级别的安全性,尤其是在公钥/私钥的管理和密钥交换方面,因为即使公钥被公开,没有私钥也无法解密数据。
4. **常见算法**:RSA、ECC(椭圆曲线加密)、Diffie-Hellman 密钥交换等。
使用场景
- **对称加密**通常用于加密大量数据的情况,因为它的加密和解密过程更快。
- **非对称加密**通常用于加密小量数据或进行安全密钥交换的场景。例如,在SSL/TLS协议中,非对称加密用于安全地交换对称密钥,然后对称密钥用于加密传输的数据。
在实际应用中,为了同时利用对称加密的高效性和非对称加密的安全性,两者往往会结合使用。例如,非对称加密用于安全地交换对称加密密钥,然后使用对称加密密钥来加密实际的数据传输。这种方法结合了两者的优点,既保证了加密过程的安全性,又提高了加密和解密的效率。
3.MyBatis-Plus关联表查询怎么写
在 MyBatis-Plus 中进行多表关联查询可以通过使用注解 @TableField
和 @TableId
,以及使用 QueryWrapper 或 LambdaQueryWrapper 来实现。
以下是一个示例,假设有两个表 A 和 B,它们之间通过外键关联:
1.实体类定义
@Data
@TableName("table_a")
public class TableA {
@TableId("id")
private Long id;
@TableField("name")
private String name;
@TableField("b_id")
private Long bId;
}
@Data
@TableName("table_b")
public class TableB {
@TableId("id")
private Long id;
@TableField("name")
private String name;
}
2.数据库查询
@Service
public class MyService {
@Autowired
private TableAMapper tableAMapper;
public List<TableA> getTableAWithTableB() {
QueryWrapper<TableA> queryWrapper = new QueryWrapper<>();
queryWrapper.inSql("b_id", "select id from table_b");
return tableAMapper.selectList(queryWrapper);
}
}
在这个示例中,通过在 TableA 实体类中添加 @TableField("b_id")
注解来映射 A 表中与 B 表关联的字段。然后在 MyService 类中通过 QueryWrapper 来创建查询条件,实现了 A 表和 B 表的联合查询。
当然,具体的多表关联查询方式还取决于你的数据库表结构和业务需求,你可以根据实际情况进行调整和修改。
4.(笔试题-选择)已知二叉树的前序遍历和中序遍历,选择后序遍历结果
二叉树的深度优先遍历有三种形式,分别是:
前序遍历:遍历顺序为根左右;
中序遍历:遍历顺序为左根右;
后序遍历:遍历顺序为左右根。
以下面一颗二叉树为例,它的不同形式的深度优先遍历的结果为:
前序遍历:1 2 4 7 3 5 6 8
中序遍历:4 7 2 1 5 3 8 6
后序遍历:7 4 2 5 8 6 3 1
5.(笔试题-选择)数据结构中,同时满足最快查找和删除的是:有序数组、二叉树、HashMap、有序链表?
在数据结构中,同时满足最快查找和删除的是哈希表(HashMap)。哈希表具有常数时间复杂度 O(1) 的查找和删除操作,即使在最坏情况下,其时间复杂度也是 O(n),但通常情况下能够提供非常高效的性能。相比之下,有序数组、二叉树和有序链表在查找和删除方面的性能通常较差,其时间复杂度通常为 O(log n) 或 O(n)。
6.(笔试题-选择)最快的排序算法:快速排序、堆排序、冒泡排序、归并排序?
在Java中,最快的排序算法通常是快速排序(Quick Sort)。快速排序的平均时间复杂度为 O(n log n),在最好情况下可达到 O(n log n),而在最坏情况下为 O(n^2)。尽管最坏情况下的性能可能不如其他排序算法,但在实践中,快速排序通常表现出色,尤其对于大规模数据集合。
归并排序(Merge Sort)也是一种非常有效的排序算法,其时间复杂度同样为 O(n log n),而且在任何情况下都能保持稳定的性能。
堆排序(Heap Sort)虽然具有 O(n log n) 的时间复杂度,但相比快速排序和归并排序,它通常在实践中稍显慢一些。
冒泡排序(Bubble Sort)的时间复杂度为 O(n^2),在大规模数据集合中效率较低,通常不被认为是最快的排序算法。
因此,综合考虑,快速排序和归并排序通常被认为是Java中最快的排序算法之一。
7.(笔试题-填空)TCP和ip分别在OSI模型的哪一层?
TCP(Transmission Control Protocol)和IP(Internet Protocol)位于OSI模型中的不同层级。
- TCP(传输控制协议)位于OSI模型的第四层,即传输层。它负责提供可靠的、面向连接的通信服务,确保数据的可靠传输,以及数据的分段、重组、流量控制和拥塞控制等功能。
- IP(Internet Protocol)位于OSI模型的第三层,即网络层。它负责在网络中实现主机之间的数据传输,包括寻址、路由和分片等功能。
因此,TCP负责在应用程序之间建立可靠的连接和数据传输,而IP负责在网络中的主机之间进行数据包的路由和转发。
8.(笔试题-填空)403表示什么意思?
一、什么是HTTP ERROR 403
403 Forbidden 是HTTP协议中的一个状态码(Status Code)。可以简单的理解为没有权限访问此站,服务器受到请求但拒绝提供服务。
二、HTTP 403 状态码解释大全
403.1 -执行访问禁止。
403.2 -读访问禁止。
403.3 -写访问禁止。
403.4要求SSL。
403.5 - 128要求SSL。
403.6 - IP地址被拒绝。
403.7 -客户证书要求。
403.8 -站点访问被拒绝。
403.9 -禁止:太多的客户端试图连接到Web服务器。
403.10 -禁止:Web服务器配置为拒绝执行访问。
403.11 -禁止:密码已更改。
403.12映射器拒绝访问。
403.13 -客户端证书吊销。
403.14 -目录列表被拒绝。
403.15 -禁止:客户端访问许可证超出了Web服务器的限制。
403.16客户证书不可信或无效。
403.17 -客户端证书已过期或尚未有效。
403.18 -无法在当前应用程序池中执行请求的URL。
403.19不能执行此应用程序池中的客户端的CGI应用程序。
403.20 -禁止:护照登录失败。
403.21 -禁止:源访问拒绝。
403.22 -禁止:无限深度被拒绝。
403.502 -禁止:来自同一客户端IP的请求太多;达到动态IP限制限制。
三、导致403错误的主要原因
1、你的IP被列入黑名单。
2、你在一定时间内过多地访问此网站(一般是用采集程序),被防火墙拒绝访问了。
3、网站域名解析到了空间,但空间未绑定此域名。
4、你的网页脚本文件在当前目录下没有执行权限。
5、在不允许写/创建文件的目录中执行了创建/写文件操作。
6、以http方式访问需要ssl连接的网址。
7、浏览器不支持SSL 128时访问SSL 128的连接。
8、在身份验证的过程中输入了错误的密码。
9、DNS解析错误,手动更改DNS服务器地址。
10、连接的用户过多,可以过后再试。
11、服务器繁忙,同一IP地址发送请求过多,遭到服务器智能屏蔽。
9.(笔试题-算法)判断由“(”和“)”组成的字符串是否是合理的成对出现的。
10.(笔试题)获取俩个集合的交集。
11.(笔试题)最终输出的值
public static void main(String[] args) {
//n=5
System.out.println(fun(5));
}
public static int fun(int n){
if (n < 2){
return 0;
}
return fun(n-2) + fun(n-1);
}
结果:0
12.map和set的区别
1.Map是键值对,Set是值的集合,当然键和值可以是任何的值;
2.Map可以通过get方法获取值,而set不能因为它只有值;
3.都能通过迭代器进行for…of遍历;
4.Set的值是唯一的可以做数组去重,Map由于没有格式限制,可以做数据存储
5.map和set都是stl中的关联容器,map以键值对的形式存储,key=value组成pair,是一组映射关系。set只有值,可以认为只有一个数据,并且set中元素不可以重复且自动排序
13.Redis的存储结构
Redis的五种数据结构
一、字符串(String)
字符串是Redis最基本的数据结构,可以存储任意类型的数据,例如文本、数字等。Redis中的字符串是二进制安全的,可以进行基于字符串的操作,如设置、获取、修改、删除等。
-
应用场景: 单值缓存、对象缓存、计数器
-
存储结构
-
-
SpringBoot中基本操作
-
@Slf4j @RestController @RequestMapping("/redis/string") public class RedisStringController { @Resource private RedisTemplate redisTemplate; @GetMapping("/set") public void setString() { redisTemplate.opsForValue().set("key", 1); } @GetMapping("/get") public void getString() { Object key = redisTemplate.opsForValue().get("key"); log.info("{}", key); if (key.equals(1)) { log.info("111"); } if ((Integer) key == 1) { log.info("Integer类型"); } } @GetMapping("/delete") public void deleteString() { redisTemplate.delete("key"); } }
二、列表(List)
列表是一个有序的字符串集合,可以存储多个字符串元素。列表支持在头部或尾部进行元素的插入、删除、获取等操作,还支持根据索引进行访问和修该。列表可以用于实现队列、栈等数据结构。
-
应用场景: 公众号最新消息
-
存储结构
-
-
SpringBoot中基本操作
@RestController @Slf4j @RequestMapping("/redis/list") public class RedisListController { @Resource private RedisTemplate redisTemplate; @PostMapping("/push") public void pushList() { BoundListOperations listOps = redisTemplate.boundListOps("msg:1001"); listOps.leftPush("123"); listOps.leftPush("456"); listOps.rightPush("789"); //使用list集合 // List<String> list = new LinkedList<>(); // list.add("123"); // list.add("456"); // listOps.leftPushAll(list); } @PostMapping("/get") public void getList() { BoundListOperations listOps = redisTemplate.boundListOps("msg:1001"); Object index = listOps.index(0); log.info("获取指定索引位置的元素: {}", index); List range = listOps.range(0, listOps.size() - 1); log.info("获取所有元素: {}", range.toString()); } @PostMapping("/pop") public void popList() { BoundListOperations listOps = redisTemplate.boundListOps("msg:1001"); Object leftPop = listOps.leftPop(); log.info("从左弹出一个元素: {}", leftPop); Object rightPop = listOps.rightPop(); log.info("从右弹出一个元素: {}", rightPop); } @PostMapping("/del") public void delList() { redisTemplate.delete("msg:1001"); } }
三、哈希表(Hash)
哈希表是一个键值对的无序集合,其中每个键都是一个唯一的字符串,与一个值相关联。哈希表适用于存储对象,每个对象可以有多个属性。在哈希表中,可以对单个键或整个哈希表执行增删改查的操作。
-
应用场景: 对象缓存、购物车
-
存储结构
-
-
SpringBoot中基本操作
@Slf4j @RestController @RequestMapping("/redis/hash") public class RedisHashController { @Resource private RedisTemplate redisTemplate; @PostMapping("/set") public void setHash() { BoundHashOperations hashOps = redisTemplate.boundHashOps("user"); hashOps.put("1:username", "张三"); hashOps.put("1:password", "123"); //或者使用putAll // Map<String, String> map = new HashMap<>(); // map.put("1:username", "张三"); // map.put("1:password", "123"); // hashOps.putAll(map); log.info("set-string"); } @PostMapping("/get") public void getHash() { //获取所有key BoundHashOperations hashOps = redisTemplate.boundHashOps("user"); Set keys = hashOps.keys(); log.info("获取所有key: {}", keys.toString()); //获取所有value List values = hashOps.values(); log.info("获取所有value: {}", values.toString()); //根据key获取value Object o = hashOps.get("1:username"); log.info("根据key获取value: {}", o); //获取所有键值对集合 Map entries = hashOps.entries(); log.info("获取所有键值对集合: {}", entries.toString()); } @PostMapping("/find") public void findHash() { BoundHashOperations hashOps = redisTemplate.boundHashOps("user"); Boolean hasKey = hashOps.hasKey("1:username"); log.info("判断hash中是否存在该键值对: {}", hasKey); } @PostMapping("/del") public void delHash() { //删除key(小key) BoundHashOperations hashOps = redisTemplate.boundHashOps("user"); hashOps.delete("1:username"); //直接删除hash(大key) redisTemplate.delete("user"); } }
四、集合(Set)
-
集合是一组唯一的、无序的字符串元素的集合。集合支持添加、删除、判断元素是否存在等操作,还支持集合间的交集、并集、差集等集合运算操作。集合适用于对成员进行唯一性判断或快速查找。
-
应用场景: 抽奖、点赞、收藏、标签、微博等平台关注模型(共同好友、可能认识的人等)
-
存储结构
-
SpringBoot中基本操作
@RestController @Slf4j @RequestMapping("/redis/set") public class RedisSetController { @Resource private RedisTemplate redisTemplate; @PostMapping("/add") public void addSet() { BoundSetOperations setOps = redisTemplate.boundSetOps("act:101"); setOps.add("001", "002", "003"); } @PostMapping("/member") public void memberSet() { BoundSetOperations setOps = redisTemplate.boundSetOps("act:101"); List list = setOps.randomMembers(2); log.info("随机获取两个元素: {}", list.toString()); Set members = setOps.members(); log.info("获取所有的值: {}", members.toString()); } @PostMapping("/find") public void findSet() { BoundSetOperations setOps = redisTemplate.boundSetOps("act:101"); Boolean member = setOps.isMember("002"); log.info("判断元素是否存在于set中: {}", member); } @PostMapping("/remove") public void removeSet() { BoundSetOperations setOps = redisTemplate.boundSetOps("act:101"); Long remove = setOps.remove("002"); log.info("移除指定的元素个数: {}", remove); } @PostMapping("/del") public void delSet() { redisTemplate.delete("act:101"); } }
五、有序集合(ZSet)
有序集合是一个有序的字符串集合,每个字符串都与一个分数相关联。有序集合按照分数进行排序,可以根据分数范围或成员值进行范围查询。有序集合常用于排行榜、排序等场景。
-
应用场景: 排行榜、带权重的任务调度
-
存储结构
-
SpringBoot中基本操作
@RestController @Slf4j @RequestMapping("/redis/zset") public class RedisZSetController { @Resource private RedisTemplate redisTemplate; @GetMapping("/add") public void addZSet() { BoundZSetOperations zSetOps = redisTemplate.boundZSetOps("hotspot:20230602"); zSetOps.add("李四", 2); zSetOps.add("王五", 1); zSetOps.add("刘留", 3); zSetOps.add("赵六", 4); zSetOps.add("张三", 6); } @GetMapping("/range") public void rangeZSet() { BoundZSetOperations zSetOps = redisTemplate.boundZSetOps("hotspot:20230602"); Set range = zSetOps.range(0, -1); log.info("获取ZSet中所有的元素:{}", range); } @GetMapping("/rangeByScore") public void rangeByScoreZSet() { BoundZSetOperations zSetOps = redisTemplate.boundZSetOps("hotspot:20230602"); Set range = zSetOps.rangeByScore(2, 4); log.info("获取ZSet中指定score范围中的元素:{}", range); } @GetMapping("/size") public void sizeZSet() { BoundZSetOperations zSetOps = redisTemplate.boundZSetOps("hotspot:20230602"); Long size = zSetOps.size(); log.info("获取ZSet中元素的长度:{}", size); } @GetMapping("/incrementScore") public void incrementScoreZSet() { BoundZSetOperations zSetOps = redisTemplate.boundZSetOps("hotspot:20230602"); log.info("获取ZSet中增加前[张三]的score:{}", zSetOps.score("张三")); zSetOps.incrementScore("张三", 3); log.info("获取ZSet中增加后[张三]的score:{}", zSetOps.score("张三")); } @GetMapping("/count") public void countZSet() { BoundZSetOperations zSetOps = redisTemplate.boundZSetOps("hotspot:20230602"); Long count = zSetOps.count(2, 6); log.info("获取ZSet中指定score范围内的个数:{}", count); } @GetMapping("/remove") public void removeZSet() { BoundZSetOperations zSetOps = redisTemplate.boundZSetOps("hotspot:20230602"); log.info("获取ZSet中移除[李四]之前的元素:{}", zSetOps.range(0,-1)); zSetOps.remove("李四"); log.info("获取ZSet中移除[李四]之后的元素:{}", zSetOps.range(0,-1)); } }
14.io的了解
Java IO 体系的组成部分:BIO 和 NIO
BIO 的基本组成部分:字节流,字符流,转换流和处理流
NIO 的三大重要模块:缓冲区(Buffer),通道(Channel),选择器(Selector)以及它们的作用
NIO 与 BIO 两者的对比:同步/非同步、阻塞/非阻塞,在文件 IO 和 网络 IO 中,使用 NIO 相对于使用 BIO 有什么优势
15.说说索引
1.什么是索引?
索引是一种特殊的文件,它包含着对数据表里所有记录的引用指针
索引是一种数据结构,以协助快速查询,更新数据库中的数据
所有的实现通常使用B树接变种B+树
更通俗的说索引就相当于目录,为了方便查找书中的内容,通过对内容建立索引形成目录
索引是一个文件,它是要占用物理空间的
2.索引的优缺点?
索引的优点:
1.可以大大加快数据的检索速度,这个是创建索引的主要原因
2.通过使用索引,可以查询的过程中,使用优化隐藏器,提高系统性能
索引的缺点:
1.时间方面:创建索引和维护索引要耗费时间,具体的,当对表中的数据进行增加,删除和修改的时候,索引也要动态维护,会降低增删改的执行效率
2.空间方面:索引需要占用物理内存
3.MySQL的索引分类
单例索引
1.普通索引:MySQL中的基本索引类型,没有什么限制,允许在定义索引的列中插入重复和空值,纯属为了查询更快 ALTER TABLE table_name ADD INDEX index_name(column)
2.唯一索引:索引列中的值必须是唯一的,但是允许空值 ALTER TABLE table_name ADD UNIQUE(column)
3.主键索引:是一种特殊的唯一索引,不允许有空值
复合索引
多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用,使用复合索引时遵循最左侧前缀集合 ALTER TABLE table_name ADD INDEX index_name(column1,column2,column3)
全文索引
解释:就是在一对文字中,通过某个关键字等,就能够到该字段所属的记录行
只有MyISAM引擎才能使用,只能在CHAR,VARCHAR,TEXT类型字段上使用全文索引
ALTER TABLE table_name ADD FULLTEXT(column)
空间索引
空间索引是对空间数据类型的字段建立索引
MySQL中的空间字段有四个,GEOMETTY,POINT,LINESTRING,POLYGON
4.索引失效
1.like以%开头的索引无效,但是like以%结尾,索引有效
2.or语句前后没有同时使用索引会失效,当且仅当or语句查询条件的前后均有索引生效
3.复合索引,使用的不是第一列索引的时候,索引失效,即最左侧匹配规则
4.数据类型出现隐式转换,比如varchar不加单引号的时候可能会自动转换成int类型,这个时候索引失效
5.在索引列上使用IS NULL或者 IS NOT NULL的时候,索引失效,因为索引是不索引空间的
6. 在索引字段上使用 NOT <> != 时候不会使用索引的,对于这样的处理只会进行全表扫描
7. 对索引字段进行计算操作,函数操作时不会使用索引
8. 当全表扫描速度比索引速度快的时候不会使用索引
16.描述一个一对多或者多对多的业务场景(最好举例多对多的情况),将表结构设计一下
比如:
学生表student:
id name
1001 张三
1002 张四
1003 王五
1004 赵六
课程表course:
id name
111 java
222 mysql
17.事务指的是什么,什么时候用到
一、什么是事务?
事务是指单个逻辑工作单元执行得一系列操作,要么都做,要么都不做,是不可分割的工作单位,是数据库环境中的的最小工作单元。
二、为什么需要事务?
事务包含了一组操作,这些操作可以是一条SQL语句、一组SQL语句或整个程序。如果其中一个操作不成功,这些操作都不会执行,前面执行的操作也会回滚原状态,用来保证数据的一致性和完整性。例如,就像银行转账,张三给李四转账,只有当张三的钱转走了,并且李四账户的钱收到了之后才会事务提交,否则事务会回滚到转账前的状态,保证数据的一致性,保证数据不会出错。
三、事务的四大特征:
1、原子性
整个事务要么成功提交要么全部失败回滚。
2、隔离性
一个事务在完成前对其他事务是不可见的,一个事务执行前就代表上一个事务一定结束了。
3、一致性
事务操作前后,数据表中的数据是不会发生变化的,直到成功提交前。
4、持久性
一旦事务提交则会永久保存在数据库当中。
18.Sql中的group by 是用来做什么的?举例说明
(1)语法:group by 字段
查询语句
select column_name(s) #字段名
[,聚合函数]
from table #表名
where #条件语句
group by column_name #字段名
说明:group by分组的字段(列名)可为多个字段,“[,聚合函数]”表示可选,分组函数group by一般与聚合函数一起使用。若不与聚合函数一起使用单纯查询是非数值列用group by有汇总取不同值的作用。
select column_name(s) #字段名
from table #表名
group by column_name #字段名
相当于
select distinct column_name(s) #字段名
from table #表名
(2)用法:用于分组,一般用于与聚合函数进行分组聚合(求和、统计等)。
2.实例
现有一个成绩表score,学号id,姓名name,性别sex,民族nation,班级class,语文Chinese,数学math,英语English。如下表所示。
(1)获取分组信息,取不同值。
例1:分组获取班级、性别信息。
select class,sex
from score
group by class,sex
相当于
select distinct class,sex
from score
结果如下图所示。
2)与聚合函数结合使用
例2:按班级性别分组获取语数英的成绩求和。
select class,sex,
sum(Chinese) as Chinese,
sum(math) as math,
sum(English) as English
from score
group by class,sex
19.Sql中的left join 是用来做什么的?举例说明
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录
20.java 中list 与 set 有什么区别
1. 区别:
- Set集合中的元素是无序的,且不允许重复;List集合中的元素是有序的,允许重复。
- Set集合通过元素的哈希码来保证元素的唯一性,因此Set集合的元素必须实现hashCode()和equals()方法;而List集合则完全依赖于元素的顺序。
- Set集合使用的实现类有HashSet、LinkedHashSet和TreeSet;List集合使用的实现类有ArrayList、LinkedList和Vector。
2. 子类的用法和说明:
- HashSet:使用哈希表实现,能够提供较快的插入、删除和查询速度,但不能保证元素的顺序。
- LinkedHashSet:使用哈希表和链表实现,在HashSet的基础上额外维护了一个链表,能够保证元素的插入顺序和遍历顺序一致。
- TreeSet:使用红黑树实现,能够对元素进行自然排序或指定排序方式排序,但插入、删除和查询速度相对较慢。
- ArrayList:使用动态数组实现,支持随机访问和快速插入、删除元素。
- LinkedList:使用双向链表实现,支持高效的插入、删除操作,但对于随机访问的性能较差。
- Vector:与ArrayList类似,但是Vector是线程安全的,支持同步操作,但性能较差。
总结:Set集合适用于需要保证元素唯一性且无序的场景,List集合适用于需要保留元素顺序且可以重复的场景。子类的选择则取决于具体的需求,如对效率要求较高时可选择HashSet或ArrayList,对有序性要求高时可选择LinkedHashSet或TreeSet。
21.java 中接口与抽象类有什么区别
abstract class 和interface有什么区别?
答:
1抽象类是一个特殊的类,特殊在,抽象类中可以包含没有方法体的方法(抽象方法)
2接口可以理解成一个特殊的抽象类,特殊在,接口里的都是抽象方法,没有普通方法
3接口会为方法自动拼接public abstract,还会为变量自动拼接public final static
4抽象类可以有构造方法–用来给子类创建对象,接口中没有构造方法
5抽象类和接口都不能实例化(创建对象)
6接口可继承接口,并可多继承接口,但类只能单继承
7抽象方法只能声明,不能实现,接口是设计的结果 ,抽象类是重构的结果
22.java中多态是什么?举例说明
首先,多态指同一个实体同时具有多种形式。它是面向对象程序设计(OOP)的一个重要特征。如果一个语言只支持类而不支持多态,只能说明它是基于对象的,而不是面向对象的。
另外,多态是出现在具有继承关系的两个类的对象之间,所以它不像方法重载(发生在一个类中)在编译期间发生(也就是确定下来),而是在运行期间发生(确定下来)。
1.一个父类类型的引用可以指向他任何一个子类的对象
2.[相同]类域的[不同]对象执行[同一]方法的时候会有[不同]的表现
有一个比较经典的多态实例:
有一个Animal类,它有Cat,和Dog两个子类,在Animal中有个say方法,当Cat调用这个方法的时候输出的是“小猫喵喵喵”,当Dog调用这个方法时,输出的是“小狗汪汪汪”,这就是Java多态的实现。
23.java中什么时候需要使用同步锁
synchronized与Lock的对比
Lock是显式锁(手动打开和关闭锁),synchronized是隐式锁,出了作用域自动释放
Lock只有代码块锁,synchronized有代码块锁和方法锁
使用Lock锁,JVM将花费较少的时间来调度线程,性能更好,并且提供了更多的子类,有良好的扩展性
24.解释SSH是什么,分别给予简要描述
SSH: Struts(表示层)+Spring(业务层)+Hibernate(持久层) Struts: Struts是一个表示层框架,主要作用是界面展示,接收请求,分发请求。 在MVC框架中,Struts属于VC层次,负责界面表现,负责MVC关系的分发。(View:沿用JSP,HTTP,Form,Tag,Resourse ;Controller:ActionServlet,struts-config.xml,Action) Hibernate: Hibernate是一个持久层框架,它只负责与关系数据库的操作。 Spring: Spring是一个业务层框架,是一个整合的框架,能够很好地黏合表示层与持久层。
25.简要说明Spring MVC
SpringMVC五大组件
前端控制器(DispatcherServlet)
处理器映射器(HandlerMapping)
处理器适配器(HandlerAdapter)
视图解析器(ViewReslover)
视图渲染(View)
SpringMVC执行原理
提示:DispatcherServlet的作用:接收请求,调用其它组件处理请求,响应结果,相当于转发器、中央处理器,是整个流程控制的中心
用户发送请求 至 前端控制器(DispatcherServlet);
前端控制器(DispatcherServlet)收到请求后调用处理器映射器(HandlerMapping),处理器映射器(HandlerMapping)找到具体的Controller(可以根据xml配置、注解进行查找),并将Controller返回给DispatcherServlet;
前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)。处理器适配器经过适配调用具体的Controller;(Controller–> service --> Dao --> 数据库)
Controller执行完成后返回ModelAndView,处理器适配器(HandlerAdapter)将controller执行的结果(ModelAndView)返回给前端控制器(DispatcherServlet);
提示:Model(模型数据,即Controller处理的结果,Map) View(逻辑视图名,即负责展示结果的JSP页面的名字)
.前端控制器(DispatcherServlet)将执行的结果(ModelAndView)传给视图解析器(ViewReslover)
视图解析器(ViewReslover)根据View(逻辑视图名)解析后返回具体JSP页面
前端控制器(DispatcherServlet)根据Model对View进行渲染(即将模型数据填充至视图中);(默认会存到request域中)
前端控制器(DispatcherServlet)将填充了数据的网页响应给用户。
其中整个过程中需要开发人员编写的部分有Controller、Service、Dao、View;
MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范
26.递归算法是什么?什么时候用得到?
简单地说,就是如果在函数中存在着调用函数本身的情况,这种现象就叫递归。
27.设计一个产品购物车订单系统的表结?
构,包括产品表和订单表,产品表包括产品ID、产品名称、价格等字段,订单表包括订单ID、产品ID、数量、总价格等字段。下面是一个简单的产品购物车订单系统的表结构设计:
产品表(Product table):
- 产品ID(Product ID):主键,唯一标识每个产品的ID
- 产品名称(Product Name):产品的名称
- 价格(Price):产品的价格
订单表(Order table):
- 订单ID(Order ID):主键,唯一标识每个订单的ID
- 产品ID(Product ID):外键,与产品表关联,表示订单中的产品
- 数量(Quantity):订单中该产品的数量
- 总价格(Total Price):订单中该产品的总价格
通过以上表结构设计,可以实现一个简单的产品购物车订单系统,用户可以向购物车中添加产品,生成订单并计算总价格。