零基础学Servlet

零基础学Servlet

一。介绍:

servlet是一种比较古老的编写网站的方式,在2010年之前比较流行,在此之后,有一堆大佬创造了Spring(一种框架),Spring是针对Servlet进行进一步封装,从而让我们编写程序更加简单,现在使用java进行商业级别的开发几乎都是使用Spring为主

Servlet是Tomcat提供的一组api,封装了HTTP协议相关操作,让我们更加方便的搭建一个网站的后端

Servlet的主要工作就是让程序员自己实现一些类,然后把这些类加载到Tomcat之中,后续Tomcat收到HTTP请求,就会执行咱们自己写的类,通过这些代码完成一些业务逻辑

二。使用Srevlet的基本步骤

下面进行手动操作,写一个简单的servlet的hello world程序

Step1:创建项目

此处创建的是Maven项目,Maven是java中一个知名的构建工具(帮助我们编译/打包代码的工具),只要在电脑上下载好IDEA,就自然有了Maven

请添加图片描述

点击创建项目,然后选中Build system中的Maven即可创建Maven项目,Maven项目首次创建的时候,会从Maven网站上下载一些依赖的组建(这个过程要保证网络的稳定)

当创建完成之后,就会进入一下和原来写java代码相似的页面,然后关注其左半边部分(如下图所示)

请添加图片描述

这里的main目录下放的是业务代码(解决实际问题的具体过程就叫业务)

main目录之中的java目录是用来存放java代码的,resourses是用来存放java代码中依赖的其他资源(例如:图片,配置文件…)

test目录下主要存放的是测试代码

pom.xml是maven项目的入口配置文件,点开这个文件就可以发现里面已经有一些内容,这些是默认生成的情况,后续还需要修改这个文件添加更多的内容完成一些效果

Step2:引入依赖

接下来写的程序就要用到Servlet,这个api是Tomcat提供的,不是jdk提供的

可以进行手动下载导入,这样很麻烦(工作中涉及的项目会很多,可能依赖的内容也很多),手动管理就很麻烦

因此maven就可以很方便的解决这些问题

(1)打开maven中央仓库(大佬们把市面上的第三方库都收集起来,搞了一个网站,方便我们下载使用),找到Servlet的jar包

网址: https://mvnrepository.com/search?q=Servlet

请添加图片描述

找到这个后,点进去找3.1.0的版本然后拷贝下面图片画圈部分

请添加图片描述

复制之后,回到pom.xml之中,然后加一个标签,将复制的东西粘贴到这个标签之中(如下图所示)

请添加图片描述

这个dependencies标签可以加入多个依赖,后续加入到依赖都可放到这个标签之中

一般来说,只要复制进来就会自动进行下载,如果依然爆红,那么就要进行手动点击刷新键下载

Step3:创建目录

此处的Maven项目是普适的,不仅仅局限于Tomcat;而对与Tomcat来说,项目结构上有一些额外的要求

请添加图片描述

如上图所示,要在main这个文件夹中创建一个新的文件夹(名叫webapp),然后在webapp中创建一个文件夹(叫WEB-INF),最后在这个文件夹中创建一个文件,名叫web.xml

放入内容如下:

<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app><display-name>Archetype Created Web Application</display-name>
</web-app>

此处无需记忆,只需复制粘贴即可

这里是Tomcat要求的结构,咱们写的代码以后要放到Tomcat之中,就必须按照Tomcat的要求进行编写代码

前面三步都不复杂,是一些固定的操作

Step4:编写代码

在java文件夹中创建一个class

import javax.servlet.http.HttpServlet;public class HelloServlet extends HttpServlet {
}

如果第一句import爆红了,那么就表示引入的依赖有问题

这里的继承是为了重写父类中的方法

请添加图片描述

HttpServletRequest 是Http请求

HttpSerletResponse是Http响应

doGet是处理Http GET请求,当Tomcat收到一个GET请求时,有可能执行到这个指令上来

写一个服务器主要步骤就三步:

1.读取请求并解析

2.根据请求计算响应

3.把响应返回给客户端

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("hello world");resp.getWriter().write("hello world");}
}

第一行就是让这个类和HTTP请求路径关联起来(配置路由)

