当前位置: 首页 > news >正文

SpringBoot项目--电脑商城【上传头像】

一、易错点

1.错误写法:

把文件存到数据库中,需要图片时访问数据库,数据库将文件解析为字节流返回,最后写到本地的某一个文件.这种方法太耗费资源和时间了

2.正确写法:

将对应的文件保存在操作系统上,然后再把这个文件路径记录下来,因为在记录路径的时候是非常便捷和方便的,将来如果要打开这个文件可以依据这个路径找到这个文件,所以说在数据库中保存该文件的路径即可.

3.注意点

稍微大一点的公司都会将所有的静态资源(图片,文件,其他资源文件)放到某台电脑上,再把这台电脑作为一台单独的服务器使用

2.持久层[Mapper]

1.SQL语句的规划

update t_user set avatar=?,modified_user=?,modified_time=? where uid=?

2. 设计接口和抽象方法

在UserMapper接口中定义一个抽象方法用于修改用户的头像

    /*** @param:是将映射文件中的#{}进行换名,如果不一致的时候* 根据用户uid值来最高用户的头像* @param uid* @param avatar* @param modifiedUser* @param modifiedTime* @return*//*** 注解@Param("SQL映射文件中#{}占位符的变量名"),解决的问题:* 当SQL语句的占位符和映射的接口方法参数名不一致时,需要将某个参数强行注入到某个* 占位符变量上时,可以使用@Param这个注解来标注映射的关系* */Integer updateAvatarByUid(@Param("uid") Integer uid,@Param("avatar") String avatar,@Param("modifiedUser") String modifiedUser,@Param("modifiedTime") Date modifiedTime);
}

3. 编写映射

UserMapper.xml文件中编写映射的SQL语句

    <update id="updateAvatarByUid">update t_usersetavatar=#{avatar},modified_time=#{modifiedTime},modified_user=#{modifiedUser}whereuid=#{uid}</update>

4. 单元测试

@Test
public void updateAvatarByUid() {userMapper.updateAvatarByUid(11,"abc","mxy",new Date());
}

3.业务层[Service]

1. 规划异常

  • 用户数据不存在,找不到对应的用户数据
  • 更新的时候,出现未知异常

无需重复开发

2. 设计接口和抽象方法及实现

1.先分析一下业务层接口需要哪些参数:那就需要看持久层接口要的有什么参数:

uid,avatar,modifiedUser,modifiedTime,其中modifiedTime是在方法中创建的,uid和modifiedUser从session中获取,但是session对象是在控制层的并不会出现在业务层,所以业务层要保留这两个参数,以便控制层可以传递过来

    /*** 修改用户头像* @param uid 用户id* @param avatar 用户头像的路径* @param username 用户名称*/void changeAvatar(Integer uid,String avatar,String username);//业务层一般叫username而不叫modifiedUser,因// 为业务层并没有直接和数据库关联

