JAVA|后端编码规范

news2025/5/24 0:11:14

目录

零、引言

一、基础

二、集合

三、并发

四、日志

五、安全


零、引言

规范等级:

  • 【强制】:强制遵守,来源于线上历史故障,将通过工具进行检查。
  • 【推荐】:推荐遵守,来源于日常代码审查、开发人员反馈和行业经验。

一、基础

序号

等级

规范

示例  

说明

1

强制

在POJO类中定义布尔类型成员变量时,禁止用is作变量名前缀。

反例:                                                                                                                                          

private boolean isDeleted;

// Getter方法:IDEA生成,与变量同名。

public boolean isDeleted() {

    return isDeleted;

}

// Setter方法:IDEA生成

public void setDeleted(boolean deleted) {

    isDeleted = deleted;

}

is作变量名前缀的布尔型成员变量,在一些IDE(如:IDEA)中,默认生成的getter方法与变量名相同,导致部分框架(如:Jackson、Fastjson)在反向解析时会引发“找不到指定成员变量名”的错误。
2

强制

在对象之间做相等比较时,应当使用Objects工具类(java.util.Objects)的equals方法。

正例:

String versionNo = "6.6.1";

// 如param为null,不会出现异常。

Objects.equals(param, versionNo);

反例:

String versionNo = "6.6.1";

// 如param为null,会出现异常。

param.equals(versionNo);

当对象为null时,直接调用equals会出现空指针异常。

注意:Objects的equals方法内部会利用参数对象的equals方法进行比较,对数组、集合之类的对象并不会做内部元素的一一比较。

3

强制

在BigDecimal之间做等值比较时,禁止使用equals方法。

正例:

// 商品原价格

BigDecimal skuPrice = new BigDecimal("120.00");

// 商品优惠后价格

BigDecimal skuPromoPrice = new BigDecimal("120.0");

// 使用compareTo做比较,不会比较精度。

if (skuPrice.compareTo(skuPromoPrice) == 0) { // true

    // ...

}

反例:

// 商品原价格

BigDecimal skuPrice = new BigDecimal("120.00");

// 商品优惠后价格

BigDecimal skuPromoPrice = new BigDecimal("120.0");

// 使用equals做比较,会比较精度。

if (skuPrice.equals(skuPromoPrice)) { // false

    // ...

}

BigDecimal的equals方法会比较精度,如1.0与1.00比较的结果为false,推荐使用其

compareTo方法做比较。

4强制在浮点数之间做等值比较时,基本类型禁止使用==,包装类型禁止使用equals。

正例:

// 下方减法运算是为了故意引起浮点误差

// 时段一的单价:充电站单价 - 优惠价

float timePrice1 = 1.0F - 0.9F;

// 时段二的单价:充电站单价 - 优惠价

float timePrice2 = 0.9F - 0.8F;

// 工具类推荐:org.apache.commons.lang3.math.NumberUtils

// 将浮点数转为BigDecimal并指定保留位数和取舍方式

BigDecimal decimalTimePrice1 = NumberUtils.toScaledBigDecimal(timePrice1, 2, RoundingMode.HALF_UP);

BigDecimal decimalTimePrice2 = NumberUtils.toScaledBigDecimal(timePrice2, 2, RoundingMode.HALF_UP);

if (decimalTimePrice1.compareTo(decimalTimePrice2) == 0) { // true

    // ...

}

反例:

// 下方减法运算是为了故意引起浮点误差

// 时段一的单价:充电站单价 - 优惠价

float timePrice1 = 1.0F - 0.9F;

// 时段二的单价:充电站单价 - 优惠价

float timePrice2 = 0.9F - 0.8F;

//  可能存在浮点误差,等式不成立。

if (timePrice1 == timePrice2) { // false

    // ...

}

反例:

// 下方减法运算是为了故意引起浮点误差

// 时段一的单价:充电站单价 - 优惠价

Float timePrice1 = 1.0F - 0.9F;

// 时段二的单价:充电站单价 - 优惠价

Float timePrice2 = 0.9F - 0.8F;

// 可能存在浮点误差,等式不成立。

if (timePrice1.equals(timePrice2)) { // false

    // ...

}

