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

从Cookie到Session: Servlet API中的会话管理详解

文章目录

  • 一. Cookie与Session
    • 1. Cookie与Session
    • 2. Servlet会话管理操作
  • 二. 登录逻辑的实现

一. Cookie与Session

1. Cookie与Session

首先, 在学习过 HTTP 协议的基础上, 我们需要知道 Cookie 是 HTTP 请求报头中的一个关键字段, 本质上是浏览器在本地存储数据的一种机制, 要清楚 Cookie 是从哪里来, 要到哪里去.

Cookie 是来自于服务器的, 通过响应报文中的 Set-Cookie 字段将数据返回保存在浏览器本地的; 后续当浏览器访问服务器的时候, 就会把本地的 Cookie 通过 HTTP 请求给带过去.

HTTP 协议是 “无状态” 协议, 这里的 “无状态” 指的是默认情况下 HTTP 协议的客户端和服务器之间的每次通信, 和它之前之后的通信是没有直接的联系的, 但是在实际开发中多次通信是需要建立起 “上下文” 联系的, 用户发起请求通过 Cookie 字段将 Cookie 中的内容发送到服务器, 服务器就能知道和客户端的上一次通信处于什么样的状态, 此时 Cookie 这种机制就有了用武之地, 最典型的一种应用, 就是使用 Cookie 来标识用户的身份信息.

常见的网站登录, 比如淘宝, 我们登录一次网站后, 后续再使用访问淘宝的其他页面, 是不需要再次登录的, 还有自动登录功能, 隔了一段时间再次访问淘宝网站, 我们会发现此时并不需要再次输入账号密码登录, 网站就会自动地帮我们登录.

为了实现这种网站自动登录和访问的功能, 就可以将 SessionCookie 搭配使用, 在用户在输入账号密码登录在淘宝服务器查询数据库验证通过后, 服务器会创建一个 Session 会话来保存当前用户的数据和信息, 并生成一个 Cookie 数据.

该 Session 中包含用户一些关 '键身份信息, 服务器会给这个用户分配一个表示身份的序号, 是具有唯一性的整数/字符串 (SessionId), 服务器使用类似于 Hash 表这样的结构把身份序号 (SessionId) 作为 Key, 身份信息 (Session) 作为 Value 存储起来, 这样的每一对键值对就是一个 Session 会话.

服务器给客户端返回的 Cookie 里面就包含 SessionId, 浏览器就会在本地将这个 Cookie 储存起来, 后续浏览器发送请求的时候就会带上这个 Cookie, 服务器收到 Cookie 中的身份序号后, 就会查询 Session 会话表, 如果存在就会可以正常访问, 不用重复的输入账号与密码, 否则就需要用户重新输入账号密码进行登录.

img

有时候我们会发现登录网站后隔一段时间再次登录, 会出现让我们再次输入账号密码的情况, 此时就是登录状态失效过期了, 这种情况可能是可能是客户端把 Cookie 删了, 也可能是服务器这把对应的身份信息删了.

举个生活中里例子, 去医院看病需要先挂号, 如果你是第一次去这家医院的, 就会给你新办理一个就诊卡, 这个就诊卡里面就含有你的一些关键身份信息, 并且会在医院的服务器上新建一个档案, 拿着这个就诊卡, 你就可以在该医院的各个科室进行刷卡, 如果你之前在这个医院有就诊记录, 你一刷卡就可以查询到你所有在医院的就诊信息.

这个例子中的就诊卡就相当于是 Cookie, 上面有你最基本的身份信息, 在医院服务器上所储存有关你的详细信息, 就相当于一个 Session 会话, 服务器上包含很多用户的就诊信息, 即会有多个 Session 会话对应不同的用户.

🎯要注意理解 Cookie 和 Session 之间的区别和关联.

  • 关联: 在网站登录功能中可以搭配使用.
  • 区别:
  1. Cookie 是客户端的存储机制, Session 是服务器的存储机制.
  2. Cookie 里面可以存各种键值对 (还可以存除 SessionId 以外的), Session 则专门用来保存用户信息.
  3. Cookie 完全可以单独使用, 不搭配 Session (实现非登录的场景), Session 也可以不搭配 Cookie (手机 App 登录服务器, 此时也需要 Session, 但这里没有 Cookie 的概念, Cookie 和浏览器强相关的).
  4. Cookie 是 HTTP 协议中的一个部分, Session 则可以和 HTTP 无关 (TCP, WebSocket …也可以用 Session).