第一个打印(System.out.println(“hello world”);)是把这个打印显示在控制台上

第二个打印(resp.getWriter().write(“hello world”);)是把打印显示在客户端上

Tomcat不是收到所有的get请求都调用这个doGet方法,而是同时判断请求是否为get,和请求的路径是否为/hello

Step5:打包程序

把写好的程序打包成war包(Tomcat要有一个war包在上面)

首先修改pom.xml,设置打包类型和包的名字

<packaging>war</packaging>
<build><finalName>java666</finalName>
</build>

注:默认打包的是jar包(java中通用的打包方式),但是Tomcat中要求是war包

然后右侧maven面板中找到backage按钮,并双击

请添加图片描述

看到这个就表明打包成功

Step6:部署程序

把war包拷贝到webapps中(目录中有想要的war包)

然后启动Tomcat(点bin文件夹中有一个startup.bat)

Strp7:验证程序

通过浏览器,访问Tomcat,获取到代码返回Hello World

127.0.0.1:8080/java666/hello

三。优化Servlet打包部署过程

如果此时想改代码怎么改:1.修改代码 2.重新打包 3.重新部署

这个过程会很麻烦,尤其到后期经常进行增删,这时我们就可以使用IDEA给的插件,把tomcat集成到IDEA中,此时就可以一键打包部署

Step1:安装

File ->settings ->plugins
搜索Smart Tomcat即可找到此插件
请添加图片描述

Step2:运行三角框旁边的位置,点Exit configuration

然后点击左上角的加号,找到tomcat

请添加图片描述

Steo3:配置

请添加图片描述

这里的context path决定了浏览器中访问这个Servlet的时候,第一级路径怎么写

不使用smart tomcat是直接写作war包的名字(目录第名字)

使用smart tomcat的话,context path就要手动进行配置,如果不配置则默认是项目名字

Step4 :运行

补充:如果输出是乱码的情况:

乱码意味着有多个环节对于编码方式的理解不一致,比如构造数据使用utf-8的形式,解析数据使用gbk的形式,那么就很容易出现乱码的状况了

构造数据:此处“你好”是在IDEA编译器上构造的(utf-8)

解析数据:浏览器上进行解析(默认跟随系统的,win10使用的字符集是jbk)

因此要把gbk改为utf-8,在http响应报文中,告诉浏览器返回的body字符集是啥

因此,加上下面这串代码在doGet之中:

resp.setContentType("text/html; charset=utf8");

在http响应报文的header中,就会有content-type,这里描述了body的数据格式,以及编码方式

四。常见的运行问题

1.出现404:

表示用户访问的资源不存在

原因:(1)url路径写错了(在浏览器中把地址栏的内容写错了)

(2)webapp没有正确加载,比如web.xml的内容不正确

2.出现405:

表示方法没有被实现(就比如发一个Get请求,但是Servlet中doGet没有被实现)

还一种可能就是没有删除super.doget(…);

3.出现500:

表示服务器内部出现问题,写的代码抛出异常了

4.出现空白页面:

这个时候就要检查服务器是否返回了带有正文的响应报文

5.出现“无法访问此网站”:

Tomcat没有正确运行

五。Servlet API:

Servlet API有三大类:1.HttpServlet 2.HttpServletRequest。3.HttpServletResponse

1.HttpServlet

方法名称调用时机
init通过这个方法来完成初始化
destroy用来释放资源
service收到Http请求的时候调用
doGet收到Get请求时调用
doPost收到Post请求的时候调用
doPut/doDelete…收到其他请求的时候进行调用

前三个方法都不用进行手动调用,会被Tomcat在合适的时机自动调用

前三个方法在实际开发中很少用到,但是面试题中常出现

init还算比较有用;service一般会被doPost和doGet替代;但是destory就非常尴尬了,说了不算,算了不说,这个方法大概率时执行不到的,一个Servlet不用了,说明Tomcat关闭了,而关闭Tomcat一般就两种办法:1.直接干掉Tomcat进程(在任务管理器上结束进程,或者是直接在IDEA上按X)这样就完全来不及调用destroy了。2.通过8005管理端口,给Tomcat发送一个“停机”指令,这个时候就能执行destory了 但是结合实际场景发现使用第一种方式关闭Tomcat的人更多一些

