JavaWeb6、Servlet

6.1Servlet简介

  • Servlet就是sun公司开发动态web的一门技术

  • sun公司在这些API中提供一个接口叫做Servlet,如果想开发一个Servlet程序,只需要完成两个小步骤:

    • 编写一个类,实现Servlet接口

    • 把开发好的Java类部署到web服务器中

把实现了Servlet接口的Java程序叫做Servlet

6.1.1doGet方法

用途:doGet 方法主要用来处理 HTTP 的 GET 请求。当你在浏览器的地址栏输入一个网址然后回车,或者点击网页上的超链接时,浏览器一般就会发送一个 GET 请求到服务器,这时服务器端对应的 Servlet 就会调用 doGet 方法来处理这个请求。

特点:

  • 参数可见:GET 请求会把要传递的数据附加在 URL 后面,就像在地址后面加了个小尾巴,所以这些数据在浏览器的地址栏里是可以直接看到的。比如你搜索 “苹果”,URL 可能就变成 https://example.com/search?keyword=苹果 ,这里的 keyword=苹果 就是传递的数据。

  • 数据量有限:因为 URL 的长度是有限制的,所以 GET 请求能携带的数据量也不能太多。

  • 适合获取数据:它比较适合从服务器获取一些信息,比如查看新闻列表、商品详情等,不会对服务器上的数据进行修改、删除等操作。

6.1.2doPost方法

用途:doPost 方法用于处理 HTTP 的 POST 请求。当你在网页上填写表单(比如注册、登录表单)然后点击提交按钮时,浏览器通常会发送一个 POST 请求到服务器,这时对应的 Servlet 就会调用 doPost 方法来处理这个请求。

特点:

  • 参数不可见:POST 请求会把要传递的数据放在请求的主体部分,不像 GET 请求那样把数据显示在 URL 里,所以数据在浏览器地址栏是看不到的,相对更安全一些。

  • 数据量无限制:它没有 GET 请求那样的数据量限制,可以传递大量的数据,比如上传文件等。

  • 适合提交数据:常用于向服务器提交数据,像注册新用户、添加新商品等操作,可能会对服务器上的数据进行修改、添加等操作。

doGet 主要用于从服务器获取信息,而 doPost 主要用于向服务器提交数据。

6.2HelloServlet

Servlet接口sun公司有两个默认的实现类:HttpServlet,GenericServlet

1.构建一个普通的Maven项目,删掉里面的src目录,以后我们的学习就在这个项目里面建立Moudel;这个空的工程就是maven的主工程;

2.关于Maven父子工程的理解:

在父项目中会有

    <modules>
        <module>servlet-01</module>
    </modules>

子项目中会有

    <parent>
        <groupId>com.zim</groupId>
        <artifactId>javaweb-02-servlet</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

父项目中的jar包子项目可以直接使用

3.Maven环境优化

1.修改web.xml为最新的

2.将maven的结构搭建完整

4.编写一个Servlet程序

1.编写一个普通类

2.实现Servlet接口,这里我们直接继承HttpServlet

public class HelloServlet extends HttpServlet {
​
    //由于Get或者Post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //ServletOutputStream outputStream = resp.getOutputStream();
        PrintWriter writer = resp.getWriter();//响应流
​
        writer.print("Hello,Servlet!");
    }
​
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

5.编写Servlet的映射

为什么需要映射:我们写的是Java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务器中注册我们写的Servlet,还需要给他一个浏览器能访问的路径:

  <!--注册Servlet-->
  <servlet>
    <servlet-name>hello2</servlet-name>
    <servlet-class>com.zim.servlet.HelloServlet</servlet-class>
  </servlet>
  <!--Servlet映射-->
  <servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <!--请求路径-->
    <url-pattern>/hello2</url-pattern>
  </servlet-mapping>

6.配置Tomcat

注意:配置项目发布的路径就可以了

7.启动测试