2. Servlet会话管理操作

HttpServletRequest 类中, 可以使用 getSession 来获取或者创建会话, getCookies 可以获取请求中的 Cookie 列表.

方法描述
HttpSession getSession()在服务器中获取会话. 参数如果为 true, 则当不存在会话时新建会话; 参数如果为 false, 则当不存在会话时返回 null
Cookie[] getCookies()返回一个数组, 包含客户端发送该请求的所有的 Cookie 对象. 会自动把Cookie 中的格式解析成键值对.

调用 getSession 方法所做的事情:

getSession 有一个 boolean 类型的参数, 如果参数是 true, 它有如下行为:

  1. 读取 cookie 里的 sessionId 字段.
  2. 根据 sessionld 来查询对应的 HttpSession 对象在服务器上是否存在.
  3. 如果不存在, 就创建一个新的会话, 即创建一个新的 HttpSession 对象, 并生成一个唯一的 sessionId, 会以新生成的 sessionId 作为 Key, 生成的 HttpSession 对象作为 Value, 以键值对形式储存到类似于 Hash 的结构中, 然后将 sessionId 设置到响应报文中的 set-Cookie 字段返回给浏览器.
  4. 如果存在就直接返回查询到的 HttpSession 对象.

如果参数是 false, 行为如下:

  1. 读取 cookie 里的 sessionId 字段.
  2. 根据 sessionld 来查询对应的 HttpSession 对象在服务器上是否存在.
  3. 如果不存在, 直接返回 null.
  4. 如果存在就直接返回查询到的 HttpSession 对象.

总之就是, getSession 的参数为true 时允许创建 Session 会话, 为false 时不允许创建 Session 会话.

🍂关于HttpSession
这个对象也可以看作是一个哈希表, 是以键值对的形式存储数据的, 并且允许程序员在对象中储存任意的键值对数据, 但是 Key 必须是 String 类型, Value 的类型是 Object, 设置就比较随意了.

该类中提供了两个方法可以用来获取该对象中键值和设置键值对.

方法描述
Object getAttribute(String name)查询 session 会话中指定键的键值, 查不到则返回 null.
void setAttribute(String name, Object value)绑定一个键和值到该 session 会话中
boolean isNew()判定当前是否是新创建出的会话

所以服务器组织会话的方式就如下图:

img

二. 登录逻辑的实现

我们这里模拟实现一个登录的功能, 很多网站都会让你先登录, 才能使用其中的一些功能, 我们这里实现登录完成之后, 就跳到另一个主页, 不进行登录的话, 这个主页是不能被访问的.

所以, 我们这里主要涉及到两个页面, 第一个是登录页面, 第二个是登录成功后要跳转的主页面.

登录页面包含两个输入框 (用来输入用户名和密码) 和一个登录按钮, 点击登录按钮就会发起一个 HTTP 请求, 服务器处理这个请求的时候就会验证用户名和密码, 验证通过就会跳转到主页, 主页就简单的显示出当前用户的用户名就行了.

实现整这里的逻辑就涉及到两个 Servlet 类:

  1. 处理登录的 LoginServlet, 用来判段用户名和密码, 登录成功和登录失败的情况.
  2. 构造主页面的 IndexServlet, 用来构造登录成功的主页.

img

1️⃣第一步, 约定前后端接口.
我们需要实现两套交互逻辑, 一是登录跳转, 二是获取主页.
登录跳转, 这里只是示范作用, 约定只有一个用户, 就不加数据库的逻辑了.

约定用户名就是 zhangsan, 密码就是 123, 使用 POST 请求, 响应采用 302 重定向.
img
获取主页, 采用 GET 请求, 响应返回一个页面.
img
2️⃣第二步, 编写前端交互页面

目标页面如下:
img
这里的场景很简单. 就直接使用 form 表单构造来 Post 请求了.

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>login</title>
</head>
<body><form action="login" method="post"><span>用户名</span><input type="text" name="username"><span>密码</span><input type="password" name="password"><input type="submit" value="登录"></form>
</body>
</html>

3️⃣第三步, 编写后端处理代码