以后经常会涉及到咱们自己写好的代码让别人来调用,这就是所谓的“框架”(一个程序已经被大佬写好了,有些细节的内容,咱们可以插入咱们自己写的自定义逻辑

当我们开发人员想测试一下自己写的服务器代码是否能得到自己的预期时,我们可以使用Postman这个软件进行测试构造请求

还是以上面的服务器代码为例,运行服务器,然后打开Postman,构造GET请求

请添加图片描述

然后我们可以从图片上看到,Postman的下面就是服务器返回响应的结果,这样就可以查看自己的预期和实际运行结果是否相同了

2.HttpServletRequest

方法描述
String getProtocol()返回请求协议的名称和版本
String getMethod()返回请求的HTTP方法的名称,例如POST,GET,PUT等等
String getRequestURI()从协议名称知道HTTP请求第一行查询字符串中,返回该URL的一部分
String getContextPath()返回指令请求上下文的请求URI的部分(就是?之前的部分)
String getQueryString()返回URL中的查询字符串(就是?之后的部分)
Enumeration getParameterNames()获取quary String中所有的key
String getParameter(String name)这里的name就是key,这个方法就是根据key获取value
String[ ] getParameterValues(String name)当key存在重复的情况下,一个key可以有多个值(?a=10&a=20),这种情况就是把key对应的所有value都放到数组之中
String getCharacterEncoding()获取请求主体获取的字符编码的名称
String getContentType()获取主体的类型
int getContentLength()获取以字节为单位返回请求主体的长度
inputStream getinputStream()通过这个方法可以得一个流对象,读取这个流对象可以获得整个请求的body
String getHeader(String name)这里的name时header中的key,根据这个key在header中获取到对应的value

通过上述方法,可以看到上面的都是get系列(读方法)没有set系列(写方法)

3.HttpServletResponse

方法描述
void setStatus(int sc)为响应设置状态码(sc就是要设置的状态码)
void setHeader(String name,String value)设置一个给定名称和值的header,如果name已经存在,那么就覆盖掉原来的值
void addHeader(String name,String value)设置一个给定名称和值的header,如果name已经存在,那么不覆盖,继续添加新的值
void setContentType(String type)设置被发送到客户端的响应的内容的类型
void setCharacterEncoding(String charset)设置发送到客户端响应的字符编码(比如utf8)
void sendRedirect(String location)指定重定向位置URL
PrintWriter getWriter()用于往body中写入文本格式的数据
OutputStream getOutputStream()用于往body中写入二进制格式的数据

例子:

1.设置状态码和报错信息

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//resp.setStatus(200);设置状态码resp.sendError(404,"这是一个错误的页面");//设置报错信息和报错状态码}
}

2.通过setHeader给响应中设置一些特殊的header

比如可以设置refreash:1,让浏览器每秒自动刷新一次

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setHeader("refresh","1");resp.getWriter().write((int) System.currentTimeMillis());//获取时间戳}
}

3.构造一个重定向响应

重定向的状态码是(3xx),一般使用302

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setStatus(302);resp.setHeader("Location","https://mvnrepository.com/");}
}

另一种写法是直接写resp.sendRedirect(“https://mvnrepository.com/”);

六。前后端交互:服务器获取请求中的参数

1.使用Query String:

query String时程序员自定义的,开发的时候经常使用

这里的query string是在URL中“?”后的内容

例如:127.0.0.1:8080/hello_servlet/hello?username=zhangsan&password=lisi

上面加上下滑线的部分就是query string

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username=req.getParameter("username");String password=req.getParameter("password");System.out.println("username="+username);System.out.println("password="+password);resp.getWriter().write("ok");}
}

这里前后端约定请求中给定的query string是形如:username=xxxx&password=xxx

上述query string会被tomcat自动解析成一个Map这样的结构

getParameter就是在查询Map<String,String>里面的内容

注:一般使用Query String都是在GET请求中使用,而POST请求一般都是使用form表单

2.使用form表单:

form表单是通过http请求的body来获取表单,body的格式就是query string

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username=req.getParameter("username");String password=req.getParameter("password");System.out.println("username="+username);System.out.println("password="+password);resp.getWriter().write("ok");}
}