6.3Servlet原理

Servlet是由web服务器调用,web服务器在收到浏览器请求之后,会:

6.4Mapping问题

1.一个Servlet请求可以指定一个映射路径

  <!--一个Servlet对应一个Mapping映射-->
  <servlet-mapping>
    <servlet-name>helloServlet</servlet-name>
    <!--请求路径-->
    <url-pattern>/zim</url-pattern>
  </servlet-mapping>

2.一个Servlet请求可以指定多个映射路径

  <!--Servlet映射-->
  <servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <url-pattern>/hello2</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <url-pattern>/hello3</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <url-pattern>/hello4</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <url-pattern>/hello5</url-pattern>
  </servlet-mapping>

3.一个Servlet请求可以指定通用映射路径

  <servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <url-pattern>/hello/*</url-pattern>
  </servlet-mapping>

4.默认请求路径(少用)

  <!--默认请求路径-->
  <servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

5.指定一些后缀或者前缀

<!--可以自定义后缀实现请求映射
注意:*前面不能加项目映射的路径
-->  
<servlet-mapping>
    <servlet-name>hello2</servlet-name>
    <url-pattern>*.zim</url-pattern>
  </servlet-mapping>

6.优先级问题

指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;

  <servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.zim.servlet.ErrorServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>error</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

6.5ServletContext

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;

1、共享数据

我在这个Servlet中保存的数据,可以在另外一个Servlet中拿到;

//放置数据的类
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
​
//        this.getInitParameter()   初始化参数
//        this.getServletConfig()   Servlet配置
//        this.getServletContext()  Servlet上下文
        ServletContext context = this.getServletContext();
​
        String username = "郑子铭";//数据
        context.setAttribute("username",username);//将一个数据保存到ServletContext中,名字为:username,值为username
​
        System.out.println("Hello");
    }
//读取数据的类
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");
​
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("名字"+username);
    }
​
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
  <servlet>
  <servlet-name>hello</servlet-name>
  <servlet-class>com.zim.servlet.HelloServlet</servlet-class>
</servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
​
  <servlet>
    <servlet-name>getc</servlet-name>
    <servlet-class>com.zim.servlet.GetServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>getc</servlet-name>
    <url-pattern>/getc</url-pattern>
  </servlet-mapping>

测试访问结果

2、获取初始化参数

在web.xml中配置初始化参数

  <!--配置一些web应用初始化参数-->
  <context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
  </context-param>
public class ServletDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String url = context.getInitParameter("url");
        resp.getWriter().print(url);
    }
​
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
3、请求转发
public class ServletDemo04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        System.out.println(("进去了ServletDemo04"));
        //RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
        //requestDispatcher.forward(req,resp);//调用forward实现请求转发
        context.getRequestDispatcher("/gp").forward(req,resp);
    }
​
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

4、读取资源文件

Properties

  • 在java目录下新建properties

  • 在resources目录下新建properties

发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath:

思路:需要一个文件流

username=root
password=123456
public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties prop = new Properties();
        prop.load(is);
        String user = prop.getProperty("username");
        String pwd = prop.getProperty("password");
​
        resp.getWriter().print(user+":"+pwd);
    }
​
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

访问测试即可

6.6HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,Http请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息

获取参数,请求转发

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
​
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
​
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbys = req.getParameterValues("hobbys");
        System.out.println("===================================");
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbys));
        System.out.println("===================================");
​
        System.out.println(req.getContextPath());
        //通过请求转发
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
    }
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>
    <h1>登录</h1>
    <div style="text-align: center">
        <%--这里表单表示的意思:以post方式提交表单到login请求--%>
        <form action="${pageContext.request.contextPath}/login" method="post">
            用户名:<input type="text" name="username"><br>
            密码:<input type="password" name="password"><br>
            爱好:
            <input type="checkbox" name="hobbys" value="唱歌">唱歌
            <input type="checkbox" name="hobbys" value="代码">代码
            <input type="checkbox" name="hobbys" value="电影">电影
            <input type="checkbox" name="hobbys" value="跳舞">跳舞
            <br>
            <input type="submit">
        </form>
    </div>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>success</title>
</head>
<body>
    <h1>登陆成功</h1>
</body>
</html>

面试题:请你聊聊重定向和转发的区别

相同点:

  • 都可以实现页面跳转

不同点:

  • 请求转发的时候,url不会产生变化;编码307

  • 重定向时,url地址栏会发生变化;编码302

6.7HTTPServletResponse

web服务器接收到客户端的http请求,针对这个请求分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;

  • 如果要获取客户端请求过来的参数:找HttpServletRequest

  • 如果要给客户端响应一些信息:找HttpServletResponse

1、简单分类

负责向浏览器发送数据的方法

  • ServletOutputStream getOutputStream() throws IOException;
    PrintWriter getWriter() throws IOException;

负责向浏览器发送响应头的方法

  •     void setCharacterEncoding(String var1);
    ​
        void setContentLength(int var1);
    ​
        void setContentLengthLong(long var1);
    ​
        void setContentType(String var1);
    ​
        void setDateHeader(String var1, long var2);
    ​
        void addDateHeader(String var1, long var2);
    ​
        void setHeader(String var1, String var2);
    ​
        void addHeader(String var1, String var2);
    ​
        void setIntHeader(String var1, int var2);
    ​
        void addIntHeader(String var1, int var2);

响应的状态码

  •     int SC_CONTINUE = 100;
        int SC_SWITCHING_PROTOCOLS = 101;
        int SC_OK = 200;
        int SC_CREATED = 201;
        int SC_ACCEPTED = 202;
        int SC_NON_AUTHORITATIVE_INFORMATION = 203;
        int SC_NO_CONTENT = 204;
        int SC_RESET_CONTENT = 205;
        int SC_PARTIAL_CONTENT = 206;
        int SC_MULTIPLE_CHOICES = 300;
        int SC_MOVED_PERMANENTLY = 301;
        int SC_MOVED_TEMPORARILY = 302;
        int SC_FOUND = 302;
        int SC_SEE_OTHER = 303;
        int SC_NOT_MODIFIED = 304;
        int SC_USE_PROXY = 305;
        int SC_TEMPORARY_REDIRECT = 307;
        int SC_BAD_REQUEST = 400;
        int SC_UNAUTHORIZED = 401;
        int SC_PAYMENT_REQUIRED = 402;
        int SC_FORBIDDEN = 403;
        int SC_NOT_FOUND = 404;
        int SC_METHOD_NOT_ALLOWED = 405;
        int SC_NOT_ACCEPTABLE = 406;
        int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
        int SC_REQUEST_TIMEOUT = 408;
        int SC_CONFLICT = 409;
        int SC_GONE = 410;
        int SC_LENGTH_REQUIRED = 411;
        int SC_PRECONDITION_FAILED = 412;
        int SC_REQUEST_ENTITY_TOO_LARGE = 413;
        int SC_REQUEST_URI_TOO_LONG = 414;
        int SC_UNSUPPORTED_MEDIA_TYPE = 415;
        int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
        int SC_EXPECTATION_FAILED = 417;
        int SC_INTERNAL_SERVER_ERROR = 500;
        int SC_NOT_IMPLEMENTED = 501;
        int SC_BAD_GATEWAY = 502;
        int SC_SERVICE_UNAVAILABLE = 503;
        int SC_GATEWAY_TIMEOUT = 504;
        int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
    ​
2、下载文件

1.向浏览器输出消息

2.下载文件

1.要获取下载文件的路径

2.下载的文件名是啥

3.设置想办法让浏览器能够支持下载我们需要的东西

4.获取下载文件的输入流

5.创建缓冲区

6.获取OutputStream对象

7.将FileOutputStream流写入到buffer缓冲区

8.使用OutputStream将缓冲区中的数据输出到客户端

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.要获取下载文件的路径
        String realPath = "F:\\SVN项目文件\\code\\javaweb-01-maven\\javaweb-02-servlet\\response\\target\\classes\\1.png";
        System.out.println("下载文件的路径:"+realPath);
        //2.下载的文件名是啥
        String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
        //3.设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,让中文文件名URLEncoder.encode编码,否则有可能是乱码
        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
        //4.获取下载文件的输入流
        FileInputStream in = new FileInputStream(realPath);
        //5.创建缓冲区
        int len = 0;
        byte[] buffer = new byte[1024];
        //6.获取OutputStream对象
        ServletOutputStream out = resp.getOutputStream();
        //7.将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端
        while((len=in.read(buffer))>0){
            out.write(buffer,0,len);
        }
        //8.把流关闭
        in.close();
        out.close();
    }
3、验证码功能

验证码怎么来的

  • 前端实现

  • 后端实现,需要用到java的图片类,生成一个图片

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //如何让浏览器3秒自动刷新一次
        resp.setHeader("refresh","3");
        //在内存中创建一个图片
        BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
        //得到图片
        Graphics2D g = (Graphics2D) image.getGraphics();//笔
        //设置图片的背景颜色
        g.setColor(Color.white);
        g.fillRect(0,0,80,20);
        //给图片写数据
        g.setColor(Color.BLUE);
        g.setFont(new Font(null,Font.BOLD,20));
        g.drawString(makeNum(),0,20);
        //告诉浏览器这个请求用图片的方式打开
        resp.setContentType("image/jpeg");
        //网站存在缓存,不让浏览器缓存
        resp.setDateHeader("expires",-1);
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("Pragma","no-cache");
​
        //把图片写给浏览器
        ImageIO.write(image,"jpg", resp.getOutputStream());
    }
​
    //生成随机数
    private String makeNum(){
        Random random = new Random();
        String num = random.nextInt(9999999) + "";
        StringBuffer sb = new StringBuffer();
        for (int i=0;i<7-num.length();i++){
            sb.append("0");
        }
        num = sb.toString() + num;
        return num;
    }
4、实现重定向(重要)

一个web资源B收到客户端A请求后,他会通知客户端A去访问另外一个web资源C,这个过程叫重定向

常见场景:

  • 用户登录

    void sendRedirect(String var1) throws IOException;

测试:

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*
        resp.setHeader("Location","/r/img");
        resp.setStatus(302);
        */
        resp.sendRedirect("/r/img");//重定向
    }

