当前位置:   article > 正文

牛客网社区项目面试题【面试项目】_牛客论坛项目面试题

牛客论坛项目面试题

项目面试题

前言

写作于
2022-11-12 13:29:56

私密发布于
2022-11-20 16:32:13

公开发布于
2024-5-13 13:14:51

推荐

Java牛客网社区项目——知识点&面试题
Java基于SpringBoot的牛客网社区项目实现详解(上)
Java基于SpringBoot的牛客网社区项目实现详解(下)

简历

在这里插入图片描述

在这里插入图片描述

权限模块

Interceptor

package com.jsss.community.controller.interceptor;

@Component
public class AlphaInterceptor implements HandlerInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(AlphaInterceptor.class);

    // 在Controller之前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.debug("preHandle: " + handler.toString());
        return true;
    }

    // 在Controller之后执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        logger.debug("postHandle: " + handler.toString());
    }

    // 在TemplateEngine之后执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        logger.debug("afterCompletion: " + handler.toString());
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

作用
拦截器
对于未登录的用户,禁止一些资源的访问,必须在登录之后才可以访问
比如:未登录之前,主页头部显示
首页、登录、注册
登录之后,显示
首页、消息、头像(下拉-用户信息)

授权的Spring Security
怎么用

权限管理的角色,分为
普通用户
通用功能:登录、发帖、私信、点赞
版主:置顶、加精
管理员:删帖、数据统计

核心模块

Advice
ExceptionAdvice
用来处理Controller层的异常

package com.jsss.community.controller.advice;

import com.jsss.community.util.CommunityUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@ControllerAdvice(annotations = Controller.class)
public class ExceptionAdvice {

    private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class);

    @ExceptionHandler({Exception.class})
    public void handleException(Exception e, HttpServletRequest request, HttpServletResponse response) throws IOException {
        logger.error("服务器发生异常: " + e.getMessage());
        for (StackTraceElement element : e.getStackTrace()) {
            logger.error(element.toString());
        }

        String xRequestedWith = request.getHeader("x-requested-with");
        if ("XMLHttpRequest".equals(xRequestedWith)) {
            response.setContentType("application/plain;charset=utf-8");
            PrintWriter writer = response.getWriter();
            writer.write(CommunityUtil.getJSONString(1, "服务器异常!"));
        } else {
            response.sendRedirect(request.getContextPath() + "/error");
        }
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

Aop aspectj
处理业务层的日志
ServiceLogAspect

package com.jsss.community.aspect;

//@Component
//@Aspect
public class ServiceLogAspect {

    private static final Logger logger = LoggerFactory.getLogger(ServiceLogAspect.class);

    //任意返回值 service包下任意类 任意方法(任意参数)
    @Pointcut("execution(* com.jsss.community.service.*.*(..))")
    public void pointcut() {

    }

    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        // 用户[1.2.3.4],在[xxx],访问了[com.jsss.community.service.xxx()].
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            return;
        }
        HttpServletRequest request = attributes.getRequest();
        String ip = request.getRemoteHost();
        String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        String target = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        logger.info(String.format("用户[%s],在[%s],访问了[%s].", ip, now, target));
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

Translation
事务

敏感词过滤
前缀树

性能模块
Redis

点赞,关注

统计数据
uv:Hyperloglog 存储ip

dau:bitmap 位图

缓存

搜索模块:elasticsearch
倒排索引

通知模块:kafka
系统通知:消息队列
模式:生产者消费者

其他模块:Quartz、Caffeine
排行、上传:Quartz定时任务
服务器缓存:Caffeine分布式局限性
缓存到redis中

问题

Java牛客网社区项目——知识点&面试题

第一季:导航【Java面试题】

第二季:导航【Java面试题】

框架

Spring Boot

Spring Boot核心作用

  • 起步依赖、自动配置、端点监控
Spring入门
  • Spring Framework. Spring Core
  • loC、AOP. Spring Data Access
  • Transactions、Spring MyBatis. Web Servlet
  • Spring MVC- lntegration
  • Email、Scheduling、AMQP、Security
Spring loC
  • Inversion of Control
  • 控制反转,是一种面向对象编程的设计思想。- Dependency lnjection
  • 依赖注入,是loC思想的实现方式。. loC Container
  • loC容器,是实现依赖注入的关键,本质上是一个工厂。
MyBatis入门

MyBatis

  • 核心组件
  • sqlSessionFactory:用于创建SqlSession的工厂类。- SqlSession: MyBatis的核心组件,用于向数据库执行SQL。
  • 主配置文件:XML配置文件,可以对MyBatis的底层行为做出详细的配置。- Mapper接口:就是DAO接口,在MyBatis中习惯性的称之为Mapper。
  • Mapper映射器:用于编写SQL,并将SQL和实体类映射的组件,采用XML、注解均可实现。。示例
  • 使用MyBatis对用户表进行CRUD操作。

功能模块

权限模块

发送邮件

  • 邮箱设置:启动客户端SMTP服务

  • Spring Email

导入jar包

 		 <!-- spring 邮箱       -->
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mail -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
            <version>2.7.4</version>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

邮箱参数配置

# MailProperties
spring.mail.host=smtp.qq.com
spring.mail.port=465
spring.mail.username=3063494684@qq.com
spring.mail.password=vtzhmfetkpeldddg
spring.mail.protocol=smtps
spring.mail.properties.mail.smtp.ssl.enable=true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 模板引擎

使用Thymeleaf 发送HTML邮件

MailClient JavaMailSender

注册功能

  • 访问注册页面
    • 点击顶部区域内的链接,打开注册页面。
  • 提交注册数据
    • 通过表单提交数据。
    • 服务端验证账号是否已存在、邮箱是否已注册。
    • 服务端发送激活邮件。
  • 激活注册账号
    • 点击邮件中的链接,访问服务端的激活服务。

会话管理

cookie
http是无状态的

session
数据存放在服务端更 安全

规避分布式session的问题

用redis存储

生成验证码

Kaptcha

  • 导入jar包
		 <!-- 验证码       -->
        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 编写Kaptcha配置类
  • 生成随机字符、生成图片
@Configuration
public class KaptchaConfig {

    @Bean
    public Producer kaptchaProducer() {
        Properties properties = new Properties();
        properties.setProperty("kaptcha.image.width", "100");
        properties.setProperty("kaptcha.image.height", "40");
        properties.setProperty("kaptcha.textproducer.font.size", "32");
        properties.setProperty("kaptcha.textproducer.font.color", "0,0,0");
        properties.setProperty("kaptcha.textproducer.char.string", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYAZ");
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.NoNoise");

        DefaultKaptcha kaptcha = new DefaultKaptcha();
        Config config = new Config(properties);
        kaptcha.setConfig(config);
        return kaptcha;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

登录、退出

  • 访问登录页面
    -点击顶部区域内的链接,打开登录页面。·登录
    -验证账号、密码、验证码。
    -成功时,生成登录凭证,发放给客户端。-失败时,跳转回登录页。
  • 退出
    -将登录凭证修改为失效状态。
    -跳转至网站首页。

显示登录信息

  • 拦截器示例
    -定义拦截器,实现Handlerlnterceptor-配置拦截器,为它指定拦截、排除的路径
  • 拦截器应用
    -在请求开始时查询登录用户
    -在本次请求中持有用户数据
    -在模板视图上显示用户数据
    -在请求结束时清理用户数据
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号