浮点数先转成BigDecimal,再用compareTo方法做比较,以避免精度问题影响结果。

浮点数采用“尾数+阶码”的编码方式,类似于科学计数法的“有效数字+指数”的表示方式。二进制无法精确表示大部分的十进制小数。

5

强制

将浮点数转换为BigDecimal 时,禁止直接使用构造方法。

正例:

// 商品SKU单价

double skuPrice = 0.1D;

// 工具类推荐:org.apache.commons.lang3.math.NumberUtils

// 精度不影响,仍然是0.1。

BigDecimal decimalSkuPrice = NumberUtils.createBigDecimal(Double.toString(skuPrice));

反例:

// 商品SKU单价

double skuPrice = 0.1D;

// 精度受影响,可能是0.1000000000000000055511151231257827021181583404541015625。

BigDecimal decimalSkuPrice = new BigDecimal(skuPrice);

BigDecimal的浮点数构造方法存在精度损失风险,在精确计算或值比较的场景中会导致业务逻辑异常。

注意:和上一条的正例不同的是,前者在经过浮点计算后已经形成了误差,在转换时用toScaledBigDecimal方法限定了精度。在此处,是为了避免因直接利用浮点数构造而导致的误差。

6强制在空指针异常易发的场景中,应当对对象做null判断。

正例:

@Resource

private UserService userService;

public String queryCityName(String userId) {

    User userObj = userService.queryUserInfo(userId);

    Optional<User> userData = Optional.ofNullable(userObj);

    Optional<UserAddress> userAddress = userData.map(User::getUserAddress);

    // 如用户地址为null,不会空指针异常。

    Optional<String> optionalCityName = userAddress.map(UserAddress::getCiyName);

    // null时返回默认值

    String cityName = optionalCityName.orElse(DEFAULT_CITY);

    return cityName;

}  

反例:

@Resource

private UserService userService;

public String queryCityName(String userId) {

    User userObj = userService.queryUserInfo(userId);

    // 如用户地址为null,会空指针异常。

    String cityName = userObj.getUserAddress().getCiyName();

    return cityName;

}

在对象未判断null的情况下直接引用,容易发生空指针异常,推荐用Optional类更优雅的处理null对象。

一些空指针异常(NPE)易发的场景:

  1. 返回类型为基本数据类型,return包装数据类型的对象时,自动拆箱有可能产生NPE。
  2. 数据库的查询结果可能为null
  3. 集合里的元素即使isNotEmpty,取出的数据元素也可能为null。
  4. 远程调用返回对象时,一律要求进行空指针判断,防止NPE。
  5. 对于Session中获取的数据,建议进行NPE检查,避免空指针。
  6. 级联调用obj.getA().getB().getC(),一连串调用,易产生NPE。

7

强制

在日期格式化时,应当使用DateUtils工具类

正例

Calendar calendar = Calendar.getInstance();

// 日期是2023-12-31

calendar.set(20231131);

// strDateTime:2023-12-31

String strDateTime = DateUtils.datesToString(calendar.getTime());

反例

Calendar calendar = Calendar.getInstance();

// 日期是2023-12-31

calendar.set(20231131);

// 误用了大写Y格式化年份

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-dd");

// strDateTime:2024-12-31

String strDateTime = simpleDateFormat.format(calendar.getTime());

DateUtils包装了常用的日期格式,避免了手动格式化时的误用风险,如:年份格式化误书写成YYYY,如本周存在跨年的情况,返回的就是下一年。

8强制POJO类属性,禁止使用基本数据类型。

正例

@Resource

private UserRepository userRepository;

public Integer queryUserId(String phone) {

    // getUserIdByPhone返回的是Integer类型,当返回null时,不会出现空指针异常。

    Integer userId = userRepository.getUserIdByPhone(phone);

    // 可以做防御性校验,以避免直接空指针

    if(userId != null){

        // …

    }

    // …

}

反例:

@Resource

private UserRepository userRepository;

public int queryUserId(String phone) {

    //  getUserIdByPhone返回的是Integer类型,当返回null时,会出现空指针异常。

    int userId = userRepository.getUserIdByPhone(phone);

    // …

}