面试题:请你聊聊重定向和转发的区别?

相同点:

  • 都可以实现页面跳转

不同点:

  • 请求转发

    • url不会产生变化

    • 服务器端操作:转发是在服务器端完成的,客户端不知道请求被转发了。服务器内部将请求从一个资源传递到另一个资源。

    • 性能较高:由于转发发生在服务器内部,减少了网络开销,通常性能较高。

  • 重定向

    • 重定向时,url地址栏会发生变化

    • 客户端操作:重定向是通过客户端完成的。服务器返回一个响应,指示客户端向另一个 URL 发起新的请求。

    • 性能稍低:重定向会导致额外的网络往返,因为需要先接收重定向响应,然后再次发起请求,这可能会稍微增加响应时间。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

论文粗读——Isometric 3D Adversarial Examples in the Physical World

论文地址:Isometric 3D Adversarial Examples in the Physical World 动机 现有的3D点云攻击方法远远不够隐蔽,并且在物理世界中性能严重下降。 已有方法及其不足 基于梯度的攻击->仅限于数字世界攻击;KNN攻击和GeoA3攻击->点云重建引入了较大的噪声和错误,导致攻…

AI视频领域的DeepSeek—阿里万相2.1图生视频

让我们一同深入探索万相 2.1 &#xff0c;本文不仅介绍其文生图和文生视频的使用秘籍&#xff0c;还将手把手教你如何利用它实现图生视频。 如下为生成的视频效果&#xff08;我录制的GIF动图&#xff09; 如下为输入的图片 目录 1.阿里巴巴全面开源旗下视频生成模型万相2.1模…