这里可以发现代码的写法和上面的query string代码是完全相同的,只是把GET改成了POST,但是,实际上的差别还是很大的;query string是把键值对写在url中,而form表单是把键值对写在body之中

请添加图片描述

通过postman来构造一个post请求,去验证服务器代码

从postman进行构造就可以很容易的发现form表单发送post请求的方式是通过body进行的

3.使用json:

前面两种方式都是servlet天然支持的,但是json是需要引入第三方

此处为了针对json格式的数据进行解析和构造,就要引入json的库

Step1:下载json库:

在浏览器找到maven中央仓库,然后搜索Jackson Dateblind,然后找到任意一个版本进行复制,最后粘贴到pom.xml之中

请添加图片描述

Step2:使用Jackson,一个类,两个方法

类:objectMapper

两个方法:read方法(把json字符串映射成一个java对象) write方法(把java对象,映射成json字符串)

站在服务器的角度上,收到的请求就是json字符串,就需要把json字符串先映射成java对象,再进行一系列业务逻辑处理,处理完之后,把java对象映射回json字符串,并且通过响应来返回

class Request{public String username;public String password;
}class Response{public boolean ok;
}
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ObjectMapper objectMapper=new ObjectMapper();Request request=objectMapper.readValue(req.getInputStream(),Request.class);System.out.println("username="+request.username);System.out.println("password="+request.password);Response response=new Response();response.ok=true;String respJson=objectMapper.writeValueAsString(response);resp.setContentType("application/json; charset=utf8");resp.getWriter().write(respJson);}
}

下面解释一下上面的代码:

首先doGet方法里的第一条就是刚才说的那个类(ObjectMapper),在写json的时候一定要先把这个类进行实例话;

然后来到第二行,我们要想在下面对来的数据进行更改和使用,就要先将数据转变成我们能处理的形式,所有就需要把json字符串映射成一个java对象,那么这个java对象需要一个类来进行接收,这个类中要包含json字符串中的所有的key,这样就可以把json字符串转换成我们想要的样子了,readvalue括号中第一个是表示通过获取流对象,来得到到body中的内容,第二个表示把拿到的东西转换成什么样的形式

然后下面的打印就是根据获取到的username和password进行处理

接着到了把java对象转回json字符串了,因此先在最上方写一个类,类中把要转换的对象写出,然后下面代码中进行实例话,接着对变量进行赋值

然后使用一个字符串来接收转换的结果,使用writeValueAsString这个方法,对实例话的类进行转换

最后指定返回的类型和编码方式,然后进行打印

七。Cookie和Session

1.概述:

Cookie是Http请求中header中的一个机制,也是浏览器持久话存储数据的一种机制

页面无法访问主机的文件系统,要想存储数据,就要通过其他方式

cookie中保存数据也是以键值对的形式,最终还是要把这个键值对返回给服务器的,服务器要使用cookie来完成一系列的业务逻辑

其中就有一种情况,是会使用cookie存储当前用户的身份信息

假设去医院挂号,医生给了一个就诊卡,这个就诊卡就相当于cookie,就诊卡中存储来用户的身份信息(身份标识),拿着这个就诊卡去各个科室,见到医生之后,医生会让你先刷就诊卡,刷卡这个过程,就会通过医院的系统,查询你的身份标识,进一步得到完成的身份信息(当前诊断信息,过往开药信息,以往病例,账户余额…)

每个患者都有这样的一份数据,那么这些数据在服务器中如何组织的呢?那必然是存储在数据库之中的

在服务器代码逻辑展开执行的过程中,这些数据就会被从数据库中查询出来,把他们先临时保存到某个内存结构中,后续有修改之类的,直接修改内存,然后重新写入数据库

这个内存结构就叫会话(session)

cookie是客户端存储数据的机制:在cookie中存储的用户身份标识,也经常被理解成sessionid

session是服务器存储数据的机制(不算持久化存储):服务器中有很多session,也有不同的sessionid

服务器通常会使用hash这样的键值对形式来存储session的,sessionid就是key,session本身就是value,在session里面存储用户的自身信息(是程序员自定的)

请添加图片描述

2.通过servlet api来操作上述结构:

cookie是浏览器的机制,servlet提供了api获取到cookie