POJO类属性使用包装数据类型有如下优点:

  1. 若值为null时,能显式的提醒使用者做相应的处理,而不是使用基本数据类型的默认值。
  2. 避免对象之间的自动拆装箱时出现NPE。

二、集合

序号

等级

规范

示例

说明

1

强制

在需要对List的subList方法返回结果进行遍历、增加、删除元素时,禁止直接变更原List中的元素。

反例:

List<String> cityList = new ArrayList<>();

cityList.add("北京");

cityList.add("上海");

cityList.add("广州");

List<String> citySubList = cityList.subList(01);

// subList之后变更原List

cityList.add("深圳");

// 出现ConcurrentModificationException异常

for (int i = 0; i < citySubList.size(); i++) {

    // ...

}

List的subList方法返回的是一个List的内部类对象,它是List的一个视图,对原List所有的操作都会反映到这个对象上。

同时,对原List进行元素的增加或删除,会被计数(modCount,结构变更次数),此数值和原subList时记录的数值(expectedModCount)不一致,会引发ConcurrentModification

Exception异常。

2强制

对集合进行for循环时,禁止在循环体内用remove/add方法。

正例:

List<String> cityList = new ArrayList<>();

cityList.add("北京");

cityList.add("上海");

cityList.add("广州");

Iterator<String> iterator = cityList.iterator();

while (iterator.hasNext()) {

    String city = iterator.next();

    // 工具类推荐:org.apache.commons.lang3.StringUtils

    if (StringUtils.equals("广州", city)) {

        iterator.remove();

    }

}

反例:

List<String> cityList = new ArrayList<>();

cityList.add("北京");

cityList.add("上海");

cityList.add("广州");

// 出现ConcurrentModificationException异常

for (String city : cityList) {

    // 工具类推荐:org.apache.commons.lang3.StringUtils

    if (StringUtils.equals("广州", city)) {

        cityList.remove(city);

    }

}

若在for循环体内对集合元素进行remove/add操作,可能导致异常,建议使用iterator方式处理。

三、并发

序号

等级

规范

示例

说明

1

强制

动态线程池只允许使用通义管理平台定义的(比如Poseidon),禁止自行创建。

正例:

// poseidonThreadPool在Poseidon管理平台已创建

@Resource(name = "poseidonThreadPool")

private ThreadPoolExecutor poseidonThreadPool;

CompletableFuture.supplyAsync(() -> {

    // ...

}, poseidonThreadPool);

反例:

// 自建线程池,未接入Poseidon。

ThreadPoolExecutor customThreadPool = new ThreadPoolExecutor(corePoolSize,

                    maximumPoolSize,

                    keepAliveTime,

                    unit,

                    workQueue,

                    new ThreadPoolExecutor.AbortPolicy());

CompletableFuture.supplyAsync(() -> {

    // ...

}, customThreadPool);

通过Poseidon创建的线程池将能较好的进行管理和监控:

  1. 支持通过Poseidon动态修改线上线程池参数(线程数量、队列长度、拒绝策略),无需重启服务即可生效。
  2. CAT平台能对线程池状态进行监控和告警。
2强制

在使用线程池时,禁止将拒绝策略设置为DiscardPolicy。

反例:

// poseidonThreadPool在Poseidon管理平台已创建,且配置了DiscardPolicy拒绝策略。

@Resource(name = "poseidonThreadPool")

private ThreadPoolExecutor poseidonThreadPool;

public void process(){

    // ...

    // 队列满且已达到最大线程数后,任务会被自动抛弃。

    Future<String> resultFuture = poseidonThreadPool.submit(task);

    // ...

}

若配置了DiscardPolicy,当线程池队列排满且已达到了最大线程数后,新增任务会被直接丢弃,无任何提示,并且在结合future.get()运行时,存在阻塞的风险。

3强制

父子任务禁止使用同一个线程池。

反例:

class OrderManager {

    // Poseidon配置的线程池