微电网协调控制器ACCU-100 分布式光伏 光储充一本化

安科瑞 华楠 18706163979 应用范围&#xff1a; 分布式光伏、微型风力发电、工商业储能、光储充一体化电站、微电网等领域。 主要功能&#xff1a; 数据采集&#xff1a;支持串口、以太网等多通道实时运行&#xff0c;满足各类风电与光伏逆变器、储能等 设备接入&#xff…

Android MVC、MVP、MVVM三种架构的介绍和使用。

写在前面&#xff1a;现在随便出去面试Android APP相关的工作&#xff0c;面试官基本上都会提问APP架构相关的问题&#xff0c;用Java、kotlin写APP的话&#xff0c;其实就三种架构MVC、MVP、MVVM&#xff0c;MVC和MVP高度相似&#xff0c;区别不大&#xff0c;MVVM则不同&…

懒加载预加载

&#xff08;一&#xff09;、懒加载 1.什么是懒加载&#xff1f; 懒加载也就是延迟加载。当访问一个页面的时候&#xff0c;先把img元素或是其他元素的背景图片路径替换成一张大小为1*1px图片的路径&#xff08;这样就只需请求一次&#xff0c;俗称占位图&#xff09;&#…

Python 中的析构函数:对象生命周期的终结艺术

在 Python 的面向对象编程中&#xff0c;析构函数是一个重要的概念。它主要用于在对象被销毁之前执行一些清理工作&#xff0c;如释放资源、关闭文件或网络连接等。本文将详细介绍 Python 中的析构函数&#xff0c;包括其定义、语法、调用时机以及实际应用场景。 一、什么是析…