对于登录跳转主页的 Post 请求处理思路如下:

  • 从请求中获取用户名和密码.
  • 验证用户名和密码是否正确, 正常来说是要查询数据库的, 这里就不添加数据库的逻辑了.
  • 如果验证通过, 创建会话, 并将 username 和主页被访问的次数数据添加到会话中 (保存必要的用户信息), 创建好会话后, 重定向到主页index.
  • 如果验证不通过, 重定向到登录页面.
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;@WebServlet("/login")
public class LoginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf8");resp.setCharacterEncoding("utf8");// 获取用户名和密码String username = req.getParameter("username");String password = req.getParameter("password");// 验证用户名密码是否正确// 这里约定合法的用户名为zhangsan,密码是123if (username.equals("zhangsan") && password.equals("123")) {// 登陆成功!!// 创建一个会话HttpSession session = req.getSession(true);// 把当前的用户名保存到会话中session.setAttribute("username", username);// 设置初始情况下登录成功访问主页的次数为0session.setAttribute("count", 0);// 重定向到主页resp.sendRedirect("index");} else {// 登陆失败!!// 重定向到 登陆页面System.out.println("用户名或者密码错误!");resp.sendRedirect("login.html");}}
}

获取主页的 GET 请求处理思路:

  • 获取会话 (请求中包含 sessionId, 会话是根据 sessionId 获取的)
  • 取出会话信息, 将主页返回次数加 1 并写回到会话信息中.
  • 返回一个简单的页面, 显示用户名和主页访问次数.
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;@WebServlet("/index")
public class IndexServlet extends HttpServlet {// 重定向, 浏览器发起的是GET请求@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 先判定用户的登陆状态.// 如果用户还没登陆, 要求先登陆.// 已经登陆了, 则根据会话中的用户名, 将相关信息显示到页面上.HttpSession session = req.getSession(false);if (session == null) {// 未登录状态System.out.println("用户未登录!");// 重定向到登录页面resp.sendRedirect("login.html");return;}// 已经登陆, 取出会话信息String username = (String)session.getAttribute("username");Integer count = (Integer)session.getAttribute("count");// 访问次数加 1 后再写回到会话中count++;session.setAttribute("count", count);// 构造页面resp.setContentType("text/html;charset=utf8");resp.getWriter().write("<h3>欢迎您!" + username + "</h3> <h4>这个主页已经被访问了" + count + "次</h4>");}
}

抓包分析交互过程:
img
第一次交互, 浏览器从服务器获取登录页面.

img
第二次交互, 浏览器给服务器一个登录请求, 服务器返回响应, 重定向页面.

img
第三次交互, 浏览器收到 302 重定向响应后, 再次向服务器发起请求, 访问主页.

img

响应结果:

img

用户名或者密码错误的情况下:

img

img

未登录直接访问的情况下:

img

img

这里关于 IDEA 集成的 Tomcat 环境有一些需要注意的点, 正常来说, 上面说的 sessionId 并不会一直存在下去, 比如 Tomcat 服务器重新启动的时候, 原来服务器在内存中维护的会话 Hash 表就应该没有了, 此时再次访问, 就应该出现 sessionld 查不到, 就被识别成 “未登录” 状态了, 但是有些版本 Smart Tomcat 为了方便程序猿调试程序, 会在停止服务器的时候把会话持久化保存, 并且在下次启动的时候自动把会话恢复到内存中, 在这种情况下会话是不丢失的.

但如果是手动部署程序到 Tomcat, 则会话默认还是在内存中, 重启服务器是会丢失的.

相关文章:

从Cookie到Session: Servlet API中的会话管理详解

文章目录 一. Cookie与Session1. Cookie与Session2. Servlet会话管理操作 二. 登录逻辑的实现 一. Cookie与Session 1. Cookie与Session 首先, 在学习过 HTTP 协议的基础上, 我们需要知道 Cookie 是 HTTP 请求报头中的一个关键字段, 本质上是浏览器在本地存储数据的一种机制,…...

docker数据管理与网络通信

一、管理docker容器中数据 管理Docker 容器中数据主要有两种方式:数据卷(Data Volumes)和数据卷容器( DataVolumes Containers) 。 1、 数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿主机的目录挂载到数据卷上&#xff0c;对数据卷的修改操作立刻…...

怎么查询电脑的登录记录及密码更改情况?

源头是办公室公用的电脑莫名其妙打不开了&#xff0c;问别人也都不知道密码是多少 因为本来就没设密码啊&#xff01;&#xff08;躺倒&#xff09; 甚至已经想好了如果是50万想攻破电脑&#xff0c;被po抓住要怎么花这笔钱了 是我想太多 当然最后也没解决&#xff0c;莫名…...