    @Resource(name = "poseidonThreadPool"

    private ThreadPoolExecutor poseidonThreadPool;

    @Autowired

    private ProductManager productManager;

    public List<Order> queryOrders() throws Exception {

        // ...

        // 如果子任务出现阻塞,父任务一直等待。

        Future<Order> orderFuture = poseidonThreadPool.submit(() -> {

            // ...

            ProductInfo product = productManager.queryProducts(orderId);

            // ...

        });

        orderFuture.get();

        // ...

    }

}

class ProductManager {

    // Poseidon配置的线程池

    @Resource(name = "poseidonThreadPool")

    private ThreadPoolExecutor poseidonThreadPool;

    public List<ProductInfo> queryProducts(String orderId) throws Exception {

        // ...

        // 子任务存在多线程处理,且使用了同一个线程池。

        Future<ProductInfo> productFuture = poseidonThreadPool.submit(() -> {

            // ...

        });

        productFuture.get();

        // ...

    }

}

父子任务使用同一个线程池容易相互影响,线程数达上限时,子任务等待线程资源,而同时,父任务因子任务未完成,其资源得不到释放,最终可能导致相互等待或死锁。

4强制在多线程环境下,禁止直接使用HashMap。

正例:

// poseidonThreadPool在Poseidon管理平台已创建

@Resource(name = "poseidonThreadPool")

private ThreadPoolExecutor poseidonThreadPool;

public void process() {

     // ConcurrentHashMap是线程安全的

    Map<String, String> map = new ConcurrentHashMap<>();

    CompletableFuture.supplyAsync(() -> {

        // ...

        map.put("key1""value1");

        // ...

    }, poseidonThreadPool);

    CompletableFuture.supplyAsync(() -> {

        // ...

        map.put("key2""value2");

        // ...

    }, poseidonThreadPool);

}

反例:

// poseidonThreadPool在Poseidon管理平台已创建

@Resource(name = "poseidonThreadPool")

private ThreadPoolExecutor poseidonThreadPool;

public void process() {

    // HashMap是线程不安全的

    Map<String, String> map = new HashMap<>();

    CompletableFuture.supplyAsync(() -> {

        // ...

        map.put("key1""value1");

        // ...

    }, poseidonThreadPool);

    CompletableFuture.supplyAsync(() -> {

        // ...

       map.put("key2""value2");

        // ...

    }, poseidonThreadPool);

}

HashMap是线程不安全的,在容量不够进行resize时,可能因并发出现死链,导致CPU飙升。

四、日志

序号

等级

规范

示例

说明

1

强制

日志级别只允许使用ERROR、WARN、INFO、DEBUG。

正例:

// ...

// info打印业务关键信息

log.info("操作人id:{}", operatorUserId);

// ...

List<UserData> userDataList = userListService.selectUsers();

// debug打印开发调试信息

log.debug("开始执行时间:{}", System.currentTimeMillis());

userDataList.stream().forEach(userData -> {

    // ...

});

log.debug("结束执行时间:{}", System.currentTimeMillis());

