一. 面试题及剖析
1. 今日面试题
2. 题目剖析
今天 壹哥 给大家讲解的这个题目,与之前的题目有些不同。那么哪里有不同呢?我们仔细回想一下之前的面试题,你会发现之前很多题目都是以记忆、理解、底层探究为主,但今天的题目其实是以提供解决问题的思路和方案为主。
我们在面试时,可能会遇到各种各样的面试官,这些面试官都有自己的风格,他们提问的角度也不同。有的人就喜欢追着问知识点,有的就喜欢追着问项目细节,还有的人喜欢追着问解决方案。我们今天的题目,就属于在考察求职者解决问题的思路、思维,看看求职者是否有解决问题的开拓性想法,其实这个能力对于我们做项目来说更为重要一些。所以有挺多面试官多会给求职者抛出类似于这样的问题:你遇到过xxx情况吗?这种情况你是怎么解决的?如果你遇到xxx问题,你该怎么解决,你有哪些思路?......
对于这类题目,面试官一方面是在考察我们是否经历过这种问题,从而可以判断出我们的经验水平;另一方面,其实更多的是在看我们的思维逻辑能力。这种题目的答案,其实都不是唯一的,也并没有固定的标准答案,主要看我们敢不敢想,能不能想,有没有想!有些求职者,遇到类似的这种问题,觉得自己确实没有遇到过这种情况,然后就想也不想,直接给人家面试官来一句:我没遇到过,我不知道.......
如果你这样回答问题,你觉得面试官会怎么想?会怎么判定你?某种情况你可能没有遇到过,但你一定要有自己的思路和解决方案,这个解决方案未必就正确,但你得给出自己的想法!要不然以后真把你招到项目组里来了,遇到个难题,你就跟老大说我以前没碰到过这情况,我弄不了,那人家公司花这么多钱招你干嘛来的啊?!是为了听你说不知道的吗?
二. 参考答案
1. 需求背景
行转列、列转行这样的需求,一般是在做表格效果时会遇到,常见的就是Excel报表统计、Excel文件的导入导出等。
对于行转列或者列转行,我们的实现方案,其实可以从3个维度来进行考虑实现:
本例中会采用第2种实现方案,即采用Java后端代码,对查询出的数据集合进行转换。
2. 转换前的效果
这里我先用LayUI编写了一个分页效果页面,下面是未进行 行转列之前的效果图:
从图中可以看出,id、姓名、地址、性别等数据在一行中展示,而此时前端从后端返回的JSON数据格式如下所示:
{
"code": 0,
"msg": "success",
"count": 14,
"data": [{
"id": 3,
"username": "壹壹哥",
"address": "上海",
"sex": "男"
}, {
"id": 4,
"username": "壹哥",
"address": "上海",
"sex": "男"
},......]
}
这是用JSON格式化工具进行格式化后的效果。
从中可以看出,id、username、address、sex等字段同时被封装在一个json对象中。那么接下来,我们就需要对这个表格中的数据进行 行转列的变换,那么该如何实现呢?壹哥 把核心代码提供给大家了,大家可以参考下面的内容。
3. 转换代码
以下是实现行转列的关键代码,大家可以参考实现。
3.1 User类
为了方便封装数据,我这里会定义一个User类,后面进行 行转列时会对该类进行操作。
@Data
@ToString
public class User {
private Integer id;
private String username;
private String address;
private String sex;
}
3.2 行转列核心类
我把行转列的操作,定义在了service层,各位可以按照根据自己的需求,把行转列的核心代码进行自定义调用。
@Service
public class UserServiceImpl implements UserService {
@Autowired
private com.yyg.boot.mapper.UserMapper userMapper;
//本案例中用到了PageHeper分页类,它与行列转换没有关系,只是为了实现分页效果,你完全可以去掉PageHelper的内容。
@Override
public PageInfo<User> findUsers(Integer pageNum, Integer pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<User> list = userMapper.findUsers();
//进行行转列操作,调用封装的行转列代码
List convertList = convert(User.class, list);
return new PageInfo<User>(convertList);
}
/**
* 封装行转列的实现方法,主要是利用了反射,对集合中JavaBean的字段进行取值
*/
public <T> List convert(Class<T> clazz, List<T> list) {
//获取字节码中的所有字段
Field[] fields = clazz.getDeclaredFields();
//创建一个空的List集合,在该集合中又嵌套了一个List集合
List<List> result = new ArrayList<>(fields.length);
for (int i = 0; i < fields.length; i++) {
//添加若干个空的List集合
result.add(new ArrayList());
}
for (T t : list) {
for (int i = 0; i < fields.length; i++) {
//取出每个List集合
List l = result.get(i);
Field field = fields[i];
field.setAccessible(true);
try {
//将字段中的数据,添加到集合中
l.add(field.get(t));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
return result;
}
}
4. 转换后的效果
当我们转换后,此时得到的JSON数据格式如下:
{"code":0,"msg":"success","count":4,
"data":[[3,4,5,7,9,11,14,15,16,18],
["壹壹哥","壹哥","一一哥","一一哥","一一哥","一一哥","一一哥","一一哥","一一哥22","一一哥22"],
["上海","上海","上海","上海","上海","上海","上海","上海","上海","上海"],
["男","男","男","男","男","男","男","男","男","男"]]}
利用JSON格式化工具对以上JSON进行格式化,得到的效果如下图所示:
这时我们会发现,此时JSON中的data数组,内部的数据与之前的数据完全不同了,前端只需要根据新的JSON数组进行页面渲染就可以了。
三. 结语
另外对于列转行,请参考我的代码,进行逆向处理。
今天的题目,其实答案并不唯一,壹哥 在这里只能给大家提供一些参考实现,各位可能会有更好的解决思路,就算是抛砖引玉吧,如果你有更好的解决思路,请在评论区留言给我哦。