《三》TypeScript 中函数的类型

TypeScript 允许指定函数的参数和返回值的类型。 函数声明的类型定义&#xff1a;function 函数名(形参: 形参类型, 形参: 形参类型, ...): 返回值类型 {} function sum(x: number, y: number): number {return x y } sum(1, 2) // 正确 sum(1, 2, 3) // 错误。输入多余的或者…...

深入学习 Mysql 引擎 InnoDB、MyISAM

tip&#xff1a;作为程序员一定学习编程之道&#xff0c;一定要对代码的编写有追求&#xff0c;不能实现就完事了。我们应该让自己写的代码更加优雅&#xff0c;即使这会费时费力。 &#x1f495;&#x1f495; 推荐&#xff1a;体系化学习Java&#xff08;Java面试专题&#…...

【华为OD统一考试B卷 | 100分】阿里巴巴找黄金宝箱(V)(C++ Java JavaScript Python)

题目描述 一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,每个箱子上面贴有一个数字。 阿里巴巴念出一个咒语数字k(k<N),找出连续k个宝箱数字和的最大值,并输出该最大值。 输入描述 第一行输入一个数字字串,数字之间…...

六步快速搭建个人网站

目录 第一步、选择搭建平台WordPress 第二步、选域名 1&#xff09;域名在哪买&#xff1f; 2&#xff09;域名怎么选&#xff1f; 3&#xff09;以阿里云为例&#xff0c;讲解怎么买域名 第三步、选择服务器 第四步、申请主机、安装WordPress 第五步、选择WordPress模…...

TypeScript 中的 type 关键字有什么用?

创建类型别名 在 TypeScript 中&#xff0c;type 关键字用于创建类型别名&#xff08;Type Alias&#xff09;。类型别名可以给一个类型起一个新的名字&#xff0c;使代码更具可读性和可维护性。 类型别名可以用于定义各种类型&#xff0c;包括基本类型、复合类型和自定义类型…...

27 getcwd 的调试

前言 同样是一个 很常用的 glibc 库函数 不管是 用户业务代码 还是 很多类库的代码, 基本上都会用到 获取当前路径 不过 我们这里是从 具体的实现 来看一下 测试用例 就是简单的使用了一下 getcwd rootubuntu:~/Desktop/linux/HelloWorld# cat Test04Getcwd.c #inc…...

使用IDEA使用Git:Git使用指北——实际操作篇

Git使用指北——实际操作 &#x1f916;:使用IDEA Git插件实际工作流程 &#x1f4a1; 本文从实际使用的角度出发&#xff0c;以IDEA Git插件为基座讲述了如果使用IDEA的Git插件来解决实际开发中的协作开发问题。本文从 远程仓库中拉取项目&#xff0c;在本地分支进行开发&…...

java boot将一组yml配置信息装配在一个对象中

其实将一组yml数据封进一个对象中才是以后的主流开发方式 我们创建一个springboot项目 找到项目中的启动类所在目录 在同目录下创建一个类 名字你们可以随便取 我这里直接叫 dataManager 然后 在yml中定义这样一组数据信息 然后 我们在类中定义三个和这个配置信息相同的字段…...

【裸机开发】链接脚本(.lds文件)的基本语法

目录 一、什么是链接脚本&#xff1f; 二、链接脚本的基本语法格式 1、常用命令 2、内置变量 三、链接脚本的简单案例 一、什么是链接脚本&#xff1f; 一段程序的编译需要经历四个阶段&#xff08;预处理—编译—汇编—链接&#xff09;&#xff0c;而链接脚本管理的就是…...

Java 进阶 -- 集合(三)

4、实现 实现是用于存储集合的数据对象&#xff0c;它实现了接口部分中描述的接口。本课描述了以下类型的实现: 通用实现是最常用的实现&#xff0c;是为日常使用而设计的。它们在标题为“通用实现”的表格中进行了总结。特殊目的实现是为在特殊情况下使用而设计的&#xff0…...

【华为OD机试真题 C语言】5、TLV解析 | 机试真题+思路参考+代码解析

文章目录 一、题目&#x1f383;题目描述&#x1f383;输入输出&#x1f383;样例1 二、思路参考三、代码参考&#x1f3c6;C语言 作者&#xff1a;KJ.JK &#x1f342;个人博客首页&#xff1a; KJ.JK &#x1f342;专栏介绍&#xff1a; 华为OD机试真题汇总&#xff0c;定期…...