使用QT + 文件IO + 鼠标拖拽事件 + 线程 ,实现大文件的传输

第一题、使用qss&#xff0c;通过线程&#xff0c;使进度条自己动起来 mythread.h #ifndef MYTHREAD_H #define MYTHREAD_H#include <QObject> #include <QThread> #include <QDebug>class mythread : public QThread {Q_OBJECT public:mythread(QObject* …

在 macOS 上使用 CLion 进行 Google Test 单元测试

介绍 Google Test&#xff08;GTest&#xff09;是 Google 开源的 C 单元测试框架&#xff0c;它提供了简单易用的断言、测试夹具&#xff08;Fixtures&#xff09;和测试运行机制&#xff0c;使 C 开发者能够编写高效的单元测试。 本博客将介绍如何在 macOS 上使用 CLion 配…

[MySQL初阶]MySQL(5)内置函数详解

标题&#xff1a;[MySQL初阶]MySQL&#xff08;5&#xff09;内置函数详解 水墨不写bug 文章目录 一、日期函数1. current_date()2. current_time()3. current_timestamp()4. date(datetime)5. date_add(date, interval expr unit)6. date_sub(date, interval expr unit)7. dat…

【MySQL】事务(隔离性、MVCC)

文章目录 1. 事务的概念2. 事务的提交方式3. 事务常见操作4. 隔离性4.1 隔离级别4.2 查看与设置隔离性4.3 隔离级别的测试 5. 隔离性的原理5.1 MVCC5.1.1 3个隐藏字段5.1.2 undo日志5.1.3 模拟MVCC 5.2 Read view5.3 RR与RC的本质区别 1. 事务的概念 在之前所有的SQL操作中&am…

单细胞分析(22)——高效使用 Cell Ranger:安装、参数解析及 Linux 后台运行指南

