基于vite创建的react18项目的单元测试
题外话
最近一个小伙伴进了字节外包,第一个活就是让他写一个单元测试。
嗯,说实话,在今天之前我只知道一些理论,但是并没有实操过,于是我就试验了一下。
通过查询资料,大拿们基本都说基于vite的项目,用vitest进行测试比较方便一写。
闲话不多说,步入正题。
1、下载依赖
在vscode终端输入以下命令:
npm install --save-dev vitest @testing-library/react @testing-library/jest-dom
-
--save-dev: 这个标志表示将这些包添加为开发依赖(devDependencies)。这些依赖只在开发环境中使用,而不会被包含在生产环境中。例如,测试框架和工具通常只在开发时需要,而不需要在生产环境中。
-
vitest: 这是一个快速的单元测试框架,类似于 Jest,但专为 Vite 生态系统设计。它支持现代 JavaScript 特性,并且与 Vite 无缝集成,非常适合用于测试 Vite 创建的项目。
-
@testing-library/react: 这是一个用于测试 React 组件的库,提供了一组 API,使得编写测试变得简单而直观。它鼓励以用户的方式来测试组件,而不是实现细节,从而提高测试的可靠性和可维护性。
-
@testing-library/jest-dom: 这是一个为 Jest 提供的自定义匹配器库,增强了 Jest 的断言功能,使得你可以使用更自然的语法来进行 DOM 相关的断言。例如,你可以使用
toBeInTheDocument()
来检查某个元素是否在文档中,而不需要写复杂的查询逻辑。
2、创建testSetup.js文件
文件里只有一行代码:
import '@testing-library/jest-dom';
3、配置vite.config.js文件
代码如下:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'// https://vitejs.dev/config/
export default defineConfig({plugins: [react()],test: {globals: true,environment: 'jsdom',setupFiles: './testSetup.js',},
})
test
: 这是 Vitest 的配置部分。globals: true
: 这个选项表示在测试文件中可以使用全局的测试函数,比如describe
、test
、expect
等,而不需要每次都导入它们。environment: 'jsdom'
: 这个选项指定测试运行在jsdom
环境中。jsdom
是一个 JavaScript 实现的 DOM,用于模拟浏览器环境,这样你可以在 Node.js 中运行测试并且测试涉及 DOM 操作的代码。setupFiles: './testSetup.js'
: 这个选项指定一个设置文件,在测试运行之前会执行。在第二步中我只是引入了一个包。
4、添加脚本
在项目的 package.json
中添加测试脚本:
"scripts": {"test": "vitest"
}
5、创建测试文件
在你的组件目录下,创建一个与组件同名的测试文件,通常以 .test.tsx
结尾。例如,如果你有一个 Wjllogin.jsx
组件,你可以在同一目录下创建 Wjllogin.test.jsx
。
我的demo中的Wjllogin.jsx中的代码如下:
import React, { useState } from "react"; // 导入 React 和 useState Hook
import "./wjs.scss"; // 导入样式文件
import "animate.css"; // 导入动画效果库
import { wjllogin } from "../axiosAPI/wjl"; // 导入用于登录的 API 函数
import { useNavigate } from "react-router-dom"; // 导入路由导航 Hook
import { message } from "antd"; // 导入 Ant Design 的消息提示组件// 定义 Wjllogin 组件
export default function Wjllogin() {let navigate = useNavigate(); // 初始化路由导航let [name, setName] = useState(""); // 定义状态变量 name 和更新函数 setNamelet [card, setCard] = useState(""); // 定义状态变量 card 和更新函数 setCardlet [tid, setTid] = useState(""); // 定义状态变量 tid 和更新函数 setTidconst [messageApi, contextHolder] = message.useMessage(); // 使用 Ant Design 的消息提示 API// 定义登录函数let login = async () => {// 调用 wjllogin API 进行登录let {data: { code, sid, clazz, sname }, // 解构 API 返回的数据} = await wjllogin({ name, card, tid }); // 传递姓名、身份证号和学号到 API// 检查返回的状态码if (code === 200) {// 登录成功,保存用户信息到 sessionStoragesessionStorage.setItem("sid", sid); // 保存会话 IDsessionStorage.setItem("clazz", clazz); // 保存班级信息sessionStorage.setItem("token", "token"); // 保存 token(这里是示例,实际应从 API 获取)sessionStorage.setItem("sname", sname); // 保存姓名// 显示成功消息messageApi.open({type: "success",content: "登录成功, 即将跳转至主页",});// 设置延迟后跳转到主页setTimeout(() => {navigate("/wjlhome"); // 跳转到主页}, 2000);} else {// 登录失败,显示错误消息messageApi.open({type: "error",content: "登录失败,请检查姓名、身份证号或学号",});}};// 组件的 JSX 结构return (<div className="examlogin animate__animated animate__slideInLeft">{" "}{/* 主容器,包含动画效果 */}<div className="top">{" "}{/* 顶部区域 */}<imgclassName="main"src="https://cdn7.axureshop.com/demo/2001850/images/%E5%9C%A8%E7%BA%BF%E8%80%83%E8%AF%95/u2853.svg"alt=""/>{" "}{/* 主图标 */}<imgclassName="x"src="https://cdn7.axureshop.com/demo/2001850/images/%E5%9C%A8%E7%BA%BF%E8%80%83%E8%AF%95/u2854.svg"alt=""/>{" "}{/* 副图标 */}</div><div className="title">{" "}{/* 标题区域 */}培训学院在线考试系统 {/* 系统名称 */}<span className="lessfont">考生版</span> {/* 子标题 */}</div><div className="form">{" "}{/* 表单区域 */}<p><label htmlFor="name">考生姓名:</label><inputid="name"value={name}onChange={(e) => setName(e.target.value)}/></p><p><label htmlFor="card">身份证号:</label><inputid="card"type="text" // 输入框类型value={card} // 绑定到 card 状态onChange={(e) => {setCard(e.target.value); // 更新 card 状态}}/></p><p><label htmlFor="tid">学号:</label> {/* 学号标签 */}<inputid="tid"type="text" // 输入框类型value={tid} // 绑定到 tid 状态onChange={(e) => {setTid(e.target.value); // 更新 tid 状态}}/></p><p><buttonclassName="btn" // 按钮样式onClick={() => {login(); // 点击按钮时调用 login 函数}}>登录 {/* 按钮文本 */}</button></p>{contextHolder} {/* 显示消息提示的容器 */}</div></div>);
}
测试代码Wjllogin.test.jsx中的代码如下:
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom'; // 导入 MemoryRouter
import Wjllogin from './Wjllogin'; // 根据你的文件路径调整
import { wjllogin } from '../axiosAPI/wjl'; // 导入登录 API
import { describe, it, beforeEach, vi } from 'vitest'; // 导入 Vitest 的函数// Mock the API call
vi.mock('../axiosAPI/wjl', () => ({wjllogin: vi.fn(),
}));describe('Wjllogin Component', () => {beforeEach(() => {// 清除所有的 mocksvi.clearAllMocks();});it('renders Wjllogin component', () => {render(<MemoryRouter><Wjllogin /></MemoryRouter>);// Check if elements are renderedexpect(screen.getByText(/考生姓名:/)).toBeInTheDocument();expect(screen.getByText(/身份证号:/)).toBeInTheDocument();expect(screen.getByText(/学号:/)).toBeInTheDocument();expect(screen.getByRole('button', { name: /登录/i })).toBeInTheDocument();});it('successful login', async () => {// Mock the API response for a successful loginwjllogin.mockResolvedValueOnce({data: { code: 200, sid: '123', clazz: 'A1', sname: 'John Doe' },});render(<MemoryRouter><Wjllogin /></MemoryRouter>);// Fill in the input fieldsfireEvent.change(screen.getByLabelText(/考生姓名:/), { target: { value: 'John Doe' } });fireEvent.change(screen.getByLabelText(/身份证号:/), { target: { value: '123456789012345678' } });fireEvent.change(screen.getByLabelText(/学号:/), { target: { value: '2023001' } });// Click the login buttonfireEvent.click(screen.getByRole('button', { name: /登录/i }));// Wait for the success message to appearawait waitFor(() => {expect(screen.getByText(/登录成功, 即将跳转至主页/)).toBeInTheDocument();});// Check if sessionStorage is set (you may need to mock sessionStorage)expect(sessionStorage.getItem('sid')).toBe('123');expect(sessionStorage.getItem('clazz')).toBe('A1');expect(sessionStorage.getItem('sname')).toBe('John Doe');});it('failed login', async () => {// Mock the API response for a failed loginwjllogin.mockResolvedValueOnce({data: { code: 400 },});render(<MemoryRouter><Wjllogin /></MemoryRouter>);// Fill in the input fieldsfireEvent.change(screen.getByLabelText(/考生姓名:/), { target: { value: 'Invalid User' } });fireEvent.change(screen.getByLabelText(/身份证号:/), { target: { value: '000000000000000000' } });fireEvent.change(screen.getByLabelText(/学号:/), { target: { value: '0000000' } });// Click the login buttonfireEvent.click(screen.getByRole('button', { name: /登录/i }));// Wait for the error message to appearawait waitFor(() => {expect(screen.getByText(/登录失败,请检查姓名、身份证号或学号/)).toBeInTheDocument();});});
});
解释代码
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom'; // 导入 MemoryRouter
import Wjllogin from './Wjllogin'; // 根据你的文件路径调整
import { wjllogin } from '../axiosAPI/wjl'; // 导入登录 API
import { describe, it, beforeEach, vi } from 'vitest'; // 导入 Vitest 的函数
@testing-library/react
: 这个库提供了一些函数,用于渲染组件和进行交互测试。MemoryRouter
: 这是 React Router 提供的一个组件,用于在测试中模拟路由环境。Wjllogin
: 这是被测试的组件,假设它是一个登录表单。wjllogin
: 这是一个从 API 模块导入的函数,用于处理登录请求。describe
,it
,beforeEach
,vi
: 这些是 Vitest 提供的函数,用于组织测试用例和创建 mock 函数。
vi.mock('../axiosAPI/wjl', () => ({wjllogin: vi.fn(),
}));
- 这里使用
vi.mock
来模拟wjllogin
函数,以便在测试中控制其返回值,而不实际调用 API。
describe('Wjllogin Component', () => {}
describe
用于将相关的测试用例组织在一起,便于管理和阅读。
beforeEach(() => {vi.clearAllMocks();
});
beforeEach
在每个测试用例执行之前调用,确保每个测试用例都在干净的状态下运行,避免测试之间的相互影响。
测试用例
it('renders Wjllogin component', () => {render(<MemoryRouter><Wjllogin /></MemoryRouter>);// Check if elements are renderedexpect(screen.getByText(/考生姓名:/)).toBeInTheDocument();expect(screen.getByText(/身份证号:/)).toBeInTheDocument();expect(screen.getByText(/学号:/)).toBeInTheDocument();expect(screen.getByRole('button', { name: /登录/i })).toBeInTheDocument();
});
- 这个测试用例检查
Wjllogin
组件是否能够正确渲染,并且确保特定的文本和登录按钮存在于文档中。
it('successful login', async () => {// Mock the API response for a successful loginwjllogin.mockResolvedValueOnce({data: { code: 200, sid: '123', clazz: 'A1', sname: 'John Doe' },});render(<MemoryRouter><Wjllogin /></MemoryRouter>);// Fill in the input fieldsfireEvent.change(screen.getByLabelText(/考生姓名:/), { target: { value: 'John Doe' } });fireEvent.change(screen.getByLabelText(/身份证号:/), { target: { value: '123456789012345678' } });fireEvent.change(screen.getByLabelText(/学号:/), { target: { value: '2023001' } });// Click the login buttonfireEvent.click(screen.getByRole('button', { name: /登录/i }));// Wait for the success message to appearawait waitFor(() => {expect(screen.getByText(/登录成功, 即将跳转至主页/)).toBeInTheDocument();});// Check if sessionStorage is set (you may need to mock sessionStorage)expect(sessionStorage.getItem('sid')).toBe('123');expect(sessionStorage.getItem('clazz')).toBe('A1');expect(sessionStorage.getItem('sname')).toBe('John Doe');
});
- 这个测试用例模拟了一个成功的登录过程。它首先设置了
wjllogin
函数的返回值,然后渲染组件,填写表单,点击登录按钮,并最终检查成功消息是否出现以及 sessionStorage 是否正确设置。
it('failed login', async () => {// Mock the API response for a failed loginwjllogin.mockResolvedValueOnce({data: { code: 400 },});render(<MemoryRouter><Wjllogin /></MemoryRouter>);// Fill in the input fieldsfireEvent.change(screen.getByLabelText(/考生姓名:/), { target: { value: 'Invalid User' } });fireEvent.change(screen.getByLabelText(/身份证号:/), { target: { value: '000000000000000000' } });fireEvent.change(screen.getByLabelText(/学号:/), { target: { value: '0000000' } });// Click the login buttonfireEvent.click(screen.getByRole('button', { name: /登录/i }));// Wait for the error message to appearawait waitFor(() => {expect(screen.getByText(/登录失败,请检查姓名、身份证号或学号/)).toBeInTheDocument();});
});
- 这个测试用例模拟了一个失败的登录过程。它设置了
wjllogin
函数的返回值为一个错误代码,然后填写不正确的表单数据,点击登录按钮,并最终检查错误消息是否出现。
这段代码为 Wjllogin
组件提供了全面的测试,包括组件的渲染、成功登录和失败登录的场景。通过使用 Vitest 和 React Testing Library,测试用例能够模拟用户交互并验证组件的行为是否符合预期。
6、运行测试
通过在终端运行命令 npx vitser 看结果
npx vitest
这里三个测试用例全部通过,说明代码编写没有问题。
相关文章:
基于vite创建的react18项目的单元测试
题外话 最近一个小伙伴进了字节外包,第一个活就是让他写一个单元测试。 嗯,说实话,在今天之前我只知道一些理论,但是并没有实操过,于是我就试验了一下。 通过查询资料,大拿们基本都说基于vite的项目&…...
fiddler抓包工具与requests库构建自动化报告
一. Fiddler 抓包工具 1.1 Fiddler 工具介绍和安装 Fiddler 是一款功能强大的 HTTP 调试代理工具,能够全面记录并深入检查您的计算机与互联网之间的 HTTP 和 HTTPS 通信数据。其主界面布局清晰,主要包含菜单栏、工具栏、树形标签栏和内容栏。 1.2 Fid…...
Docker login 报证书存储错误的解决办法
文章目录 docker login 出现错误,提示:Error saving credentials: error storing credentials - err: exit status 1, out: Cannot autolaunch D-Bus without X11 $DISPLAY 环境 使用的是 Mint Linux ,容器为 docker-ce 最新版 1 2 3 4 $…...
【自动化Selenium】Python 网页自动化测试脚本(上)
目录 1、Selenium介绍 2、Selenium环境安装 3、创建浏览器、设置、打开 4、打开网页、关闭网页、浏览器 5、浏览器最大化、最小化 6、浏览器的打开位置、尺寸 7、浏览器截图、网页刷新 8、元素定位 9、元素交互操作 10、元素定位 (1)ID定位 &…...
什么是MyBatis?
MyBatis简介 MyBatis是一款优秀的持久层框架,用于简化Java应用程序对数据库的操作。它曾是Apache的一个开源项目,名为iBatis,2010年迁移到Google Code并改名为MyBatis,2013年11月又迁移到了GitHub。 一、MyBatis的作用 在JavaE…...
TortoiseGit 将本地已有仓库推送到远程
TortoiseGit 将本地已有仓库推送到远程 一、创建线上仓库二、创建本地仓库三、提交内容到本地仓库四、添加远程仓库地址补充 一、创建线上仓库 在gitlab管理面页面按这前讲过的步骤创建一个空仓库。(通常我们把服务器上这个仓库叫远程仓库,把我们自己电…...
腾讯云OCR车牌识别实践:从图片上传到车牌识别
在当今智能化和自动化的浪潮中,车牌识别(LPR)技术已经广泛应用于交通管理、智能停车、自动收费等多个场景。腾讯云OCR车牌识别服务凭借其高效、精准的识别能力,为开发者提供了强大的技术支持。本文将介绍如何利用腾讯云OCR车牌识别…...
TailwindCss 总结
目录 一、简介 二、盒子模型相关 三、将样式类写到一个类里面apply 四、一款TailWind CSS的UI库 一、简介 官方文档:Width - TailwindCSS中文文档 | TailwindCSS中文网 Tailwind CSS 的工作原理是扫描所有 HTML 文件、JavaScript 组件以及任何 模板中的 CSS 类…...
Java与C#
Java和C#(C Sharp)是两种流行的面向对象编程语言,它们在很多方面非常相似,因为它们都受到了类似的编程范式和语言设计理念的影响。然而,它们之间也存在一些重要的区别。 平台依赖性: Java:Java是…...
leetcode:222完全二叉树的节点个数
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。 完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最…...
[STM32]从零开始的STM32 FreeRTOS移植教程
一、前言 如果能看到这个教程的话,说明大家已经学习嵌入式有一段时间了。还记得嵌入式在大多数时候指的是什么吗?是的,我们所说的学习嵌入式大部分时候都是在学习嵌入式操作系统。从简单的一些任务状态机再到复杂一些的RTOS,再到最…...
java——Tomcat连接池配置NIO、BIO、APR
Tomcat连接池的配置涉及不同的IO模型,包括NIO(Non-blocking IO,非阻塞IO)、APR(Apache Portable Runtime,Apache可移植运行库)和BIO(Blocking IO,阻塞IO)。以…...
跨域相关的一些问题 ✅
当网页从一个源(https://baidu.com)请求另一个源(如 https://taobao/api)的资源时,就发生了跨域。由于安全原因(防止恶意网站通过脚本访问用户在其他网站上的数据),浏览器对跨域请求…...
RPC学习
一、什么是 RPC RPC(Remote Procedure Call),即远程过程调用,是一种计算机通信协议,它允许运行在一台计算机上的程序调用另一台计算机上的子程序或函数,就好像调用本地程序中的函数一样,无需程序…...
coe文件转mif(c语言)
1 mif文件格式 DEPTH=1024; --The size of data in bits WIDTH=16; --The size of memory in words ADDRESS_RADIX = DEC; --The radix for address values DATA_RADIX = UNS...
【leetcode】动态规划
31. 873. 最长的斐波那契子序列的长度 题目: 如果序列 X_1, X_2, ..., X_n 满足下列条件,就说它是 斐波那契式 的: n > 3对于所有 i 2 < n,都有 X_i X_{i1} X_{i2} 给定一个严格递增的正整数数组形成序列 arr ࿰…...
介绍一下atoi(arr);(c基础)
hi , I am 36 适合对象c语言初学者 atoi(arr);是返回整数(int型),整数是arr数组中字符中数字 格式 #include<stdio.h> atoi(arr); 返回值arr数组中的数字 未改变arr数组 #include<stdlib.h>//atoi(arr); 返 <stdlib> int main(…...
docker入门学习笔记
docker的定义 docker是一个用于构建、运行、传送 应用程序的平台。 为什么要使用docker ? 在开发测试库环境中测试成功后,打包成集装箱,到生产环境也是能够成功的。而传统的安装方式不仅繁琐,并且在测试环境安装后,到…...
使用Python和Pybind11调用C++程序(CMake编译)
目录 一、前言二、安装 pybind11三、编写C示例代码四、结合Pybind11和CMake编译C工程五、Python调用动态库六、参考 一、前言 跨语言调用能对不同计算机语言进行互补,本博客主要介绍如何实现Python调用C语言编写的函数。 实验环境: Linux gnuPython3.10…...
tableau-制作30个图表
制作条形图 步骤: 1、横轴是数值,对应了某一个度量值,纵轴是一个标签 战区的成交额,条形图横轴是战区,纵轴是成交额 下钻条形图 1、增加业务架构-战区右键点击,分层结构,增加分层结构 调整业务架构,将战区,城市,小组移动到业务架构下方 此时的条形图上方有➕号展开后…...
2024APMCM亚太杯数学建模C题【宠物行业】原创论文分享
大家好呀,从发布赛题一直到现在,总算完成了2024 年APMCM亚太地区大学生数学建模竞赛C题的成品论文。 给大家看一下目录吧: 目录 摘 要: 10 一、问题重述 14 二.问题分析 15 2.1问题一 15 2.2问题二 15 2.3问题三…...
C语言解析命令行参数
原文地址:C语言解析命令行参数 – 无敌牛 欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等 C语言有一个 getopt 函数,可以对命令行进行解析,下面给出一个示例,用的时候可以直接copy过去修改,很方便…...
推荐一款龙迅HDMI2.0转LVDS芯片 LT6211UX LT6211UXC
龙迅的HDMI2.0转LVDS芯片LT6211UX和LT6211UXC是两款高性能的转换器芯片,它们在功能和应用上有所差异,同时也存在一些共同点。以下是对这两款芯片的详细比较和分析: 一、LT6211UX 主要特性: HDMI2.0至LVDS和MIPI转换器。HDMI2.0输…...
libmodbus 源码学习笔记
1.核心函数_框架_数据结构 整个通信的过程 就是上面这个框架 下面就是具体过程 <1> 主设备 我们首先要初始化 我们要使用的串口 然后 设置我们要访问的哪一个设备 最后打开串口 <2>从机设备 也是我们要初始化我们的串口 然后随后立即设置我们的串口设备地址 最后…...
通用网络安全设备之【防火墙】
概念: 防火墙(Firewall),也称防护墙,它是一种位于内部网络与外部网络之间的网络安全防护系统,是一种隔离技术,允许或是限制传输的数据通过。 基于 TCP/IP 协议,主要分为主机型防火…...
Vue.js基础——贼简单易懂!!(响应式 ref 和 reactive、v-on、v-show 和 v-if、v-for、v-bind)
Vue.js是一个渐进式JavaScript框架,用于构建用户界面。它专门设计用于Web应用程序,并专注于视图层。Vue允许开发人员创建可重用的组件,并轻松管理状态和数据绑定。它还提供了一个虚拟DOM系统,用于高效地渲染和重新渲染组件。Vue以…...
Mybatis 执行存储过程,获取输出参数的值
数据库环境:SQL Server 2008 R2 存储过程 alter procedure proc_generateOuterApplyId acceptType varchar(4),acceptGroupId int,outerApplyId varchar(20) output as begin set nocount onset outerApplyId 24GD6688--select outerApplyId as …...
RAG架构类型
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
Oracle 数据库 IDENTITY 列的性能选项
在上一篇文章Oracle 数据库 IDENTITY 列中,我们介绍了Oracle IDENTITY列的基础知识。本文将介绍IDENTITY列的几个性能选项。由于IDENTITY列内部使用sequence机制,因此也等同于是sequence的性能选项。 由于sequence是递增的,在高并发时&#…...
计算(a+b)/c的值
计算(ab)/c的值 C语言代码C语言代码Java语言代码Python语言代码 💐The Begin💐点点关注,收藏不迷路💐 给定3个整数a、b、c,计算表达式(ab)/c的值,/是整除运算。 输入 输入仅一行&…...
静态网站建设参考文献/网站制作公司
Android403R2模拟器安装在最新的Android 4.0.3 R2模拟器中,已经加入了GPU支持,可以支持OpenGL ES 2.0标准,让开发者可以借助模拟器来测试自己的OpenGL游戏。在去年新增了摄像头支持之后,现在的新版模拟器也加入了包括多点触摸输入…...
wordpress文章分享到微信/cps广告联盟平台
文章目录1. 进程通信的本质以及目的2. 利用管道进行进程通信2.1 管道的概念2.2 匿名管道2.2.1 匿名管道的原理2.2.2 创建匿名管道2.2.3 匿名管道实现父子进程通信2.2.4 匿名管道的读写规则以及特点2.3 命名管道2.3.1 命名管道的原理2.3.2 创建命名管道2.3.3 利用命名管道实现进…...
做网站需要什么软件/点击器 百度网盘
参考文章:java 中 “” 和 equals 的区别equals和的区别 - 趙小赵 - 博客园如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存&…...
wordpress avatars/seo综合检测
计算机专业考公务员好吗 - ...... 好考~ 按往年招收职位专业划分,前三位就是计算机,会计和中文,这三个专业哪个部门都需要.三本学生毕业想考公务员难不难 - ...... 可以考的,如果符合其他职位要求也是可以报考的,无论你是几本的学生,对于考公务员关系不大,因为现在的公务员招考…...
阜阳建设部网站/windows优化大师好用吗
一. 收集器 JVM通过GC来回收堆和方法区中的内存,通常采用收集器的方式实现GC,主要的收集器有引用计数收集器和跟踪收集器。 1、 引用计数收集器 引用计数收集器采用分散式的管理方式,通过计数器记录对象是否被引用。 引用计数收集器需要在每次…...
比较好的网站建设企业/百度搜索引擎seo
数据库中的变量time_of_last_update是datetime类型,我想要做的就是在表格中打印出来(下面),但理想情况下我想知道将来如何将其转换/转换为DateTime类型PHP,然后使用它上面的方法,如 – >格式等.做:$time_date $row[time_of_last_update];$time_date->format(…...