(七)CSharp-刘铁锰版-事件

一、初步了解事件 定义&#xff1a;单词 Event &#xff0c;译为“事件” 《牛津词典》中的解释是“a thing that happens,especially something important”通顺的解释就是“能够发生的什么事情” 角色&#xff1a; 使对象或类具备通知能力的成员 &#xff08;中译&#x…...

【ROS】郭老二博文之:ROS目录

1、ROS2 【ROS】Ubuntu22.04安装ROS2&#xff08;Humble Hawksbill&#xff09; 【ROS】ROS2命令行工具详解 【ROS】ROS2中的概念和名词解释 【ROS】ROS2编程示例&#xff1a;话题订阅-发布-C版 【ROS】ROS2编程示例&#xff1a;服务和客户端-C版 【ROS】ROS2编程示例&#xf…...

Android应用程序进程的启动过程

Android应用程序进程的启动过程 导语 到这篇文章为止&#xff0c;我们已经简要地了解过了Android系统的启动流程了&#xff0c;其中比较重要的内容有Zygote进程的启动和SystemService以及Launcher的启动&#xff0c;接下来我们将要学习的是Android应用程序的启动过程&#xff…...

【2】Midjourney注册

随着AI技术的问世&#xff0c;2023年可以说是AI爆炸性成长的一年&#xff0c;近期最广为人知的AI服务除了chatgpt外&#xff0c;就是从去年五月就已经问世的AI绘画工具mid journey了。 ▲几个AI工具也代表了人工智能的热门阶段 只要输入一段文字&#xff0c;AI就会根据语意计算…...

第六十八天学习记录:高等数学:导数(宋浩板书)

导数是微积分中的一个概念&#xff0c;描述了函数在某一个点上的变化率。具体地说&#xff0c;函数 f ( x ) f(x) f(x)在 x a xa xa处的导数为 f ′ ( a ) f(a) f′(a)&#xff0c;表示当 x x x在 a a a处发生微小的变化 Δ x \Delta x Δx时&#xff0c; f ( x ) f(x) f(x)对…...

unreal 5 实现角色拾取功能

要实现角色拾取功能&#xff0c;我们需要实现蓝图接口功能&#xff0c;蓝图接口主要提供的是蓝图和蓝图之间可以通信&#xff0c;接下来&#xff0c;跟着教程&#xff0c;实现一下角色的拾取功能。 首先&#xff0c;我们要实现一个就是可视区的物品在朝向它的时候&#xff0c;会…...

chatgpt赋能python:如何使用Python升序排列一个列表?

如何使用Python升序排列一个列表&#xff1f; 在Python编程中&#xff0c;我们经常需要对列表进行排序。列表排序是一种常见的操作&#xff0c;可以帮助我们对数据进行分析和管理。在这篇文章中&#xff0c;我们将学习如何使用Python对一个列表进行升序排列。 什么是升序排列…...

Lecture 20 Topic Modelling

目录 Topic ModellingA Brief History of Topic ModelsLDAEvaluationConclusion Topic Modelling makeingsense of text English Wikipedia: 6M articlesTwitter: 500M tweets per dayNew York Times: 15M articlesarXiv: 1M articlesWhat can we do if we want to learn somet…...

ThreadPoolExecutor线程池

文章目录 一、ThreadPool线程池状态二、ThreadPoolExecutor构造方法三、Executors3.1 固定大小线程池3.2 带缓冲线程池3.3 单线程线程池 四、ThreadPoolExecutor4.1 execute(Runnable task)方法使用4.2 submit()方法4.3 invokeAll()4.4 invokeAny()4.5 shutdown()4.6 shutdownN…...

chatgpt赋能python:Python实践:如何升级pip

Python实践&#xff1a;如何升级pip Python作为一门高效的脚本语言&#xff0c;被广泛应用于数据分析、人工智能、Web开发等领域。而pip则是Python的包管理工具&#xff0c;是开发Python应用的必备工具。但是pip在使用过程中&#xff0c;有时候会出现版本不兼容或者出现漏洞等…...

【JavaEE进阶】mybatis

目录&#xff1a; 一、Mybatis是什么 三个映射关系如下图&#xff1a; 二、mybatis的使用&#xff08;前置工作简单案例&#xff09; 第一步&#xff1a;导入MAVEN依赖 第二步&#xff1a; 在spring项目当中新建数据源 第三步&#xff1a;新建一个实体类&#xff0c;是和…...