高效使用 Cell Ranger&#xff1a;安装、参数解析及 Linux 后台运行指南 背景介绍 Cell Ranger 是 10x Genomics 开发的一套用于单细胞转录组测序数据处理的软件。它可以对 10x Genomics 平台生成的 FASTQ 文件进行对齐、UMI 计数和基因表达量计算&#xff0c;是单细胞 RNA-se…

IEEE paper submission

author guideline IEEE 文章模板&#xff1a;https://template-selector.ieee.org/ 1&#xff09;Manuscripts that exceed eight pages will incur mandatory over-length page charges. (超过 8 页强制收费 $175/page) 2&#xff09;Authors are invited to submit manus…

NET431-C协议网关:跨网段·零编程PLC工业通信终极方案

系统框架图解析 三层架构&#xff0c;一图读懂&#xff1a; 设备层&#xff1a; 4个网口2个网段&#xff1a;直连AB、西门子、三菱等18台PLC&#xff0c;覆盖4个网段&#xff08;如10.1.1.0/24、192.168.2.0/24&#xff09;&#xff0c;协议转换。5路RS485串口&#xff1a;通过…

nvm 让 Node.js 版本切换更灵活

有很多小伙伴前端开发进程中&#xff0c;我们常常会遇到不同项目依赖不同版本 Node.js 的情况。我们不可能去卸载重新安装适应的版本去安装依赖或者启动项目。为了避免版本冲突带来的一系列麻烦&#xff0c;在这里给大家推荐一款Node.js 版本管理工具——nvm&#xff08;Node V…

豆包大模型 MarsCode AI 刷题专栏 001

001.找单独的数 难度&#xff1a;易 问题描述 在一个班级中&#xff0c;每位同学都拿到了一张卡片&#xff0c;上面有一个整数。有趣的是&#xff0c;除了一个数字之外&#xff0c;所有的数字都恰好出现了两次。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上…

迭代器模式:遍历集合的艺术

文章目录 什么是迭代器模式&#xff1f;现实中的例子迭代器模式的结构代码示例1. 定义Iterator接口2. 实现ConcreteIterator3. 定义Aggregate接口4. 实现ConcreteAggregate5. 客户端代码输出结果 迭代器模式的优缺点优点缺点 总结 在软件开发中&#xff0c;我们经常需要遍历集合…

通用文件模型

一、通用文件模型 通常一个完整的Linux系统有数千到数百万个文件组成&#xff0c;文件中存储了程序、数据和各种信息。层次化的目录结构用于对文件进行编排和分组。 1.ReiserFS(新型的文件系统) -->Reiser4 它通过一种与众不同的方式----完全平衡树来容纳数据&#xff0c;包…

DeepSeek + 飞书多维表格搭建你的高效工作流

众所周知&#xff0c;大模型DeepSeek擅长于处理大规模语言模型推理任务&#xff0c;特别是在成本降低和思维链推理方面表现出色‌&#xff0c;我们一般把大模型必做我们的大脑&#xff0c;但是一个人不能只有大脑&#xff0c;还需要其他输入输出以及操作支配的眼耳鼻嘴手足等。…

微服务架构下的 Node.js

Node.js 在微服务架构中的特点 轻量级和高效性 Node.js 以其轻量级和高效的特点&#xff0c;非常适合构建微服务架构。它具有事件驱动和非阻塞 I/O 模型&#xff0c;能够在处理高并发请求时表现出色。这意味着 Node.js 可以同时处理大量的并发连接&#xff0c;而不会因为阻塞…

用DeepSeek-R1-Distill-data-110k蒸馏中文数据集 微调Qwen2.5-7B-Instruct!

下载模型与数据 模型下载&#xff1a; huggingface&#xff1a; Qwen/Qwen2.5-7B-Instruct HF MirrorWe’re on a journey to advance and democratize artificial intelligence through open source and open science.https://hf-mirror.com/Qwen/Qwen2.5-7B-Instruct 魔搭&a…