Java开发工程师必会技术自检清单

Java基础概述(自检) 作为一名刚入门的初学者,应该具备的能力和知识。 阅读详情


0 前言

俗话说:“吾日三省吾身”,经常性地自检有助于查漏补缺,逐步提升技术水平。Java开发所要面对的技术多如牛毛,没有一份明确的清单很难去排查。为解决以上难题,我根据常用和实用两点原则,总结如下技术清单。
愿大家技术进步,与君共勉。


1 Java web方面

1.1 全局异常处理

主要注意的点是http响应码,这涉及到“锅由谁来背”。众所周知,500响应码是系统内部错误。很不幸的是,全局异常处理默认的响应码就是500。当然,锅能不背就不背。大胆的将ResponseStatus设成HttpStatus.OK之后,你会发现大部分请求都回归了200响应码。
当然,错误信息还是要传递出去的。通过在返回JSON添加returnCode字段,就可以将异常信息与正常信息区分出来。

核心代码如下所示:

/**
 * 跟定义顺序无关,只是优先处理具体异常
 * @author yiqiang
 * @date 2020/8/7 10:31
 */
@ControllerAdvice
@Slf4j
@ResponseBody
public class GlobalExceptionHandler {

    private static final String COMMON_EXCEPTION="COMMON EXCEPTION: ";

    private static final String SERIOUS_EXCEPTION="SERIOUS_EXCEPTION: ";

    private static final String UNKNOWN_EXCEPTION="UNKNOWN_EXCEPTION: ";

    @ExceptionHandler(value = {CommonException.class})
    @ResponseStatus(value = HttpStatus.OK)
    public String commonHandler(CommonException e) throws JsonProcessingException {
        log.error(e.getMessage());
        e.printStackTrace();
        return ReturnDTO.failToJson(COMMON_EXCEPTION + e.getMessage(),null);
    }

    @ExceptionHandler(value = {SeriousException.class})
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public String seriousHandler(SeriousException e) throws JsonProcessingException {
        log.error(e.getMessage());
        e.printStackTrace();
        return ReturnDTO.failToJson(SERIOUS_EXCEPTION + e.getMessage(),null);
    }

    @ExceptionHandler(value = {Exception.class})
    @ResponseStatus(value = HttpStatus.OK)
    public String unknownHandler(Exception e) throws JsonProcessingException {
        log.error(e.getMessage());
        e.printStackTrace();
        return ReturnDTO.failToJson(UNKNOWN_EXCEPTION + "PLEASE CONNECT TO MANAGER",null);
    }

}

个人强烈建议,不要将异常堆栈信息直接返回给前端,而应该返回自定义的“帮助信息”。毕竟,返回堆栈信息一方面不安全;另一方面,返回的信息对不是程序员的客户没有任何帮助。
具体做法也很简单:实现建立异常枚举类和自定义异常,直接抛出自定义异常即可。

1.2 拦截器写法

拦截器对于绝大多数Java工程师而言,也是必备技能。废话不多说,步骤如下。

  1. 继承HandlerInterceptor,并作为component传递给Spring容器
@Component
@Slf4j
public class PtzRoleInterceptor implements HandlerInterceptor{


    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        log.info("PtzRoleInterceptor 成功拦截 ==> [{}]",httpServletRequest.getRequestURL());
        String roleIds = httpServletRequest.getHeader("roleIds");
        log.info("roleIds {}",roleIds);
        if(roleIds==null){
            log.info("roleIds为空");
        }
        boolean role=true;
        if(!StringUtils.isEmpty(roleIds)){
            for (String roleId : roleIds.split(",")) {
                if (ConstantUtil.PTZ_CONTROLLER_ROLE_ID.equals(roleId)) {
                    role = false;
                }
            }
        }