Redis的大key

什么是 redis 的大 key redis 的大 key 不是指存储在 redis 中的某个 key 的大小超过一定的阈值&#xff0c;而是该 key 所对应的 value 过大对于 string 类型来说&#xff0c;一般情况下超过 10KB 则认为是大 key&#xff1b;对于set、zset、hash 等类型来说&#xff0c;一般…...

MMPretrain

title: mmpretrain实战 date: 2023-06-07 16:04:01 tags: [image classification,mmlab] mmpretrain实战 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ccTl9bOl-1686129437336)(null)] 主要讲解了安装,还有使用教程.安装教程直接参考官网.下面讲…...

栈和队列(数据结构刷题)[一]-python

文章目录 前言一、原理介绍二、用栈实现队列1.操作2.思路 三、关于面试考察栈里面的元素在内存中是连续分布的么&#xff1f; 前言 提到栈和队列&#xff0c;大家可能对它们的了解只停留在表面&#xff0c;再深入一点&#xff0c;好像知道又好像不知道的感觉。本文我将从底层实…...

【备战秋招】JAVA集合

集合 前言 一方面&#xff0c; 面向对象语言对事物的体现都是以对象的形式&#xff0c;为了方便对多个对象 的操作&#xff0c;就要 对对象进行存储。 另一方面&#xff0c;使用Array存储对象方面具有一些弊端&#xff0c;而Java 集合就像一种容器&#xff0c;可以动态地把多…...

setState详解

this. setState( [partialState], [callback]) 1.[partialState] :支持部分状态更改 this, setState({ x:100 //不论总共有多少状态&#xff0c;我们只修改了x&#xff0c;其余的状态不动 });callback :在状态更改/视图更新完毕后触发执行&#xff0c;也可以说只要执行了setS…...

动易网站默认密码/如何进行网络营销

昨日&#xff0c;台湾南海岸一带发生了7.1级地震。这次地震损坏了亚太 2号国际海底光缆 (APCN2) 。一时间&#xff0c;无数与国际网络通讯有关的业务&#xff0c;都经历了致命的堵塞。现代人类对科技的依赖&#xff0c;再一次遭到自然的嘲弄。不提这事对大洋两岸人们带来的诸多…...

复古传奇网页版游戏/搜索引擎优化方案案例

IDC公布的数据显示&#xff0c;联想在2018年四季度再次夺得全球PC市场份额第一名&#xff0c;这已是它在反超惠普之后连续两季取得这一位置&#xff0c;柏颖科技认为它巩固了自己在PC市场的领先优势固然是好事&#xff0c;不过对于它来说未来的重点是如何发展新业务。PC市场日渐…...

禅城区网站建设/网站排名优化软件联系方式

贰、两条主线 &#xff1a;一切的开端 &#xff08;一&#xff09;、出发点 这里只从先天的原则出发来阐明纯粹的“先验知识”中仅仅用以维计先验感性、先验知性到先验理性的自身贯通而完全独立于任何经验且先在于任何经验的两条主线&#xff0c;&#xff08;它们给出的是对哲…...

汕头政务发布/网站怎么优化

如今&#xff0c;使用Android等技术以及许多智能手机应用程序&#xff0c;计算机应用程序变得更加复杂&#xff0c;前端越复杂&#xff0c;后端就越复杂。 因此&#xff0c;了解数据库测试、有效地验证数据库&#xff0c;以确保数据库的安全性和质量就显得尤为重要。 在本文中…...

网站开发的测试/爱廷玖达泊西汀

今天&#xff0c;看到一篇文章&#xff0c;蛮有趣的&#xff0c;文章的作者也是我一直有关注的&#xff0c;目前主要从事算法视频制作。他看到一个贪吃蛇游戏&#xff0c;当然也不仅仅是简单的贪吃蛇游戏&#xff0c;重点是这个贪吃蛇把食物吃完后&#xff0c;刚好布满了全屏。…...

网站建设的软件/seo博客模板

来看看strdup在Glibc 2.20&#xff08;标准C库&#xff09;中的实现&#xff1a; 默认参数s不为空指针&#xff0c;这个在我们的数据结构库中是有问题的 改进&#xff1a; 当前版本g编译器不允许析构函数抛异常这么做 打印出来结果&#xff1a;1 3 然后程序崩溃 我们都删除了…...