Go单元测试及框架使用
Go自带测试框架
单元测试
- 建议Go 语言推荐测试文件和源代码文件放在一块,测试文件以 _test.go 结尾。
- 函数名必须以 Test 开头,后面一般跟待测试的函数名
- 参数为 t *testing.T
简单测试用例定义如下:
func TestXXXX(t *testing.T) {// ...}
在goland中,编写好方法后,右键Generate->Test for funtion, 可自动生成单元测试代码
生成的代码如下:
需要在TODO里填上单元测试参数,含义如下:
name:单元测试名称args:方法入参want:希望的出参
测试结果:
日志打印
Log() | 打印日志 |
---|---|
Logf() | 格式化打印日志 |
Error() | 打印错误日志 |
Errorf() | 格式化打印错误日志 |
Fatal() | 打印致命日志, 会直接中断当前测试方法 |
Fatalf() | 格式化打印致命日志,会直接中断当前测试方法 |
Fail() | 标记失败,但继续执行当前测试函数 |
FailNow() | 失败,立即终止当前测试函数执行 |
Skip() | 跳过当前函数,通常用于未完成的测试用例 |
基准测试
基准测试用例的定义如下:
func BenchmarkName(b *testing.B){// ...}
- 函数名必须以 Benchmark 开头,后面一般跟待测试的函数名
- 参数为 b *testing.B
- goland中没有自动基准测试的方法,需要按照规则手动自己加
原方法
func sayHi(name string) string{return "hi," + name}
基准测试代码
func BenchmarkSayHi(b *testing.B) {for i := 0; i < b.N; i++ {sayHi("Max")}}
Goland中执行基准测试
命令行中执行基准测试
go test helloworld_test.go
结果解读
当测试开始时,b.N的值被设置为1,执行后如果没有超过默认执行时间上限(默认为1秒),则加大b.N的值,按某种规则一直递增,直到执行时间等于或超过上限,那么就用这一次的b.N的值,做为测试的最终结果
BenchmarkSayHi-12 81593520 14.71 ns/opPASSok zh.com/internal/benchmark_test 2.347s
- BenchmarkSayHi-12表示执行 BenchmarkSayHi 时,所用的最大P的数量为12
- 81593520: 表示sayHi()方法在达到这个执行次数时,等于或超过了1秒
- 14.71 ns/op: 表示每次执行sayHi()所消耗的平均执行时间
- 2.347s:表示测试总共用时
测试总时间的计算
既然81593520表示1秒或大于1秒时执行的次数,那么测试总时间用时却是2.386s,超出了不少,这是为什么呢
在测试中加入b.Log(“NNNNN:”, b.N),再执行基准测试,并加入-v,打印测试中的日志
func BenchmarkSayHi(b *testing.B) {for i := 0; i < b.N; i++ {SayHi("Max")}b.Log("NNNNN:", b.N)
}
go test -v -bench=. -run=^$ gott/SayHiBenchmarkSayHifun1_test.go:26: NNNNN: 1fun1_test.go:26: NNNNN: 100fun1_test.go:26: NNNNN: 10000fun1_test.go:26: NNNNN: 1000000fun1_test.go:26: NNNNN: 3541896fun1_test.go:26: NNNNN: 4832275BenchmarkSayHi-4 4832275 236.8 ns/opPASSok gott/SayHi 2.395s
可以看到b.Log(“NNNNN:”, b.N)被执行了6次,这证明了之前提到的,测试会对b.N依次递增,直到执行时间等于或超过上限。在对BenchmarkSayHi()运行基准测试时,N值依次按1,100,10000,1000000,3541896,4832275递增,直到执行次数为4832275时,执行时间等于或超过了上限。
同时也说明BenchmarkSayHi()一共被调用了6次,每次运行BenchmarkSayHi()都要消耗一定的时间,所以测试总耗时为这6次调用时间之和,2.395s,超过了1秒
benchtime 标记
可以通过-benchtime标记修改默认时间上限,比如改为3秒
go test -v -bench=. -benchtime=3s -run=^$ gott/SayHigoos: darwingoarch: amd64pkg: gott/SayHiBenchmarkSayHifun1_test.go:31: NNNNN: 1fun1_test.go:32: /Users/ga/m/opt/go/go_rootfun1_test.go:31: NNNNN: 100fun1_test.go:32: /Users/ga/m/opt/go/go_rootfun1_test.go:31: NNNNN: 10000fun1_test.go:32: /Users/ga/m/opt/go/go_rootfun1_test.go:31: NNNNN: 1000000fun1_test.go:32: /Users/ga/m/opt/go/go_rootfun1_test.go:31: NNNNN: 15927812fun1_test.go:32: /Users/ga/m/opt/go/go_rootBenchmarkSayHi-4 15927812 223.4 ns/opPASSok gott/hello 3.802s
还可以设置具体的探索次数最大值,格式为-benchtime=Nx
go test gott/hello -run=^$ -bench=BenchmarkHello -benchtime=50xgoos: darwingoarch: amd64pkg: gott/helloBenchmarkHello-4 50 2183 ns/op--- BENCH: BenchmarkHello-4fun1_test.go:35: NNNNN: 1fun1_test.go:36: /Users/ga/m/opt/go/go_rootfun1_test.go:35: NNNNN: 50fun1_test.go:36: /Users/ga/m/opt/go/go_rootPASSok gott/hello 0.011s
b.N的值被设置为50,函数运行了50次
benchmem 标记
可以通过-benchmem标记查看内存使用信息
go test -bench=. -run=none -benchmem
go test gott/hello -run=^$ -bench=BenchmarkHello -benchmem
go test gott/hello -run=^$ -bench=BenchmarkHello -benchmem
goos: darwin
goarch: amd64
pkg: gott/hello
BenchmarkHello-4 5137456 223.1 ns/op 32 B/op 2 allocs/op
--- BENCH: BenchmarkHello-4
fun1_test.go:35: NNNNN: 1
fun1_test.go:36: /Users/ga/m/opt/go/go_root
fun1_test.go:35: NNNNN: 100
fun1_test.go:36: /Users/ga/m/opt/go/go_root
fun1_test.go:35: NNNNN: 10000
fun1_test.go:36: /Users/ga/m/opt/go/go_root
fun1_test.go:35: NNNNN: 1000000
fun1_test.go:36: /Users/ga/m/opt/go/go_root
fun1_test.go:35: NNNNN: 5137456
fun1_test.go:36: /Users/ga/m/opt/go/go_root
... [output truncated]
PASS
ok gott/hello 1.399s
- 32 B/op:平均每次迭代内存分配的字节数
- 2 allocs/op:平均每次迭代内存分配的次数
平均每次迭代计算的依据应该使用的是 b.N=5137456迭代次数
基准测试的用途
一般用于对比两个不同的操作所消耗的时间,如
- 渐近增长函数的运行时间一个函数需要1ms处理1,000个元素,处理10000或1百万将需要多少时间呢
- I/O缓存该设置为多大基准测试可以帮助我们选择在性能达标情况下所需的最小内存
- 确定哪种算法更好
覆盖率测试
运行run with coverage
结果解读
右侧会展示覆盖率,左侧绿色为单元测试已覆盖到的代码,红色为未覆盖的代码
example测试
样例测试比较像平时在一些算法刷题平台(比如LeetCode)的题目的一些例子,样例测试以Example打头,其逻辑也很简单,就是使用fmt.Println输出该测试用例的返回结果,然后在函数体的末尾使用如图的注释,一一对应每个fmt.Println的输出:
如果输出和注释不能对应上则不通过
模糊测试
go版本要求
Fuzz模糊测试需要Go 1.18 Beta 1或以上版本的泛型功能
测试代码
package fuzz_testimport ("fmt""testing""unicode/utf8"
)func Reverse(s string) string {b := []byte(s)for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {b[i], b[j] = b[j], b[i]}return string(b)
}func FuzzReverse(f *testing.F) {testcases := []string{"Hello, world", "!12345"}for _, tc := range testcases {f.Add(tc) // Use f.Add to provide a seed corpus}f.Fuzz(func(t *testing.T, orig string) {rev := Reverse(orig)fmt.Printf("original->:%s", orig)fmt.Printf("after->:%s", rev)doubleRev := Reverse(rev)if orig != doubleRev {t.Errorf("Before: %q, after: %q", orig, doubleRev)}if utf8.ValidString(orig) && !utf8.ValidString(rev) {t.Errorf("Reverse produced invalid UTF-8 string %q", rev)}})
}
测试结果
第三方框架
总体介绍
框架名 | 使用说明 | 优点 | 缺点 |
---|---|---|---|
testing | 如上 | go官方原生测试框架,简单好用 | 断言不够友好,需要大量if else可以配合testify的assert使用 |
testify | 1. 和 go test 无缝集成,直接使用该命令运行2. 支持断言,写法更简便3. 支持 mock & suite功能 | mock的功能不够强大,需要配合其他mock框架使用 | |
GoConvey | 1. 能够使用 go test 来运行测试2. 支持断言,写法更简便3. 支持通过浏览器查看测试结果4. 支持嵌套,可以分组 | 1. 写法并不简便,主要多了个通过浏览器查看测试结果,个人觉得不是很有使用的必要2. 单元测试应该尽可能简单可维护,嵌套分组等功能太复杂,不利于维护 | |
结论
建议采用testing+testify,goland支持自动生成testing单测模板,加上testify丰富的断言够用了
mock框架
golang中常用的stub/mock框架
GoStub | Gomonkey | Gomock |
---|---|---|
轻量级打桩框架 | 运行时重写可执行文件,类似热补丁 | 官方提供的mock框架,功能强大 |
支持为全局变量,函数打桩 | 性能强大,使用方便 | mockgen 工具可自动生成mock代码;支持mock所有接口类型 |
需要改造原函数,使用不方便;性能不强 | 支持对变量,函数,方法打桩,支持打桩序列 | 可以配置调用次数,调用顺序,根据入参动态返回结果等 |
不是并发安全的;使用可能根据版本不同需要有些额外配置工作 | 只支持接口级别mock,不能mock普通函数 |
结论
建议采用Gomonkey. GoStub很多功能不支持,GoMock每次编写完需要重新generate生成代码,不太方便
其他特定领域mock工具
框架名 | 说明 | |
---|---|---|
GoSqlMock | sqlmock包,用于单测中mock db操作 | |
miniredis | 纯go实现的用于单元测试的redis server。它是一个简单易用的、基于内存的redis替代品,它具有真正的TCP接口。当我们为一些包含 Redis 操作的代码编写单元测试时可以使用它来 mock Redis 操作 | |
Httptest | Golang官方自带,生成一个模拟的http server.主要使用的单测场景是:已经约定了接口,但是服务端还没实现 |
其他
goland中没有类似TestMe的Go单元测试插件,可以考虑实现一个
mock工具GoMock使用
GoMock
gomock 是官方提供的 mock 框架,同时还提供了 mockgen 工具用来辅助生成测试代码。
go get -u github.com/golang/mock/gomock go get -u github.com/golang/mock/mockgen
简单的使用方法:
// db.gotype DB interface {Get(key string) (int, error)}func GetFromDB(db DB, key string) int {if value, err := db.Get(key); err == nil {return value}return -1}复制代码
有一个DB接口,使用mockgen产生一个mock对象
mockgen -source=db.go -destination=db_mock.go -package=main
下面是自动生成的代码
// Code generated by MockGen. DO NOT EDIT.// Source: db.go// Package mian is a generated GoMock package.package mianimport (reflect "reflect"gomock "github.com/golang/mock/gomock")// MockDB is a mock of DB interface.type MockDB struct {ctrl *gomock.Controllerrecorder *MockDBMockRecorder}// MockDBMockRecorder is the mock recorder for MockDB.type MockDBMockRecorder struct {mock *MockDB}// NewMockDB creates a new mock instance.func NewMockDB(ctrl *gomock.Controller) *MockDB {mock := &MockDB{ctrl: ctrl}mock.recorder = &MockDBMockRecorder{mock}return mock}// EXPECT returns an object that allows the caller to indicate expected use.func (m *MockDB) EXPECT() *MockDBMockRecorder {return m.recorder}// Get mocks base method.func (m *MockDB) Get(key string) (int, error) {m.ctrl.T.Helper()ret := m.ctrl.Call(m, "Get", key)ret0, _ := ret[0].(int)ret1, _ := ret[1].(error)return ret0, ret1}// Get indicates an expected call of Get.func (mr *MockDBMockRecorder) Get(key interface{}) *gomock.Call {mr.mock.ctrl.T.Helper()return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockDB)(nil).Get), key)}复制代码
在测试的使用mock对象
func TestGetFromDB(t *testing.T) {ctrl := gomock.NewController(t)defer ctrl.Finish() // 断言 DB.Get() 方法是否被调用m := NewMockDB(ctrl)m.EXPECT().Get(gomock.Eq("Tom")).Return(100, errors.New("not exist")) //设置期望返回结果,可以设置可调用次数times/AnyTimesif v := GetFromDB(m, "Tom"); v != -1 {t.Fatal("expected -1, but got", v)}}复制代码
goMock支持对特定输入打桩和对任意输入打桩(gomock.any()),可根据具体情况使用;
实际项目中,可以用gomock来mock dao层和rpc层代码,隔离外部依赖
相关文章:
Go单元测试及框架使用
Go自带测试框架 单元测试 建议Go 语言推荐测试文件和源代码文件放在一块,测试文件以 _test.go 结尾。函数名必须以 Test 开头,后面一般跟待测试的函数名参数为 t *testing.T 简单测试用例定义如下: func TestXXXX(t *testing.T) {// ...}…...
TreeMap类型实体类数据进行排序
实体类Student类代码如下所示: package com.test.Test11;public class Student implements Comparable<Student>{private int age;private String name;private Double height;public int getAge() {return age;}public void setAge(int age) {this.age age…...
HOOPS助力AVEVA数字化转型:支持多种3D模型格式转换!
行业: 电力和公用事业、化工、造船、能源、采矿业 挑战: 创建大规模复杂资产的客户需要汇集多种类型的数据,以支持初始设计和创建强大的数字双胞胎;现有版本的产品只支持半打CAD格式;有限的内部开发资源限制了增加对新…...
(转载)基于遗传模拟退火的聚类算法(matlab实现)
1 理论基础 1.1 模糊聚类分析 模糊聚类是目前知识发现以及模式识别等诸多领域中的重要研究分支之一。随着研究范围的拓展,不管是科学研究还是实际应用,都对聚类的结果从多方面提出了更高的要求。模糊C-均值聚类(FCM)是目前比较流行的一种聚类方法。该…...
【C++】struct 和 class 的区别
欢迎来到博主 Apeiron 的博客,祝您旅程愉快。时止则止,时行则行。动静不失其时,其道光明。 目录 1、缘起 2、示例代码 3、总结 1、缘起 在 C 中,struct 和 class 唯一的区别就在于 默认的访问权限不同。区别如下: …...
活动笔记丨物业行业人效提升与灵活用工新路径
近日,盖雅工场成功举办物业行业人效提升专场交流,来自广深地区央企和民营的领先物业企业和现场服务业的多位代表齐聚深圳招商积余大厦,共同研讨行业人效提升的挑战和实践。 本次闭门交流会聚焦于人效提升,讨论话题包括各自企业在人…...
学习笔记:吴恩达ChatGPT提示工程
以下为个人笔记,原课程网址Short Courses | Learn Generative AI from DeepLearning.AI 01 Introduction 1.1 基础LLM 输入 从前有一只独角兽,输出 它和其他独角兽朋友一起住在森林里输入 法国的首都在哪?输出 法国的首都在哪…...
POI in Action
POI 组件依赖 按需引入对应依赖 (给出官方的指引) 组件作用Maven依赖POIFSOLE2 FilesystempoiHPSFOLE2 Property SetspoiHSSFExcel XLSpoiHSLFPowerPoint PPTpoi-scratchpadHWPFWord DOCpoi-scratchpadHDGFVisio VSDpoi-scratchpadHPBFPublisher PUBpoi-scratchpadHSMFOutloo…...
苹果Vision Pro将引爆人机交互的重大变革
2023年6月6日,苹果发布了大家期待已久的Vision Pro,Vision Pro是一款专业级MR设备,融合了虚拟现实(VR)和增强现实(AR)技术,可以让用户完全沉浸在高分辨率显示内容中。允许用户以一种全新的方式在其周围的空间中查看APP。用户可以用…...
MMDetection学习记录(二)之配置文件
文件结构 config文件 在 config_base_ 文件夹下有 4 个基本组件类型,分别是:数据集(dataset),模型(model),训练策略(schedule)和运行时的默认设置(default runtime)。 命名风格 {model}_[model setting]_{backbone}_{neck}_[no…...
Python数据分析:NumPy、Pandas和Matplotlib的使用和实践
在现代数据分析领域中,Python已成为最受欢迎的编程语言之一。Python通过庞大的社区和出色的库支持,成为了数据科学家和分析师的首选语言。在Python的库中,NumPy、Pandas和Matplotlib是三个最为重要的库,它们分别用于处理数值数组、…...
实习生面试问题及回答记录
文章目录 文章简介技术类1、DFS和BFS算法的区别是什么?2、解释一下什么是快速排序?3、 如果让你写一个排序算法?你会怎么写?(大概说出代码的思路)4、解释一下二分查找的具体逻辑?5、在代码的数据…...
设计模式(十):结构型之外观模式
设计模式系列文章 设计模式(一):创建型之单例模式 设计模式(二、三):创建型之工厂方法和抽象工厂模式 设计模式(四):创建型之原型模式 设计模式(五):创建型之建造者模式 设计模式(六):结构型之代理模式 设计模式…...
买法拍房需要注意什么
法拍房,由于其价格亲民、房屋信息透明度高、竞拍过程公平公正而受到越来越多的人开始关注。但是其中又有着许多的风险及相关的注意事项。那么,如何做到成功“捡漏”,买法拍房需要注意什么呢? 买法拍房需要注意什么 1、隐藏的各种收费 税费&a…...
linux命令输出结果但不显示在屏幕上的通用办法
linux命令输出结果但不显示在屏幕上的通用办法 这个针对于我这种小白马大哈很简单的一个命令,记给自己备用 举个例子:unzip命令不输出结果 unzip xx.zip > /dev/null 2>&1 unzip xx.zip > /dev/null 前半部分是将标准输出重定向到空设备&a…...
【Linux系统进阶详解】Linux字符权限rwx-权限组合原理,对应类型ugo,user,group,other,+-=详解及权限管理实战
在Linux系统中,每个文件和目录都有三种权限:读权限(r)、写权限(w)和执行权限(x)。这些权限可以被分配给三个不同的用户组:用户(user)、组(group)和其他人(other)。此外,权限可以使用“+”、“-”和“=”符号进行修改。 权限组合原理 Linux系统中的权限由字母…...
凡人修C传——专栏从凡人到成仙系列目录
这里先感谢博主THUNDER王给我提出来的一个创作建议,让我有了创作的灵感来创建这一篇博客以及凡人修C传这一个系列的文章。 本文最主要的目的就是给大家一个凡人修C传的一个目录,让大家更加容易学到自己想学的地方。 📝【个人主页】࿱…...
隐藏python代码,售卖并保护源代码
我写了一个基于pytorch框架的特殊卷积,他的使用方式和其他的卷积一样,但是我想把它卖出去,希望隐藏特殊卷积的代码 1、如果您希望隐藏特殊卷积的代码并将其作为一个可售卖的产品,可以考虑以下几种方法来保护您的代码:…...
Material—— VAT(Houdini To UE)
目录 一,介绍 二,柔体 二,刚体 一,介绍 VAT是将动画数据存储在纹理中,通过GPU运算来实现动画的技术;VAT纹理包含每个顶点在不同帧的位置信息,而每个像素代表一个顶点在某个时间点的位置&…...
视频后期剪辑
文章目录 后期剪辑软件三方插件提供动画制作软件 后期剪辑软件 视频剪辑后期处理涉及到多个软件和插件,下面是对其中几个主要软件及其相关插件的扩展介绍,以及为它们提供插件的一些知名第三方公司。 Adobe After Effects: Adobe After Effec…...
Python3+Selenium2完整的自动化测试实现之旅(七):完整的轻量级自动化框架实现
一、前言 前面系列Python3Selenium2自动化系列博文,陆陆续续总结了自动化环境最基础环境的搭建、IE和Chrome浏览器驱动配置、selenium下的webdriver模块提供的元素定位和操作鼠标、键盘、警示框、浏览器cookie、多窗口切换等场景的方法、web自动化测试框架、python面…...
泰山信息科技5周年:无尽的感恩,非常非常的惋惜
去年的时候,庆贺4周年,公司员工一起去某个地方玩(确实没吃到什么东西)。这是当时的情形: 因为各种原因,今年3月无锡研发基地解散。作为技术总监,我是非常非常的惋惜。因为我真的想把泰山OFFICE做…...
LabVIEW编程开发PCB测试仪
LabVIEW编程开发PCB测试仪 使用PXI和LabVIEW的PCB钉床测试仪 用于PCB(印刷电路板)的钉床测试仪,使用PXI和LabVIEW。一家电子制造公司需要测试仪来测试他们的PCB产品。钉床测试仪是一种具有连接到电路板上各个测试点的引脚的测试。电路板需要…...
React使用Electron开发桌面端
React是一个流行的JavaScript库,用于构建Web应用程序。结合Electron框架,可以轻松地将React应用程序打包为桌面应用程序。以下是使用React和Electron开发桌面应用程序的步骤: 1. 安装Electron 首先,你需要安装Electron。在终端中…...
springboot+vue餐厅点餐系统在线点餐系统(含源码+数据库)
1.系统分析 系统用例图如下所示。 从用户、餐厅等方面进行需求分析如下。 1.用户需求:系统应该提供简单易用的用户界面,用户可以浏览餐厅菜单,选择菜品,下订单。此外,应该允许用户管理个人信息和查看历史订单。 2.餐…...
Vue.js 中的 TypeScript 支持是什么?如何使用 TypeScript?
Vue.js 中的 TypeScript 支持 Vue.js 是一款流行的前端框架,它提供了一种简单、灵活的方式来构建用户界面。随着 TypeScript 的普及,Vue.js 也开始支持 TypeScript,使得开发者可以使用类型检查等 TypeScript 特性来提高代码质量和可维护性。…...
测试者必知—如何做Web测试?常见测试点总结
目录 前言: 一、Web应用程序 二、功能测试 三、易用性测试(界面测试) 四、兼容性测试 五、安全性测试 六、性能测试 前言: Web测试是指对基于Web技术的应用程序进行测试,以测试其功能、性能、安全和稳定性等方面的表…...
怎么转换英文音频成文字?英文音频转文字app分享
两位朋友正在讨论如何将一段英文讲座的音频转换成文字,以便于学习和理解。 Sophia:嗨,我最近听了一段非常精彩的英文讲座,但是对于我来说,理解听到的内容有些困难。你知道有什么方法可以将英文音频转换成文字吗&#…...
esp32-cam拍照上传,app inventor 制作安卓app实时显示
1、ESP32-cam开发环境配置 本例程 是利用arduino IDE开发,关于arduino IDE 的esp32环境配置可参考:环境配置: 点击跳转 安装好esp32 环境,开发板选择esp32 wrover module开发板,其他默认即可。 2 、程序下载 示例程序下载:点击下载 需要修改的信息有WIF名称,WIFI密码,…...
基于jsp+mysql+Spring+mybatis+Springboot的Springboot实现的就业信息管理平台
运行环境: 最好是java jdk 1.8,我在这个平台上运行的。其他版本理论上也可以。 IDE环境: Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以,如果编译器的版本太低,需要升级下编译器,不要弄太低的版本 tomcat服务器环…...
山西网站建设费用/今天的新闻摘抄
前言 今天讲解一下Android平台下ListView控件的开发,在本篇博客中,将介绍ListView的一些常用属性、方法及事件,还会讲解ListView在开发中常用的几种方式,以及使用不通用的适配器Adapter定制个性的View视图用于ListView的展示。 Li…...
wordpress 站长/seo站长工具 论坛
Ubuntu 20.04 更新源系统版本更新源系统版本 # cat /etc/issue Ubuntu 20.04.2 LTS \n \l更新源 # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multive…...
哪里有好看的网站/设计网站官网
很多搞性能测试的人员,只会跟着网上、前辈教导的方法进行测试:挑选业务逻辑中并发量、访问量最高的业务逻辑、结合读写等业务进行测试,然后取整条业务逻辑(模拟用户全流程动作)的逻辑进行测试;结果就是&…...
太原seo网站建设/推广公司哪家好
win10安装软件出现error launching installer提示怎么办?我们在平时的工作当中,经常会安装很多软件,但有时会遇到安装失败,提示“error launching installer”的问题,遇到此问题的用户,请来看看下面的解决吧。最近有位…...
门户网站cms/百度搜索的优势
在Java 中 除了字段来表示某种类型的基本数据,还有方法来表示类中的请求,或者说是动作。Java中用方法决定了一个对象能接受什么样的信息 做出什么样的动作。 方法的基本组成有 名字 参数 返回值 还有方法体(也就是代码块)下面的是…...
做购物网站的费用/百度推广怎么推
分类: Oracle 问题描述:对数据库做检查,发现system表空间持续占满99%。使用如下语句查看:SQL> select b.tablespace_name "表空间",b.bytes/1024/1024 "大小M",(b.bytes-sum(nvl(a.bytes,0)))/1024/1024 &…...