        if(role){
            //信息返回
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.setContentType("text/html;charset=utf-8");
            try(PrintWriter writer = httpServletResponse.getWriter()){
                JSONObject jsonObject=new JSONObject();
                jsonObject.put("returnCode",1);
                jsonObject.put("returnMsg","权限不足.如有需要,请联系配置管理员");
                writer.print(JSONObject.toJSONString(jsonObject,true));
            }catch (Exception e){
                e.printStackTrace();
                log.error("出现异常"+e.getMessage());
            }
            log.info("PtzRoleInterceptor 校验失败 ==> [{}],当前用户角色ID为{}",httpServletRequest.getRequestURL(),roleIds);
            return false;
        }else {
            log.info("PtzRoleInterceptor 校验成功 ==> [{}],当前用户角色ID为{}",httpServletRequest.getRequestURL(),roleIds);
            return true;
        }

    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
  1. 对拦截器进行配置
/**
 * @author yiqiang
 * @date 2020/6/19 15:19
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Resource
    private PtzRoleInterceptor ptzRoleInterceptor;

    @Resource
    private PtzControlInterceptor ptzControlInterceptor;


    @Override
    public void addInterceptors(InterceptorRegistry interceptorRegistry) {
        interceptorRegistry.addInterceptor(ptzRoleInterceptor).
                addPathPatterns("/realTimeStream/lockChannel",
                        "/realTimeStream/ptzCtrl",
                        "/realTimeStream/showLockChannel",
                        "/realTimeStream/unlockChannel",
                        "/realTimeStream/seizeChannel");
        interceptorRegistry.addInterceptor(ptzControlInterceptor).
                addPathPatterns("/realTimeStream/ptzCtrl");
    }

}

1.3 自定义注解和切面写法

自定义注解类

import java.lang.annotation.*;

@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Timeout {
    long value() default 1000;
}

切面类的编写

/**
 * @author yiqiang
 * @date 2020/8/12 13:38
 */
@Aspect
@Slf4j
@Component
public class TimeoutAspect {

    @Pointcut(value = "@annotation(com.gosun.pcms.aop.Timeout)")
    public void pointCut() {
    }
    
    @Around(value = "pointCut()")
    public Object timeOut(ProceedingJoinPoint joinPoint) throws Exception {
        log.info("正在进入切面");
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        Timeout timeOut = method.getDeclaredAnnotation(Timeout.class);
        int i = 0;
        ExecutorService executor = Executors.newCachedThreadPool();
        Future future = executor.submit(() -> {
            log.info("正在执行");
            try {
                return joinPoint.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
                return ReturnDTO.fail("操作失败");
            }
        });
        long t = System.currentTimeMillis();
        while (true) {
            Thread.sleep(1000);
            log.info("第{}次执行", i++);
            if (System.currentTimeMillis() - t >= timeOut.value()) {
                return ReturnDTO.fail("超时,TimeOut:"+timeOut.value());
            }
            if (future.isDone()) {
                return future.get();
            }
        }
    }

}

1.4 线程池的使用

声明executor,然后使用executor的submit或者execute方法创建线程。前者针对callable接口,后者针对runable接口。

    ExecutorService executor = Executors.newCachedThreadPool();
    Future future = executor.submit(() -> {
        	//do something
    });
    if(future.isDone()){
    	log.info(future.get())
    }

1.5 跨域过滤器

偶尔会遇到跨域问题,只要在启动类添加如下配置即可

   private CorsConfiguration buildConfig() {
      CorsConfiguration corsConfiguration = new CorsConfiguration();
      corsConfiguration.addAllowedOrigin("*");
      corsConfiguration.addAllowedHeader("*");
      corsConfiguration.addAllowedMethod("*");
      return corsConfiguration;
   }