session是服务器机制,servlet也提供了api来让我们使用

(1).HttpServletRequest类中的方法

(1)Cookie[ ] getCookies( ) :这个方法拿到请求中所有的cookie内容,每个cookie都是一个键值对

(2)HttpSession getSession( ) :这个方法就能完成,从cookie中获取到sessionid,并且查询到对应的session的过程;如果当前sessionid没查到,那么也能自动化的创建出新的键值对(分配新的sessionid,以及创建一个新的HttpSession对象),这个方法常用在登陆场景中

这里的HttpSession在servlet中表示一个会话,服务器上同时含有多个会话,服务器上会存在一个类似于这样的HashMap<String,HttpSession>,这里的String就是sessionid,HttpSession就是session对象

(2).HttpServletResponse类中的方法:

void addCookie(Cookie cookie):把指定的cookie添加到响应之中

(3).HttpSession类中的方法:

一个HttpSession对象里面包含多个键值对,我们往HttpSession中存任何我们需要的信息

(1)Object getAttribute(String name):该方法返回在该session对象中指定名称的对象,如果没有这个指定名称,那么就返回null

(2)void setAttribute(String name, object value):该方法用指定的名称绑定一个对象到该session对象(就是往session中添加元素内容)

(3)boolean isNew( ):判断当前是否创建出新对话

(4).cookie类中的方法:

每个cookie对象就是一个键值对

(1)String getName( ):该方法返回的是cookie的名称,名称在创建之后不能改变

(2)String getValue( ):获取于cookie相关联的值

(3)String setValue( ):设置于cookie相关的值

3.实战:用户登陆:

实际上cookie和session机制重要的作用就是辅助完成登陆功能的实现

Step1:写登陆的前端页面(html)

请添加图片描述

<form action="login" method="post"><input type="text" name="username"><input type="text" name="password"><input type="submit" name="登陆">
</form>

假设使用form表单,要求为Post请求,login路径

当然此处也可使用json,但是使用json就不能使用form表单了,使用json就要通过ajax的方式构造请求

注:浏览器构造http请求,有这么几种方式

1.url输入地址(GET)

2.特殊的html标签(a,img,script)(GET)

3.form表单(GET,POST)

4.ajax(GET,POST,PUT,DELETE…)

Step2:写一个Servlet处理请求
@WebServlet("/login")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.先读取传来的数据req.setCharacterEncoding("utf8");String username=req.getParameter("username");String password=req.getParameter("password");//2.验证账户和密码是否正确//此处为了简单一点,就不使用数据库了,先把用户名和密码写死,假设用户名是zhangsan,密码是123if(!"zhangsan".equals(username)||!"123".equals(password)){//登陆失败resp.setContentType("text/html; charset=utf8");resp.getWriter().write("当前用户名或者密码错误");return;}//登陆成功HttpSession session=req.getSession(true);session.setAttribute("username",username);//登陆成功之后跳转到的页面resp.sendRedirect("index");}
}

前面的内容都容易理解,从登陆成功之后开始解析:

HttpSession session=req.getSession(true);这个方法就是根据请求中的sessionid查询服务器的hash表,从而找到session对象;如果此时cookie中没有sessionid(首次登陆就是没有的)或者没有查询到session对象,那么就看自动创建一个sessionid和一个session对象,把这个键值对保存到hash表之中,并且会把sessionid设置到响应之中,传回给浏览器,让浏览器使用cookie来进行保存

session.setAttribute(“username”,username);这里使用attribute的作用就是为了让一个数据在多个servlet之间共享,同时attribute是会话级的,每个用户都有自己的数据,相互之间不会干扰
请添加图片描述

这就能很好的说明,同样的页面,不同的用户看到的数据是不同的,例如支付宝查看余额

Step3:跳转的网页的后端代码
@WebServlet("/index")
public class jump extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//先获取到用户对应的会话对象,生成的页面要根据当前用户的信息来进行构造HttpSession session=req.getSession(false);//sessionid不存在if(session==null){resp.setContentType("text/html;charset=utf8");resp.getWriter().write("不可登陆");return;}//从会话中拿到之前存储的用户信息String username= (String) session.getAttribute("username");//生成一个页面,把上述数据显示到页面上resp.setContentType("test/html;charset=utf8");String respBody="欢迎你"+username;resp.getWriter().write(respBody);}
}