2.编写业务层的更新用户头像的方法

    /*** 修改用户头像* @param uid 用户id* @param avatar 用户头像的路径* @param username 用户名称*/@Overridepublic void changeAvatar(Integer uid, String avatar, String username) {//查询当前用户的数据是否存在User result = userMapper.findByUid(uid);if(result==null || result.getIsDelete()==1){throw new UserNotFoundException("用户数据不存在");}Integer rows = userMapper.updateAvatarByUid(uid, avatar, username, new Date());if(rows!=1){throw new UpdateException("更新用户头像产生未知的异常");}}

3. 单元测试

@Test
public void changeAvatar() {userService.changeAvatar(11,"222","mmm");
}

4.控制层[Controller]

文件上传过程中产生的异常太多了,再比如文件类型不匹配或文件被损坏

1. 规划异常

客户端传递文件给服务器,服务器的控制端controller接收文件,接收时可能抛出异常,因为用户传过来的文件有可能超出了我们的大小限制

该异常能放在业务层抛出吗?没必要的,因为此时数据是从控制层往下传的,所以控制层产生的异常直接在这一层(控制层)抛就可以了

上传文件时的异常都是文件异常,所以可以先创建一个文件异常类的基类FileUploadException并使其继承RuntimeException

文件异常基类的子类有:

  • FileEmptyException:文件为空的异常(没有选择上传的文件就提交了表单,或选择的文件是0字节的空文件)
  • FileSizeException:文件大小超出限制
  • FileTypeException:文件类型异常(上传的文件类型超出了限制)
  • FileUploadIOException:文件读写异常
  • FileStateException:文件状态异常(上穿文件时该文件正在打开状态)

在controller包下创子包ex,在ex包里面创建文件异常类的基类和上述五个文件异常类,创建的六个类都重写其父类的五个构造方法

2. 处理异常

在基类BaseController中进行编写和统一处理

else if (e instanceof FileEmptyException) {result.setState(6000);
} else if (e instanceof FileSizeException) {result.setState(6001);
} else if (e instanceof FileTypeException) {result.setState(6002);
} else if (e instanceof FileStateException) {result.setState(6003);
} else if (e instanceof FileUploadIOException) {result.setState(6004);
}

异常统一处理方法的修饰符@ExceptionHandler(ServiceException.class)表明我们现在创建的FileUploadException异常类不会被拦截到该方法中,点进@ExceptionHandler注解可以发现传参可以传数组类型,所以可以将异常统一处理方法上的注解改为:

@ExceptionHandler({ServiceException.class,FileUploadException.class})

3. 设计请求

  • /users/change_avatar
  • POST(GET请求提交数据只有2KB左右)
  • HttpSession session(获取uid和username),MultipartFile file
  • JsonResult<String>(不能是JsonResult<Void>:如果上传头像后浏览别的页面,然后再回到上传头像的页面就展示不出来了,所以图片一旦上传成功,就要保存该图片在服务器的哪个位置,这样的话一旦检测到进入上传头像的页面就可以通过保存的路径拿到图片,最后展示在页面上)
    @PostMapping("/change_avatar")public JsonResult<String> changeAvatar(HttpSession session,@RequestParam("file") MultipartFile file) {/*** 1.参数名为什么必须用file:在upload.html页面的147行<input type=* "file" name="file">中的name="file",所以必须有一个方法的参数名* 为file用于接收前端传递的该文件.如果想要参数名和前端的name不一* 样:@RequestParam("file")MultipartFile ffff:把表单中name=* "file"的控件值传递到变量ffff上* 2.参数类型为什么必须是MultipartFile:这是springmvc中封装的一个* 包装接口,如果类型是MultipartFile并且参数名和前端上传文件的name* 相同,则会自动把整体的数据包传递给file*///判断文件是否为空if (file.isEmpty()) {throw new FileEmptyException("文件为空");}if (file.getSize() > AVATAR_MAX_SIZE) {throw new FileSizeException("文件超出限制");}//判断文件的类型是否为我们规定的类型String contentType = file.getContentType();//如果集合包含某一个元素则返回trueif (!AVATAR_TYPE.contains(contentType)) {throw new FileTypeException("文件类型不支持");}//上传的文件  ../upload/文件.png/*** session.getServletContext()获取当前Web应用程序的上下文* 对象(每次启动tomcat都会创建一个新的上下文对象)* getRealPath("/upload")的/代表当前web应用程序的根目录,通过该相* 对路径获取绝对路径,返回一个路径字符串,如果不能进行映射返回null,单* 斜杠可要可不要*/String parent = session.getServletContext().getRealPath("upload");//File对象指向这个路径,File是否存在File dir = new File(parent);if (!dir.exists()) {//检测目录是否存在dir.mkdir();//创建当前的目录}//获取到这个文件名称,UUID工具来生成一个新的字符串作为文件名//例如:avatar01.pngString originalFilename = file.getOriginalFilename();System.out.println("OriginalFilename=" + originalFilename);//获取文件后缀String suffix = "";int index = originalFilename.lastIndexOf(".");suffix = originalFilename.substring(index);String filename = UUID.randomUUID().toString().toUpperCase() + suffix;//表示在dir这个文件下创建一个filename的文件File dest = new File(dir, filename);//此时dest是一个空文件//将参数file中数据写入到这个空文件中try {//将file文件中的数据写入到dest文件//transferTo是一个封装的方法,用来将file文件中的数据写入到dest文件file.transferTo(dest);/*** 先捕获FileStateException再捕获IOException是* 因为后者包含前者,如果先捕获IOException那么* FileStateException就永远不可能会被捕获*/} catch (FileStateException e) {throw new FileStateException("文件状态异常");} catch (IOException e) {//这里不用打印e,而是用自己写的FileUploadIOException类并// 抛出文件读写异常throw new FileUploadIOException("文件读写异常");}Integer uid = getuidFromSession(session);String username = getUsernameFromSession(session);//返回头像的路径/upload/test.pngString avater = "/upload/" + filename;userService.changeAvatar(uid, avater, username);//返回用户头像的路径给前端页面,将来用于头像展示return new JsonResult<>(OK, avater);}

5.前端页面

1.在upload.html的上传头像的表单加上三个属性:

action=“/users/change_avatar”
method=“post”(get请求提交数据只有2KB左右)
enctype=“multipart/form-data”(如果直接使用表单进行文件的上传,需要给表单加该属性,这样不会将目标文件的数据结构做修改后再上传,这不同于字符串,字符串随意切割修改也能拼在一起,但文件不行)


2.确认

<input type=“file” name=“file”>的type和name以及<input type=“submit” class=“btn btn-primary” value=“上传” />中的type

6.前端页面优化——修复bug

1 更改默认的大小限制

springmvc默认为1MB文件可以进行上传,如果刚好是1024*1024=1048576 bytes则会报代码错误,自己在控制层设置的public static final int AVATAR_MAX_SIZE = 10*1024*1024;需要在不超过原有大小的情况下才会起作用,所以要手动修改springmvc默认上传文件的大小

方法一:直接在配置文件中进行配置[application.yml]

# 修改文件上传大小servlet:multipart:max-file-size: 10MB # 表示上传的文件最大是多少# 整个文件是放在request中发生给服务器,请求当中还会有消息头等其他携带消息max-request-size: 15MB 

方法二:采用java代码的形式进行设置

1.该代码必须在主类中进行配置,因为主类是最早加载的,而配置文件必须是最早加载的

2.在主类中定义一个方法,方法名无所谓,但方法需要用@bean修饰,表示该方法返回值是一个bean对象,并且该bean对象被bean修饰,也就是这个方法返回了一个对象,然后把该对象交给bean管理,类似spring中的bean标签,含义是一样的,只是这里改为了注解

3.用@Configuration修饰主类使@bean注解生效,但其实@SpringBootApplication是@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan三个注解的合并,所以可以不需要@Configuration

4.方法返回值是MultipartConfigElement类型,表示所要配置的目标的元素

@SpringBootApplication
@Configuration
//MapperScan注解指定当前项目中Mapper接口路径的位置,在项目启动的时候自动加载所有的接口
@MapperScan("com.example.mycomputerstore.mapper")
public class MyComputerStoreApplication {public static void main(String[] args) {SpringApplication.run(MyComputerStoreApplication.class, args);}/*** 设置文件上传大小* @return*/@Beanpublic MultipartConfigElement getMultipartConfigElement(){//创建一个配置的工厂类对象MultipartConfigFactory factory = new MultipartConfigFactory();//设置需要创建的对象的相关信息factory.setMaxFileSize(DataSize.of(10, DataUnit.MEGABYTES));factory.setMaxRequestSize(DataSize.of(15,DataUnit.MEGABYTES));//通过工厂类来创建MulitpartConfigElement对象return factory.createMultipartConfig();}}

2.上传后显示头像

上传头像成功后不能显示头像.

在页面中通过ajax请求来提交文件,提交完成后返回了json串,解析出json串中的data数据设置到img标签的src属性上

1.删掉在upload.html的上传头像的表单中加的三个属性

action=“/users/change_avatar”,method=“post”,enctype=“multipart/form-data”.加上id属性:id=“form-change-avatar”

2.将sumbit修改为button

把153行的input标签里面的type="submit"改为type=“button”(因为submit按钮不能添加事件,所以要改为普通的按钮)并加上属性id=“btn-change-avatar”

3.注意点:serialize用法【提交普通数据】/FormData类 的用法【提交文件】

1.serialize():可以将表单数据自动拼接成key=value的结构提交给服务器,一般提交的是普通的控件类型中的数据(type=text/password/radio/checkbox等等)

2.FormData类:将表单中数据保持原有的结构进行数据提交.文件类型的数据可以使用FormData对象进行存储

使用方法:new FormData($(“form”)[0]);

这行代码的含义是将id="form"的表单的第一个元素的整体值作为创建FormData对象的数据

3.虽然我们把文件的数据保护下来了,但是ajax默认处理数据时按照字符串的形式进行处理,以及默认会采用字符串的形式进行数据提交.手动关闭这两个功能:

processData: false,//处理数据的形式,关闭处理数据
contentType: false,//提交数据的形式,关闭默认提交数据的形式

$("#btn-change-avatar").click(function() {$.ajax({url: "/users/change_avatar",type: "POST",data: new FormData($("#form-change-avatar")[0]),dataType: "JSON",processData: false, // processData处理数据contentType: false, // contentType发送数据的格式success: function(json) {if (json.state == 200) {//attr(属性,属性值):给某一个属性设置某个值,给已有数据的属性再一次赋值$("#img-avatar").attr("src", json.data);//将头像保存在cookie//显示最新头像$.cookie("avatar", json.data, {expires: 7});} else {alert("修改失败!" + json.message);}},error: function(xhr) {alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status);location.href = "login.html";}});});

4.登录后显示头像【使用Cookie进行存储】

将头像上传后会显示头像,但是关闭浏览器后再进入个人头像页面就不会显示头像了,因为只有点击"上传"才能发送ajax请求并显示头像.

可以在每次用户登录成功后将avatar保存在cookie中,登录的业务层返回给控制层user对象,该对象包含uid,username,avatar.所以要在登录页面login.html中将服务器返回的头像路径设置到cookie中,然后每次检测到用户打开上传头像页面,在这个页面中通过ready()方法来自动读取cookie中头像路径并设到src属性上

1.需要在login.html页面头部导入cookie.js文件

<script src="../bootstrap3/js/jquery.cookie.js" type="text/javascript" charset="utf-8"></script>

2.调用cookie方法保存路径

$.cookie(key,value,time);//time单位:天

在ajax请求原有的代码上加$.cookie(“avatar”,json.data.avatar,{expires: 7});

success: function(json) {if(json.state == 200) {alert("登录成功");//跳转到主页index.html//相对路径来确定跳转的页面location.href = "index.html";//将服务器返回头像设置到Cookie中//cookie(key,value,time)-->单位:天$.cookie("avatar",json.data.avatar,{expires:7})} else {alert("登录失败 -> 原因:" + json.message);}},

3.需要在upload.html获取cookie中的值,所以要在页面头部导入cookie.js文件

<script src="../bootstrap3/js/jquery.cookie.js" type="text/javascript" charset="utf-8"></script>

4.在upload.html的script标签中加ready()自动读取cookie数据

		//cookie获取头像$(document).ready(function () {console.log("cookie中的avatar=" + $.cookie("avatar"));//将cookie值获取出来设置到头像的src属性上$("#img-avatar").attr("src", $.cookie("avatar"));});

5.显示最新头像

上传头像后不重新登录而是浏览其他页面,然后再进入个人头像页面时展示的头像是上次上传的,因为此时cookie中的值是上次上传的头像的路径,所以需要上传头像后使用同名覆盖更改cookie中路径

在ajax函数的success属性值的if语句加:

$.cookie("avatar",json.data,{expires: 7});

相关文章:

SpringBoot项目--电脑商城【上传头像】

一、易错点 1.错误写法&#xff1a; 把文件存到数据库中,需要图片时访问数据库,数据库将文件解析为字节流返回,最后写到本地的某一个文件.这种方法太耗费资源和时间了 2.正确写法&#xff1a; 将对应的文件保存在操作系统上,然后再把这个文件路径记录下来,因为在记录路径的…...

优化SOCKS5的方法

在今天的互联网世界中&#xff0c;保护个人隐私和提升网络速度至关重要。作为一种常用的代理协议&#xff0c;SOCKS5代理服务器不仅可以保护您的隐私&#xff0c;还可以实现更快速的网络访问。本文将为您介绍一些优化SOCKS5代理服务器的方法&#xff0c;以提高网络速度和安全性…...

使用 HelpLook Chatbot,让AI聊天机器人变成销售经理

想要增强AI聊天机器人销售技巧的话&#xff0c;我们需要一个强大的搭建工具来帮助我们增加客户互动&#xff0c;通过很多的客户互动数据来支撑和锻炼我们的AI聊天机器人。在本篇文章中&#xff0c;looklook将会系统地来说说该如何定制聊天机器人的行为。 使用AI聊天机器人的好处…...

MT9700 80mΩ,可调快速响应限流配电开关芯片

MT9700 80mΩ&#xff0c;可调快速响应限流配电开关芯片 特征 符合USB规范 集成80mΩ电源MOSFET 低电源电流 15μA典型开启状态 1μA典型关闭状态 宽输入电压Range&#xff1a;2.4V到5.5V 快速瞬态响应&#xff1a;<2μs 反向电流流阻塞 热关机保护 热插件应…...

RabbitMQ之延迟队列

RabbitMQ之延迟队列 1. 延迟队列概念2. 延迟队列使用场景3. RabbitMQ 中的 TTL3.1 消息设置 TTL3.2 队列设置 TTL3.3 两者的区别 4. 整合 SpringBoot4.1 创建项目4.2 添加依赖4.3 修改配置文件4.4 添加 Swagger 配置类 5. 队列 TTL5.1 代码架构图5.2 配置文件类代码5.3 消息生产…...

k8s部署手册-v06

一、基础配置 1.修改主机名 hostnamectl set-hostname k8s-master01 hostnamectl set-hostname k8s-master02 hostnamectl set-hostname k8s-master03 hostnamectl set-hostname k8s-node01 hostnamectl set-hostname k8s-node022.添加 主机名与IP地址解析 cat > /etc/ho…...

Qt 5.15集成Crypto++ 8.7.0(MSVC 2019)笔记

一、背景 笔者已介绍过在Qt 5.15.x中使用MinGW&#xff08;8.10版本&#xff09;编译并集成Crypto 8.7.0。 但是该编译出来的库&#xff08;.a和.dll&#xff09;不适用MSVC&#xff08;2019版本&#xff09;构建环境&#xff0c;需要重新编译&#xff08;.lib或和.dll&#xf…...

LeetCode——贪心篇(一)

刷题顺序及思路来源于代码随想录&#xff0c;网站地址&#xff1a;https://programmercarl.com 目录 455. 分发饼干 376. 摆动序列 53. 最大子数组和 122. 买卖股票的最佳时机 II 55. 跳跃游戏 45. 跳跃游戏 II 1005. K 次取反后最大化的数组和 455. 分发饼干 假设你是…...

2023高教社杯 国赛数学建模C题思路 - 蔬菜类商品的自动定价与补货决策

1 赛题 在生鲜商超中&#xff0c;一般蔬菜类商品的保鲜期都比较短&#xff0c;且品相随销售时间的增加而变差&#xff0c; 大部分品种如当日未售出&#xff0c;隔日就无法再售。因此&#xff0c; 商超通常会根据各商品的历史销售和需 求情况每天进行补货。 由于商超销售的蔬菜…...

【理解线性代数】(四)线性运算的推广与矩阵基础

1. 数值加法和乘法 数值加法与乘法&#xff0c;是小学数学课程中的基本数学运算。例如&#xff1a; 加法&#xff1a;112 乘法&#xff1a;2*24 在这个知识层次下&#xff0c;运算的基本单位是数字。 2. 从数值到向量 数值加法&#xff0c;可以看作一维空间中的向量加法&…...

C# 什么是继承和派生

C# 什么是继承和派生 在 C# 中&#xff0c;继承&#xff08;Inheritance&#xff09;是一种机制&#xff0c;它允许一个类&#xff08;子类&#xff09;从另一个类&#xff08;父类&#xff09;中继承属性和方法。这种关系使得子类可以重用父类的代码&#xff0c;同时可以在子…...

无涯教程-JavaScript - HEX2BIN函数

描述 HEX2BIN函数将十六进制数转换为二进制数。 语法 HEX2BIN (number, [places])争论 Argument描述Required/Optionalnumber 您要转换的十六进制数。 数字不能超过10个字符(40位)。数字的最高有效位是符号位(从右数第40位)。其余的39位是幅度位。 负数使用二进制补码表示。…...

前端面试0906

// 请给出输出结果 function foo(){ console.log(a); } function bar(){ var a 3; console.log(this.a); foo(); } var a 2; bar(); 2 2 // 请从下面的问题中挑选3道进行回答 1. 防抖和节流分别是什么&#xff0c;一般用在什么场景&#xff1f; 防抖&#xff08;Debounc…...

OceanBase社区版4.x核心技术解密

数字化时代&#xff0c;各行各业的数据量呈现爆发式增长&#xff0c;对于海量数据价值的挖掘和应用&#xff0c;正成为推动创新的主要力量&#xff0c;与此同时&#xff0c;数据计算复杂度正在提升。在此背景下&#xff0c;对于数据处理的基石数据库而言&#xff0c;正面临市场…...

快速安装k8s

RKE安装方式 官方文章资源地址 https://rke.docs.rancher.com/installation rke工具下载地址&#xff08;arm,amd,windows都有&#xff09; https://github.com/rancher/rke/releases x86的用amd64下载rke工具 https://github.com/rancher/rke/releases/download/v1.4.8/rke_li…...

[FFmpeg] 常用ffmpeg命令

去水印 ffmpeg -i water.jpeg -strict -2 -vf delogox300:y250:w56:h18:show0 no_water.jpeg 打时间戳 ffmpeg -i perf_60Hz_Raw.mp4 -vf "drawtextfontsize160:fontcolorred:text%{pts\:hms}" -c:v libx264 -an -f mp4 perf_output.mp4 -y ffmpeg -i perf_8k.mp4 -v…...

代码随想录训练营第五十七天|647. 回文子串、516.最长回文子序列

647. 回文子串 题目链接/文章讲解/视频讲解&#xff1a;代码随想录 1.代码展示 //647.回文子串 int countSubstrings(string s) {//step1 构建dp数组&#xff0c;明确dp数组的含义&#xff0c;dp[i][j]的含义是在下标为i和j区间内的字串是否为回文串vector<vector<bool&…...

对线程池设置做压测

线程池代码 Configuration public class ThreadPoolConfig {// 核心线程池大小private int corePoolSize 24;// 最大可创建的线程数private int maxPoolSize 25;// 队列最大长度private int queueCapacity 100;// 线程池维护线程所允许的空闲时间private int keepAliveSeco…...

【网络通信 -- WebRTC】项目实战记录 -- mediasoup android 适配 webrtc m94

【网络通信 -- WebRTC】项目实战记录 -- mediasoup android 适配 webrtc m94 【1】下载并配置 depot_tools 下载 depot_tools git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git编辑 ~/.bashrc 将 depot_tools 添加到路径中 vim ~/.bashrc export…...

【力扣周赛】第 357 场周赛(⭐反悔贪心)

文章目录 竞赛链接Q1&#xff1a;6925. 故障键盘解法1——直接模拟解法2——双端队列 Q2&#xff1a;6953. 判断是否能拆分数组&#xff08;贪心&#xff09;Q3&#xff1a;2812. 找出最安全路径⭐解法1——多源BFS瓶颈路模型&#xff1f;解法2——多源BFS 倒序枚举答案 并查…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...