   @Bean
   public CorsFilter corsFilter() {
      UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
      source.registerCorsConfiguration("/**", buildConfig()); 
      return new CorsFilter(source);
    }

1.6 文件上传与下载

1.7 WebSocket基本使用

1.8 图片转Base64编码

1.9 JSON转化

1.10 XML转化

1.11 自定义Starter

2 消息中间件

2.1 Rabbit MQ

2.1.1 AMQP协议

2.1.2 消息100%投递

2.1.3 死信队列

2.2 Kafka

2.2.1 Kafka与Spring整合

2.2.2 Kafka配置详解

3 缓存中间件

3.1 本地缓存EhCache

3.2 分布式缓存Redis

3.3 缓存失效及解决方案

4 ES基础知识

4.1 ELK系统搭建

4.2 ES基本增删改查

5 数据库基础

5.1 主从复制

5.2 分库分表

5.3 SQL调优

6 JVM基础

7 前端基础

7.1 原生JS发送ajax

<script>
    var xmlHttp;
    if(window.XMLHttpRequest){
        xmlHttp = new XMLHttpRequest();
    }else{
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    request.open("GET", "http://localhost:8080/test",true);
    request.send(null);
    request.onreadystatechange = function() {
        if (request.readyState==4) {
            if (request.status==200) {
                var data = JSON.parse(request.responseText);
                if (data.success) {
                    document.getElementById("XXX").innerHTML = data.msg;
                } else {
                    document.getElementById("XXX").innerHTML = "出现错误:" + data.msg;
                }
            } else {
                alert("发生错误:" + request.status);
            }
        }
    }
</script>
深度解析:新华网安卓及鸿蒙开发工程师岗位要求与技术能力图谱 【移动开发工程师岗位技术能力解析】本文系统分析了新华网安卓/HarmonyOS开发岗位的技术要求,构建了包含6大维度的能力模型:1)Android原生开发(Java/Kotlin双语言、SDK核心组件);2)架构设计(MVVM模式、模块化开发);3)性能优化(内存泄漏、ANR问题定位);4)HarmonyOS开发(ArkTS语言、分布式能力);5)跨平台技术(Flutter/RN混合开发);6)安全合规(数据加密、GDPR规范)。 阅读详情

相关推荐

开发自测规范整理表格.xls

开发人员自测点及自测规范表格.xls

人手必备的产品自查表(建议收藏+打印)

产品经理在日常工作当中,由于其岗位的职责范围广,所需要具备的能力也较多,事情也相对较“杂”。往往在有限的脑容量当中,要完美地做好每一件事,是极其有难度的。不知道朋友们是否在产品工作当中有...

liudada8265的博客 586

测试清单模板

本资源是测试清单模板,方便整理测试发现的问题,记录BUG,方便修改和确认测试。

markdown中快速插入Emoji表情包语法速查表!!!,web前端服务端开发

本人分享一下这次字节跳动、美团、头条等大厂的面试真题涉及到的知识点,以及我个人的学习方法、学习路线等,当然也整理了一些学习文档资料出来是附赠给大家的。知识点涉及比较全面,包括但不限于前端基础,HTML,CSS,JavaScript,Vue,ES6,HTTP,浏览器,算法等等详细大厂面试题答案、学习笔记、学习视频等资料领取,点击资料领取直通车免费领取!既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

2301_79655473的博客 3834

一个java程序员必备的10项技能

一个java程序员必备的10项技能,一个java程序员需要什么样的技能,你知道吗?具备了什么技能才能具备实力去竞争?请看看这里面就全部知道了。帮助很大的。

java代码检测工具

基于java开发手册的java扫描插件,主要功能是扫描出java代码潜在的代码隐患,提升代码质量!

一名【合格】前端工程师的自检清单,含BATJM大厂

一个好的心态和一个坚持的心很重要,很多冲着高薪的人想学习前端,但是能学到最后的没有几个,遇到困难就放弃了,这种人到处都是,就是因为有的东西难,所以他的回报才很大,我们评判一个前端开发者是什么水平,就是他解决问题的能力有多强。分享一些简单的前端面试题以及学习路线给大家,狂戳这里即可免费领取家的负担。**[外链图片转存中…(img-dO2EqydG-1712257456613)][外链图片转存中…(img-SOdlQ9IB-1712257456614)]

2401_84091468的博客 1198

Java本地AI推理初体验:Jlama+LangChain4j构建离线问答系统

Jlama 是专为 Java 生态设计的现代化大型语言模型(LLM)推理引擎,旨在让开发者无需依赖外部服务即可直接在 Java 应用中运行本地化模型推理。本文将结合Jlama + langchain4j 实现一个本地可运行的简单问答Demo。

2501_92589102的博客 408

程序员开发手册_一名出色的后端工程师的自检手册

点击上方蓝字设为星标每周一、三、五上午 8:30 准时推送下面开始今天的学习~如今进入计算机行业的人越来越多,计算机行业有入门简单,上手容易的特点。然而这也导致部分工作了几年的后端工程师的技术水平仍然停留在对数据库「增删改查」的阶段。实际上如今的市场上会增删改查的后端程序员不再稀缺,一名优秀的工程师仍然需要不断提升自己。程序员是一个需要终身学习的职业,计算机行业最重要的能力莫过于学习能力...