HttpSession session=req.getSession(false);这句话表示根据cookie中的sessionid来查询Servlet这里的hash表,参数设置成false,如果查到了,就直接返回,没查到,就返回null

因为是跳转到页面,所以要使用GET请求

String username= (String) session.getAttribute(“username”);由于get Attribute是object类型,所以要进行强转

当验证通过就会保存会话信息(hash),客户端也会保存身份标识(sessionid);后续浏览器再访问这个网站都会带上cookie,服务器不要让浏览器重新登录,也能识别出浏览器的用户身份信息

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

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

相关文章

OpenSource - 开源日历库tui.calendar

文章目录 强大且灵活的开源日历库推荐&#xff1a;tui.calendar多视图支持&#xff1a; Monthly, Weekly, Daily and Various View Types支持拖拽: Dragging and Resizing a Schedule事件管理支持多语言集成与扩展高度定制化其他功能地址总结 强大且灵活的开源日历库推荐&#…

关于Chrome浏览器F12调试,显示未连接到互联网的问题

情况说明 最近笔者更新下电脑的Chrome浏览器&#xff0c;在调试前端代码的时候&#xff0c;遇到下面一个情况&#xff1a; 发现打开调试面板后&#xff0c;页面上显示未连接到互联网&#xff0c;但实际电脑网络是没有问题的&#xff0c;关闭调试面板后&#xff0c;网页又能正…

防砸安全鞋这样挑,舒适又安心!

在复杂多变的工作环境中&#xff0c;安全始终放在首位&#xff0c;特别是对于那些在工地、车间等危险环境中工作的朋友们来说&#xff0c;一双好的防砸安全鞋无疑是工作中的“守护神”。然而&#xff0c;市面上的防砸安全鞋种类繁多&#xff0c;如何挑选一双既舒适又安心的鞋子…

汇川技术即将在工博会发布类博途全集成自动化平台,德国研发中心功不可没,投资数亿打造工业利器

在即将拉开帷幕的9月中国工博会上&#xff0c;汇川技术将向世界展示其自主研发的全新成果——IFA&#xff0c;一个全集成、全场景覆盖的工厂自动化软件平台。这一平台的发布&#xff0c;不仅标志着汇川技术在工业自动化领域的又一里程碑式突破&#xff0c;更彰显了其与国际工业…

VS code Jupyter notebook 导入文件目录问题

VS code Jupyter notebook 导入文件目录问题 引言正文引言 这几天被 VS code 中 Jupyter Notebook 中的文件导入折磨的死去活来。这里特来说明一下放置于不同文件夹下的模块该如何被导入。 正文 首先,我们需要按下 Ctrl + , 键打开设置,然后搜索 notebook file root。在如…

五.海量数据实时分析-FlinkCDC+DorisConnector实现数据的全量增量同步

前言 前面四篇文字都在学习Doris的理论知识&#xff0c;也是比较枯燥&#xff0c;当然Doris的理论知识还很多&#xff0c;我们后面慢慢学&#xff0c;本篇文章我们尝试使用SpringBoot来整合Doris完成基本的CRUD。 由于 Doris 高度兼容 Mysql 协议&#xff0c;两者在 SQL 语法…

G2O (General Graph Optimization)

前言 以高翔的《视觉SLAM14讲》中的 g2o 拟合曲线为例&#xff0c;讲解 g2o 的使用。源文件为 g2oCurveFitting.cpp。 #include <iostream> #include <g2o/core/g2o_core_api.h> #include <g2o/core/base_vertex.h> #include <g2o/core/base_unary_edge.…

一文读懂:监督式微调(SFT)

监督式微调 (Supervised fine-tuning)&#xff0c;也就是SFT&#xff0c;就是拿一个已经学了不少东西的大型语言模型&#xff0c;然后用一些特定的、已经标记好的数据来教它怎么更好地完成某个特定的任务。就好比你已经学会了做饭&#xff0c;但是要特别学会怎么做川菜&#xf…

计算机网络的整体认识---网络协议,网络传输过程