  • ERROR:业务功能受损或无法完成预期操作,可能会造成线上故障需要预警并及时解决,否则该功能将无法正常运行。
  • WARN:异常符合预期的情况且业务不受损,不会出现线上故障,可根据实际情况选择性预警,解决时效要求不高,但需要关注。
  • INFO:用于记录系统运行过程或重要信息点,主要为故障定位、过程追溯、数据分析等提供辅助。
  • DEBUG:用于在测试或本地的非生产环境中使用,可以记录详细的信息,主要为了方便开发调试程序,在生产环境中禁止使用。
2

强制

业务受损或预期外的异常场景,应当打印ERROR日志。

正例:

try {

    // ...

    // 发送短信验证码

    loginService.sendVerificationCode(cellphone);

    // ...

catch (Exception ex) {

    // 预期外的系统错误,业务受损。

    log.error("异常场景:{}, 异常数据:{}""用户H5登录", userId, ex);

    // 异常处理

}

反例:

try {

    // ...

    // 发送短信验证码

    loginService.sendVerificationCode(cellphone);

    // ...

catch (Exception ex) {

    log.info("异常场景:{}, 异常数据:{}""用户H5登录", userId, ex);

    // 异常处理

}

ERROR日志用于描述异常不可控的场景,当该类异常发生的时候会给业务和系统带来伤害,需要第一时间告警并介入排查修复。

3强制业务不受损且预期内的异常场景,应当打印WARN日志。

正例:

public List<User> selectUserByHeight(Integer height) {

    // ...

    // 该校验偶发于用户录入出错的情况下,需观测是否频繁以指导进一步处理。

    // 如:可能上游系统BUG导致度量单位搞错

    if (height > 270) {

        log.warn("异常场景:{},身高:{} 不能大于270cm""用户H5注册",  height);

        // ...

    }

    // ...

}

WARN日志用于描述异常可控的场景,当该类异常发生的时候不会给业务和系统带来伤害,用于记录和观测,指导进一步处理。
4

推荐

打印日志时,建议使用占位符的方式拼装内容。

正例:

// 用{}填充

log.info("用户注册ID:{}", userId);

反例:

// 用+拼接

log.info("用户注册ID:" + userId);

”+“ 拼接会多次调用StringBuilder的append()方式,每一次append的时候会计算字符串的长度以及重新分配一次内存,对性能有一定的损耗。

此外,“+”拼接方式无论本条日志是否打印都会计算长度和分配内存,而占位符的方式仅在打印的时候才进行内存分配。

5

推荐

打印日志时,不建议使用JSON工具将对象转换成String。

正例

public class UserInfo {

    private String id;

    public String getUserName() throws Exception {

        throw new Exception();

    }

    @Override

    public String toString() {

        return "id:" + id;

    }

}

public void doSth (UserInfo user) {

    // ...

   if(user != null){

        // ...

        log.info("user = {}", user.toString());

    }

    // ...

}

反例:

public class UserInfo {

    // ...

    public String getUserName() throws Exception {

        throw new Exception();

    }

}

public void doSth(UserInfo user) {

    // 会抛出异常。

    log.info("user = {}", JSON.toJSONString(user));

    // ...

}

如果对象里某些get方法被覆写,存在抛出异常的风险,进而影响正常业务流程。

6

推荐

异常日志内容中应当包含三要素:异常场景、异常数据、异常堆栈。

正例:

try {

    // ...

catch (Exception ex) {

    // 日志内容里记录异常场景、异常数据、异常堆栈信息。

    log.error("异常场景:{}, 异常数据:{}""用户H5登录", userId, ex);

    // 异常处理

}

反例:

try {       

    // ...

catch (Exception ex) {

    // 打印日志不完整,没有打印异常堆栈信息、异常数据。

    log.error("系统异常");

    // 异常处理

}

异常日志内容应记录关键的信息(异常场景、异常数据、异常堆栈),为问题排查提供有效帮助,能更高效的处理线上故障。

三要素包含:

异常场景:出现异常的业务场景说明。

异常数据:出现异常的数据(比如下单场景,需要记录商品ID、用户ID等信息)。

异常堆栈:异常堆栈信息。

五、安全

序号

等级

规范

示例

说明

1强制

用户敏感数据禁止直接展示、禁止用Get方式提交。

反例:

@Resource

private UserService userService;

public BizResponse<List<UserDTO>> getAllUsers() {

    List<User> users = userService.selectAllUsers();

    List<UserDTO> userDTOs = new ArrayList<>();

    users.forEach(user -> {

        UserDTO userDTO = new UserDTO();

        // 手机号码此处没有脱敏,直接返回到前端。

        userDTO.setPhone(user.getPhone());

        // ...

        userDTOs.add(userDTO);

    });

    return BizResponse.success(userDTOs);

}

手机号、银行卡卡号、身份证、车牌、车架号等都属于用户敏感信息,不能直接展示。

脱敏方式:

  • 手机号保留前3位和后4位;
  • 身份证号保留前6位和后3位;
  • 银行卡前6位和后4位;
  • 车牌将视情况按照保留地区和流水号后2位;
  • 车架号将视情况按照保留后6位;

禁止用Get方式提交,这种方式在URL上带有敏感数据,将会在wan/lan日志中出现这些元数据。

2强制

用户输入的参数,禁止直接拼接到SQL访问数据库。

反例:

<!-- Mapper XML -->

<select id="findUser" resultType="com.tuhu.mysql.User">

    select * from userInfo where username = ${userName}

</select>

// Mapper接口

public UserInfo findUser(String userName)

用户输入的参数可能带有SQL片段,存在SQL注入的风险,需要使用参数绑定的技术来防范。

3强制未经许可,禁止外发公司任何程序代码。

反例:

为了交流学习,将公司代码上传至GitHub,以方便各方来阅读和讨论,导致APPID、API等信息泄漏。

程序代码属于公司资产,在未经许可的情况下不得以任何方式(邮件、IM软件、纸质打印等)向外传输或公开,包括但不仅限于:

  • 第三方代码托管平台(Github、Gitee等)
  • 第三方网盘(百度网盘、阿里网盘等)
  • 第三方网站(CSDN、博客园等)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2384231.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

重写B站(网页、后端、小程序)

1. 网页端 1.1 框架 Vue ElementUI axios 1.2 框架搭建步骤 搭建Vue 1.3 配置文件 main.js import {createApp} from vue import ElementUi from element-plus import element-plus/dist/index.css; import axios from "axios"; import router from…

文档债务拖累交付速度?5大优化策略文档自动化

开发者在追求开发速度的过程中&#xff0c;往往会忽视文档的编写&#xff0c;如省略设计文档、代码注释或API文档等。这种做法往往导致在后期调试阶段需要花费三倍以上的时间来理解代码逻辑&#xff0c;进而形成所谓的文档债务&#xff0c;严重拖累交付速度并造成资源浪费。而积…

【数据结构与算法】LeetCode 每日三题

如果你已经对数据结构与算法略知一二&#xff0c;现在正在复习数据结构与算法的一些重点知识 ------------------------------------------------------------------------------------------------------------------------- 关注我&#x1f308;&#xff0c;每天更新总结文章…

基于深度学习的电力负荷预测研究

一、深度学习模型框架 在当今数字化时代&#xff0c;基于深度学习的电力负荷预测研究正成为保障电力系统稳定、高效运行的关键领域。其模型构建是一个复杂而精妙的过程&#xff0c;涉及多学科知识与前沿技术的融合应用。首先&#xff0c;要明确电力负荷预测的目标&#xff0c;…

篇章十 消息持久化(二)

目录 1.消息持久化-创建MessageFileManger类 1.1 创建一个类 1.2 创建关于路径的方法 1.3 定义内部类 1.4 实现消息统计文件读写 1.5 实现创建消息目录和文件 1.6 实现删除消息目录和文件 1.7 实现消息序列化 1. 消息序列化的一些概念&#xff1a; 2. 方案选择&#xf…

【IDEA】删除/替换文件中所有包含某个字符串的行

目录 前言 正则表达式 示例 使用方法 前言 在日常开发中&#xff0c;频繁地删除无用代码或清理空行是不可避免的操作。许多开发者希望找到一种高效的方式&#xff0c;避免手动选中代码再删除的繁琐过程。 使用正则表达式是处理字符串的一个非常有效的方法。 正则表达式 …

基于深度学习的不良驾驶行为为识别检测

一.研究目的 随着全球汽车保有量持续增长&#xff0c;交通安全问题日益严峻&#xff0c;由不良驾驶行为&#xff08;如疲劳驾驶、接打电话、急加速/急刹车等&#xff09;引发的交通事故频发&#xff0c;不仅威胁生命财产安全&#xff0c;还加剧交通拥堵与环境污染。传统识别方…

第十周作业

一、CSRF 1、DVWA-High等级 2、使用Burp生成CSRF利用POC并实现攻击 二、SSRF&#xff1a;file_get_content实验&#xff0c;要求获取ssrf.php的源码 三、RCE 1、 ThinkPHP 2、 Weblogic 3、Shiro

Python操作PDF书签详解 - 添加、修改、提取和删除

目录 简介 使用工具 Python 向 PDF 添加书签 添加书签 添加嵌套书签 Python 修改 PDF 书签 Python 展开或折叠 PDF 书签 Python 提取 PDF 书签 Python 删除 PDF 书签 简介 PDF 书签是 PDF 文件中的导航工具&#xff0c;通常包含一个标题和一个跳转位置&#xff08;如…

集星獭 | 重塑集成体验:新版编排重构仿真电商订单数据入库

概要介绍 新版服务编排以可视化模式驱动电商订单入库流程升级&#xff0c;实现订单、客户、库存、发票、发货等环节的自动化处理。流程中通过循环节点、判断逻辑与数据查询的编排&#xff0c;完成了低代码构建业务逻辑&#xff0c;极大提升订单处理效率与业务响应速度。 背景…

多模态大语言模型arxiv论文略读(八十八)

MammothModa: Multi-Modal Large Language Model ➡️ 论文标题&#xff1a;MammothModa: Multi-Modal Large Language Model ➡️ 论文作者&#xff1a;Qi She, Junwen Pan, Xin Wan, Rui Zhang, Dawei Lu, Kai Huang ➡️ 研究机构: ByteDance, Beijing, China ➡️ 问题背景…

WebSocket 从入门到进阶实战

好记忆不如烂笔头&#xff0c;能记下点东西&#xff0c;就记下点&#xff0c;有时间拿出来看看&#xff0c;也会发觉不一样的感受. 聊天系统是WebSocket的最佳实践&#xff0c;以下是使用WebSocket技术实现的一个聊天系统的关键代码&#xff0c;可以通过这些关键代码&#xff…

CSS:vertical-align用法以及布局小案例(较难)

文章目录 一、vertical-align说明二、布局案例 一、vertical-align说明 上面的文字介绍&#xff0c;估计大家也看不懂 二、布局案例

Java转Go日记(五十四):gin路由

1. 基本路由 gin 框架中采用的路由库是基于httprouter做的 地址为&#xff1a;https://github.com/julienschmidt/httprouter package mainimport ("net/http""github.com/gin-gonic/gin" )func main() {r : gin.Default()r.GET("/", func(c …

【解决】自己的域名任何端口都访问不到,公网地址正常访问,服务器报错500。

一、问题描述 后端项目部署在服务器上&#xff0c;通过域名访问接口服务器报错500&#xff0c;通过浏览器访问域名的任何端口都是无法访问此网站。 但是通过公网地址访问是可以正常访问到的&#xff0c;感觉是域名出现了问题 二、解决过程 先说结论&#xff1a;问题原因是…

制作 MacOS系统 の Heic动态壁纸

了解动态桌面壁纸 当macOS 10.14发布后&#xff0c;会发现系统带有动态桌面壁纸&#xff0c;设置后&#xff0c;我们的桌面背景将随着一天从早上、到下午、再到晚上的推移而发生微妙的变化。 虽然有些软件也有类似的动态变化效果&#xff0c;但是在新系统中默认的HEIC格式的动…

大数据 笔记

kafka kafka作为消息队列为什么发送和消费消息这么快&#xff1f; 消息分区&#xff1a;不受单台服务器的限制&#xff0c;可以不受限的处理更多的数据顺序读写&#xff1a;磁盘顺序读写&#xff0c;提升读写效率页缓存&#xff1a;把磁盘中的数据缓存到内存中&#xff0c;把…

【数据库】-1 mysql 的安装

文章目录 1、mysql数据库1.1 mysql数据库的简要介绍 2、mysql数据库的安装2.1 centos安装2.2 ubuntu安装 1、mysql数据库 1.1 mysql数据库的简要介绍 MySQL是一种开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;由瑞典MySQL AB公司开发&#xff0c;目前…

物流项目第五期(运费计算实现、责任链设计模式运用)

前四期&#xff1a; 物流项目第一期&#xff08;登录业务&#xff09;-CSDN博客 物流项目第二期&#xff08;用户端登录与双token三验证&#xff09;-CSDN博客 物流项目第三期&#xff08;统一网关、工厂模式运用&#xff09;-CSDN博客 物流项目第四期&#xff08;运费模板列…

X 下载器 2.1.42 | 国外媒体下载工具 网页视频嗅探下载

X 下载器让你能够轻松地从社交应用如Facebook、Instagram、TikTok等下载视频和图片。通过内置浏览器访问网站&#xff0c;它能自动检测视频和图片&#xff0c;只需点击下载按钮即可完成下载。去除广告&#xff0c;解锁本地会员&#xff0c;享受无广告打扰的下载体验。 大小&am…