weixin_39621060的博客 358

微信小程序获取用户手机号全流程实战(附完整代码)

本文详细介绍了微信小程序获取用户手机号的全流程实战,包括前端授权、后端解密及安全合规要点。通过传统授权按钮和新版手机号快速验证组件两种方案,帮助开发者高效实现功能,并附完整代码示例。重点解析了微信小程序接口的使用技巧和常见问题解决方案,确保数据安全与用户体验。

weixin_29280219的博客 569

ABAQUS二次开发中创建SET

在ABAQUS中创建加载、边界条件时,需要使用set,创建set时需要使用对象集合对象中的Set函数,这个函数需要提供加入对象集合的列表,但这个对象列表好像并不能自行创建,只能通过ABAQUS各类对象集合中的findAt、getSequenceFromMask、getByBoundingSphere、getByBoundingCylinder或getByBoundingSphere函数得到,但这几个函数在直接使用PYTHON编程时都不太好用。这个函数返回一个字典,如下所示。

hohoyu的专栏 2485

前端工程师自检清单1——js基础篇

一、Javascript 变量和类型: 1.JavaScript规定了几种语言类型 规定了八种语言类型:Null,Number,Nudedined,String,Boolean,Object,Symbol,BigInt 基本类型: Undefined , Number , String , Boolean , Null , Symbol (es6) , BigInt(es10) 引用类型: Object 2.JavaScript对象的底层数据结构是什么 JavaScript使用的是 堆(Heap) 和

weixin_47192676的博客 646

升降机SEW MOVIDRIVE变频器设置

选择PO1 第2,3,9,13 位,点击“SendPA”Start reference,编码器反馈值为0(PI2/3 Actual position=0)提示:传送参考位置前请断开变频器安全24V电源,否则会弹出禁止修改提示框;提示:做这一步时,如果出现电机不能转动,或产生报警不能通过编码器匹配。下载配置的参数,提示:下载参数需要断开变频器的安全24V电源。编码器匹配通过后点击下一步,进入下图画面传送参考位置。1电机不能转动:a可能是由于变频器的安全24V未给。点击2.SEW总线扩展定位,定位块设置。

xdpcxq的专栏 5399

Golang开发工程师简历(精选3篇)

随着Go语言在各个领域的广泛应用,一份出色的Golang开发工程师简历成为了求职者展示自己技能和经验的关键。

Huanzhucv的博客 2807

Stm32L0 STM32CUBE中UART和使用LPUART1以及串口不进中断问题解决

/* 开启串口1中断 */ LL_USART_EnableIT_RXNE(LPUART1); /* 开启串口2中断 */ LL_USART_EnableIT_RXNE(USART2);

シ❤゛甜虾的个人博客 7687

智能电网中的智能调度与优化算法研究

本文研究智能电网中的智能调度与优化算法,旨在提高电网运行的效率与可靠性,减少能源浪费和设备故障的风险。在智能电网日益复杂化的背景下,传统的调度方法已难以满足高效、稳定的运行要求,因此亟需借助先进的优化算法对电网进行智能调度。本文第一深入分析智能电网调度中的关键问题与挑战,探讨优化算法在智能电网中的应用现状,并分析常见的优化算法,如遗传算法、粒子群算法和模拟退火算法。随后,本文构建智能电网的调度优化数学模型,并对电网负荷、发电模型及约束条件进行详细建模。在算法部分,本文提出改进的粒子群算法和遗传算法,并结合M

weixin_44553616的博客 1893

4.28 前端开发日报

给「前端开发博客」加星标,每天打卡学习长按二维码即可识别“进入网页”查看哟~1、一名【合格】前端工程师的自检清单前端开发是一个非常特殊的行业,它的历史实际上不是很长,但是知识之繁杂,...

前端开发博客 278

计算机实战分享3:森林火灾预测分析可视化机器学习预测-完整数据代码-可直接运行

计算机实战分享3:森林火灾预测分析可视化机器学习预测-完整数据代码-可直接运行

604

java程序员技术规划!