计算机网络背景 网络发展 独立模式: 计算机之间相互独立; 网络互联: 多台计算机连接在一起, 完成数据共享; 局域网LAN: 计算机数量更多了, 通过交换机和路由器连接在一起; 广域网WAN: 将远隔千里的计算机都连在一起;所谓 "局域网" 和 "广域网" 只是一个相…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-28

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-28 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-28目录前言1. Cognitive phantoms in LLMs through the lens of latent variables摘要研究背景问题与挑战创新点算法模型实验效果…

如何调整云桌面安装的虚拟机分辨率?

如何调整云桌面安装的虚拟机分辨率&#xff1f; 1. 编辑GRUB配置文件2. 修改分辨率3. 更新GRUB4. 重启虚拟机 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在云桌面环境中&#xff0c;虚拟机分辨率过低且无法调整时&#xff0c;可以通过以…

【React】react项目中的redux使用

1. store目录结构设计 2. react组件中使用store中的数据——useSelector 3. react组件中修改store中的数据——useDispatch 4. 示例 react-basic\src\store\moduels\counterStore.js import { createSlice } from reduxjs/toolkitconst counterStore createSlice({name: cou…

LeetCode讲解篇之15. 三数之和

文章目录 题目描述题解思路题解代码 题目描述 题解思路 这道题如果我们直接使用三层循环暴力搜索&#xff0c;时间复杂度是O(n3)&#xff0c;大概率会超时 那还有更优解吗&#xff0c;答案是绝对的&#xff0c;查询搜索想要优化&#xff0c;就要思考如何进行排除法加速搜索过…

OIDC6-OIDC 授权流程类型

OpenID Connect&#xff08;OIDC&#xff09;支持三种主要的授权流程&#xff08;Authorization Flow&#xff09;&#xff0c;分别是授权码流程&#xff08;Authorization Code Flow&#xff09;、隐式流程&#xff08;Implicit Flow&#xff09;和混合流程&#xff08;Hybrid…

OpenCV视频I/O(6)检查视频捕获对象是否已成功打开的函数isOpened()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 如果视频捕获已经初始化&#xff0c;则返回 true。 如果之前调用 VideoCapture 构造函数或 VideoCapture::open() 成功&#xff0c;则该方法返回…

File systems

inode descriptor 文件系统中核心的数据结构就是inode和file descriptor。后者主要与用户进程进行交互。 inode&#xff0c;这是代表一个文件的对象&#xff0c;并且它不依赖于文件名。实际上&#xff0c;inode是通过自身的编号来进行区分的&#xff0c;这里的编号就是个整数…

游戏厅计时器ps5计算时间的软件 佳易王电玩计时计费管理系统操作教程

一、前言 游戏厅计时器ps5计算时间的软件 佳易王电玩计时计费管理系统操作教程 软件为绿色免安装版&#xff0c;解压即可使用。 二、软件程序教程 计时的时候&#xff0c;点击 开始计时按钮 开台后可设置定时语音提醒的时间 时间设置好后&#xff0c;点击 开启提醒 即可 三、…

C++远端开发环境安装(centos7)

使用VMWare安装centos7 启用网卡设备 修改文件/etc/sysconfig/network-scripts/ifcfg-ens33中的ONBOOTyes 重启网络服务 systemctl restart network 配置yum仓库 直接将如下内容覆盖原有的/etc/yum.repos.d/CentOS-Base.repo文件 清理yum缓存 yum clean all 刷新yum y…

深度学习常见术语介绍

文章目录 数据集&#xff08;Dataset&#xff09;特征&#xff08;Feature&#xff09;标签&#xff08;Label&#xff09;训练集&#xff08;Training Set&#xff09;测试集&#xff08;Test Set&#xff09;验证集&#xff08;Validation Set&#xff09;模型&#xff08;Mo…

急!现在转大模型还来得及吗?零基础入门到精通,收藏这一篇就够了

大模型的出现&#xff0c;让行内和行外大多数人都感到非常焦虑。 行外很多人想了解却感到无从下手&#xff0c;行内很多人苦于没有硬件条件无法尝试。想转大模型方向&#xff0c;相关的招聘虽然层出不穷&#xff0c;但一般都要求有大模型经验。而更多的人&#xff0c;则一直处…