认证体系:Oracle Certified Professional(OCP)、AWS/Azure认证。Spring全家桶:Spring Boot自动配置原理、Spring Cloud微服务设计模式。工具链:JProfiler(性能分析)、JUnit5(测试)、Liquibase(数据库迁移)新特性应用:Records、Pattern Matching、虚拟线程(Loom项目预览)技术雷达:定期评估新技术(如Quarkus VS Spring Native)

2401_83384536的博客 567

Oracle EBS R12.2.X JSP部署、编译和配置相关操作。

系统环境 RDBMS : 12.1.0.2.0 Oracle Applications : 12.2.6 背景 在某项目上,需要开发JSP相关程序,比如单点登陆、打印二维条码。当前把JSP部署编译以后,访问提示错误:Requested resource or page is not allowed in this site, 通过查SR发现Oracle EBS R12.2.X版本对客制化JSP进行权限控限,需要设置某些配置文件。 实例操作步骤 上传JSP文件 通常上传到$OA_HTML目录或其子目

陈显平的专栏-Oracle EBS 1913

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

MES工程师新手,该怎么学习?学习哪些技术?

一、明确两个学习大方向 1.学习生产流程,MES各功能模块的业务逻辑。 2.学习开发技术。 二、无从下手学习MES的主要原因 2.1、相对封闭的工业软件 就像前面提到了,关于MES,对于一般人而言,互联网已经不能给你提供各家MES的比较体系和齐全的入门和进阶资料,不像你学习PLC,搞自动化,你几乎可以通过互联网免费找到90%-95%的资料(这个需要看个人搜索能力的),可能大家也发现了,你能通过互联网找到的相关资料,几乎都是千篇一律的所谓解决方案,功能介绍,但是就像你学习别的软件一样,给你讲了10..

提供C#相关开发 、云计算、运维测试、网络安全相关技术分享与服务,有意向可联系。 1万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

移动端开发工程师,2024最新京东Android面试题目

自我介绍一下,小编13年北京科技大学毕业,曾经在字节跳动待过,也去过vivo、小米等大厂,18年进入华为一直到现在。小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担,能在岗位上再创辉煌,步步高升!!。

2401_84904894的博客 736

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Wing 语言前向声明机制解析:从 forward_decl 测试到编译器符号解析的完整验证

在 Wing 语言中,"先声明后使用"并不是绝对的规则:只要符号定义在**外层作用域**,无论它出现在当前语句之前还是之后,都可以被安全引用。本篇以 [tools/hangar/__snapshots__/test_corpus/valid/forward_decl.test.w_test_sim.md](https://link.gitcode.com/i/2adade9af4c84c7e389

gitblog_01040的博客 192

技术人格化:用‘不可能’验证构建工程师信用体系

在工程实践中,‘技术栈罗列’正日益失效,而基于真实问题解决过程的‘技术人格化’表达成为建立专业信任的新范式。其核心在于将隐性经验显性化,通过可测量的约束条件、可复现的拆解路径和可验证的结果数据,把抽象能力转化为可信信用锚点。这一方法深度融合了问题定义能力与工程落地思维,广泛适用于招聘筛选、客户提案、跨团队协作等高频场景。尤其在边缘AI、IoT集成、遗留系统改造等资源受限领域,‘Nothing Impossible’不是口号,而是以压力测试、失效说明书、最小可行证伪集为支撑的方法论实践——它让工程师从执行者跃

didi9310的博客 407

【AI应用开发工程师】-分享2026年转型AI应用开发工程师经验

AI转型修罗场:2026年生存指南 2025-2026年见证了AI岗位的剧变:从会调API的"咒语师"升级为需掌握RAG、智能体架构等复杂技能的"AI架构师"。企业需求从"有AI就行"变为要求稳定创造价值,导致初级岗位消失、同质化竞争加剧。不同背景的转型者面临不同挑战:后台老兵需结合工程优势,前端开发者要深入AI工作流,应届生则急需实战项目。2026年突围策略包括:构建T型技能组合,打造有业务价值的项目作品集,以及从被动学习转向主动创造。未来趋势指

【javatoai17819112191】→Java && python && AI Agent工程师 1183
上一篇: Docker容器启动时报错:container init caused “write /proc/self/attr/keycreate: permission denied““: unknown
下一篇: HttpServletResponse通过setContentType设置响应头失败,以及解决办法
一步一结
博客等级 码龄7年 50粉丝 65原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值