写在前面

本随笔是非常菜的菜鸡写的。如有问题请及时提出。

可以联系:1160712160@qq.com

GitHhub:https://github.com/WindDevil (目前啥也没有

批处理操作系统的启动和运行流程

要想把本章实现的那些模块全部都串联在一起以实现运行一个批处理操作系统,回顾本章内容,思考批处理操作系统的运行流程.

可以看到本章完成的内容大概如图所示:

可以看到在内核层,最重要的就是实现了batch来加载程序和切换程序,以及trap用来处理用户层的请求.

因此,我们只需要在main.rs中添加这两个模块的初始化即可.

编写main.rs

主要是三部分:

  1. 引入上述编写模块

    1. 嵌入link_app.S
    2. 引入batch,trap,syscall
  2. 初始化模块
  3. 开始运行用户态APP

需要添加的内容就这么多:

pub mod batch;
pub mod syscall;
pub mod trap; global_asm!(include_str!("link_app.S"));
pub fn rust_main() -> ! {
trap::init();
batch::init();
batch::run_next_app();
}

最终实现的main.rs:

//! The main module and entrypoint
//!
//! Various facilities of the kernels are implemented as submodules. The most
//! important ones are:
//!
//! - [`trap`]: Handles all cases of switching from userspace to the kernel
//! - [`syscall`]: System call handling and implementation
//!
//! The operating system also starts in this module. Kernel code starts
//! executing from `entry.asm`, after which [`rust_main()`] is called to
//! initialize various pieces of functionality. (See its source code for
//! details.)
//!
//! We then call [`batch::run_next_app()`] and for the first time go to
//! userspace. #![deny(missing_docs)]
#![deny(warnings)]
#![no_std]
#![no_main]
#![feature(panic_info_message)] use core::arch::global_asm; use log::*;
#[macro_use]
mod console;
pub mod batch;
mod lang_items;
mod logging;
mod sbi;
mod sync;
pub mod syscall;
pub mod trap; global_asm!(include_str!("entry.asm"));
global_asm!(include_str!("link_app.S")); /// clear BSS segment
fn clear_bss() {
extern "C" {
fn sbss();
fn ebss();
}
unsafe {
core::slice::from_raw_parts_mut(sbss as usize as *mut u8, ebss as usize - sbss as usize)
.fill(0);
}
} /// the rust entry-point of os
#[no_mangle]
pub fn rust_main() -> ! {
extern "C" {
fn stext(); // begin addr of text segment
fn etext(); // end addr of text segment
fn srodata(); // start addr of Read-Only data segment
fn erodata(); // end addr of Read-Only data ssegment
fn sdata(); // start addr of data segment
fn edata(); // end addr of data segment
fn sbss(); // start addr of BSS segment
fn ebss(); // end addr of BSS segment
fn boot_stack_lower_bound(); // stack lower bound
fn boot_stack_top(); // stack top
}
clear_bss();
logging::init();
println!("[kernel] Hello, world!");
trace!(
"[kernel] .text [{:#x}, {:#x})",
stext as usize,
etext as usize
);
debug!(
"[kernel] .rodata [{:#x}, {:#x})",
srodata as usize, erodata as usize
);
info!(
"[kernel] .data [{:#x}, {:#x})",
sdata as usize, edata as usize
);
warn!(
"[kernel] boot_stack top=bottom={:#x}, lower_bound={:#x}",
boot_stack_top as usize, boot_stack_lower_bound as usize
);
error!("[kernel] .bss [{:#x}, {:#x})", sbss as usize, ebss as usize);
trap::init();
batch::init();
batch::run_next_app();
}

编译运行

使用第一章就编写好的Makefile文件实现一键编译运行:

cd os
make run

第一次编译运行:

error: expected expression, found keyword `extern`
--> src/batch.rs:94:13
|
94 | extern "C"
| ^^^^^^ expected expression error: cannot find macro `asm` in this scope
--> src/batch.rs:84:9
|
84 | asm!("fence.i")
| ^^^
|
help: consider importing this macro
|
1 + use core::arch::asm;
| error: cannot find macro `global_asm` in this scope
--> src/trap/mod.rs:3:1
|
3 | global_asm!(include_str!("trap.S"));
| ^^^^^^^^^^
|
help: consider importing one of these items
|
3 + use core::arch::global_asm;
|
3 + use crate::global_asm;
| error[E0412]: cannot find type `TrapContext` in this scope
--> src/batch.rs:34:36
|
34 | pub fn push_context(&self, cx: TrapContext) -> &'static mut TrapContext {
| ^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `TrapContext` in this scope
--> src/batch.rs:34:65
|
34 | pub fn push_context(&self, cx: TrapContext) -> &'static mut TrapContext {
| ^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `TrapContext` in this scope
--> src/batch.rs:35:60
|
35 | let cx_ptr = (self.get_sp() - core::mem::size_of::<TrapContext>()) as *mut TrapContext;
| ^^^^^^^^^^^ not found in this scope
|
help: you might be missing a type parameter
|
30 | impl<TrapContext> KernelStack {
| +++++++++++++ error[E0412]: cannot find type `TrapContext` in this scope
--> src/batch.rs:35:84
|
35 | let cx_ptr = (self.get_sp() - core::mem::size_of::<TrapContext>()) as *mut TrapContext;
| ^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `RefCell` in this scope
--> src/sync/up.rs:5:12
|
5 | inner: RefCell<T>,
| ^^^^^^^ not found in this scope
|
help: consider importing this struct
|
3 + use core::cell::RefCell;
| error[E0433]: failed to resolve: use of undeclared type `RefCell`
--> src/sync/up.rs:14:23
|
14 | Self { inner: RefCell::new(value) }
| ^^^^^^^ use of undeclared type `RefCell`
|
help: consider importing this struct
|
3 + use core::cell::RefCell;
| error[E0412]: cannot find type `RefMut` in this scope
--> src/sync/up.rs:17:39
|
17 | pub fn exclusive_access(&self) -> RefMut<'_, T> {
| ^^^^^^ not found in this scope
|
help: consider importing this struct
|
3 + use core::cell::RefMut;
| error[E0412]: cannot find type `TrapContext` in this scope
--> src/trap/mod.rs:13:30
|
13 | pub fn trap_handler(cx: &mut TrapContext) -> &mut TrapContext {
| ^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `TrapContext` in this scope
--> src/trap/mod.rs:13:51
|
13 | pub fn trap_handler(cx: &mut TrapContext) -> &mut TrapContext {
| ^^^^^^^^^^^ not found in this scope error[E0425]: cannot find function `syscall` in this scope
--> src/trap/mod.rs:19:24
|
19 | cx.x[10] = syscall(cx.x[17], [cx.x[10], cx.x[11], cx.x[12]]) as usize;
| ^^^^^^^ not found in this scope
|
help: consider importing this function
|
3 + use crate::syscall::syscall;
| error[E0425]: cannot find function `run_next_app` in this scope
--> src/trap/mod.rs:24:13
|
24 | run_next_app();
| ^^^^^^^^^^^^ not found in this scope
|
help: consider importing this function
|
3 + use crate::batch::run_next_app;
| error[E0425]: cannot find function `run_next_app` in this scope
--> src/trap/mod.rs:28:13
|
28 | run_next_app();
| ^^^^^^^^^^^^ not found in this scope
|
help: consider importing this function
|
3 + use crate::batch::run_next_app;
| error[E0425]: cannot find function `init` in module `batch`
--> src/main.rs:88:12
|
88 | batch::init();
| ^^^^ not found in `batch`
|
help: consider importing one of these items
|
23 + use crate::logging::init;
|
23 + use crate::trap::init;
|
help: if you import `init`, refer to it directly
|
88 - batch::init();
88 + init();
| error[E0308]: mismatched types
--> src/batch.rs:80:41
|
80 | core::slice::from_raw_parts_mut(APP_BASE_ADDRESS as *const u8, APP_SIZE_LIMIT).fill(0);
| ------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability
| |
| arguments to this function are incorrect
|
= note: expected raw pointer `*mut _`
found raw pointer `*const u8`
note: function defined here
--> /home/winddevil/.rustup/toolchains/nightly-2024-05-01-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/raw.rs:147:21
|
147 | pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
| ^^^^^^^^^^^^^^^^^^ error[E0599]: the method `get` exists for struct `Lazy<UPSafeCell<AppManager>>`, but its trait bounds were not satisfied
--> src/batch.rs:88:1
|
88 | / lazy_static!
89 | | {
90 | | static ref APP_MANAGER: UPSafeCell<AppManager> = unsafe
91 | | {
... |
110 | | };
111 | | }
| |_^ method cannot be called on `Lazy<UPSafeCell<AppManager>>` due to unsatisfied trait bounds
|
::: src/sync/up.rs:3:1
|
3 | pub struct UPSafeCell<T> {
| ------------------------ doesn't satisfy `UPSafeCell<AppManager>: Sized`
|
= note: the following trait bounds were not satisfied:
`{type error}: Sized`
which is required by `UPSafeCell<AppManager>: Sized`
= note: this error originates in the macro `__lazy_static_internal` which comes from the expansion of the macro `lazy_static` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0433]: failed to resolve: use of undeclared type `TrapContext`
--> src/batch.rs:126:13
|
126 | TrapContext::app_init_context(APP_BASE_ADDRESS, USER_STACK.get_sp())
| ^^^^^^^^^^^ use of undeclared type `TrapContext` error[E0425]: cannot find function `sys_write` in this scope
--> src/syscall/mod.rs:5:26
|
5 | SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
| ^^^^^^^^^ not found in this scope error[E0425]: cannot find function `sys_exit` in this scope
--> src/syscall/mod.rs:6:25
|
6 | SYSCALL_EXIT => sys_exit(args[0] as i32),
| ^^^^^^^^ not found in this scope error[E0433]: failed to resolve: use of undeclared crate or module `stvec`
--> src/trap/mod.rs:8:9
|
8 | stvec::write(__alltraps as usize, TrapMode::Direct);
| ^^^^^ use of undeclared crate or module `stvec` error[E0433]: failed to resolve: use of undeclared type `TrapMode`
--> src/trap/mod.rs:8:43
|
8 | stvec::write(__alltraps as usize, TrapMode::Direct);
| ^^^^^^^^ use of undeclared type `TrapMode` error[E0433]: failed to resolve: use of undeclared crate or module `scause`
--> src/trap/mod.rs:14:18
|
14 | let scause = scause::read();
| ^^^^^^ use of undeclared crate or module `scause` error[E0433]: failed to resolve: use of undeclared crate or module `stval`
--> src/trap/mod.rs:15:17
|
15 | let stval = stval::read();
| ^^^^^ use of undeclared crate or module `stval` error: unused variable: `metadata`
--> src/logging.rs:9:23
|
9 | fn enabled(&self, metadata: &Metadata) -> bool
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_metadata`
|
note: the lint level is defined here
--> src/main.rs:18:9
|
18 | #![deny(warnings)]
| ^^^^^^^^
= note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]` error[E0433]: failed to resolve: use of undeclared type `Exception`
--> src/trap/mod.rs:26:25
|
26 | Trap::Exception(Exception::IllegalInstruction) => {
| ^^^^^^^^^ use of undeclared type `Exception` error[E0433]: failed to resolve: use of undeclared type `Trap`
--> src/trap/mod.rs:26:9
|
26 | Trap::Exception(Exception::IllegalInstruction) => {
| ^^^^ use of undeclared type `Trap` error[E0433]: failed to resolve: use of undeclared type `Exception`
--> src/trap/mod.rs:22:25
|
22 | Trap::Exception(Exception::StorePageFault) => {
| ^^^^^^^^^ use of undeclared type `Exception` error[E0433]: failed to resolve: use of undeclared type `Trap`
--> src/trap/mod.rs:22:9
|
22 | Trap::Exception(Exception::StorePageFault) => {
| ^^^^ use of undeclared type `Trap` error[E0433]: failed to resolve: use of undeclared type `Exception`
--> src/trap/mod.rs:21:25
|
21 | Trap::Exception(Exception::StoreFault) |
| ^^^^^^^^^ use of undeclared type `Exception` error[E0433]: failed to resolve: use of undeclared type `Trap`
--> src/trap/mod.rs:17:9
|
17 | Trap::Exception(Exception::UserEnvCall) => {
| ^^^^ use of undeclared type `Trap` error[E0433]: failed to resolve: use of undeclared type `Exception`
--> src/trap/mod.rs:17:25
|
17 | Trap::Exception(Exception::UserEnvCall) => {
| ^^^^^^^^^ use of undeclared type `Exception` error[E0433]: failed to resolve: use of undeclared type `Trap`
--> src/trap/mod.rs:21:9
|
21 | Trap::Exception(Exception::StoreFault) |
| ^^^^ use of undeclared type `Trap` Some errors have detailed explanations: E0308, E0412, E0425, E0433, E0599.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `os` (bin "os") due to 34 previous errors
make: *** [Makefile:42: kernel] Error 101

看到大段的报错不要着急,首先先看容易解决,能够解决的.

首先是在batch.rs里加入use core::arch::asm;:

error: cannot find macro `asm` in this scope
--> src/batch.rs:84:9
|
84 | asm!("fence.i")
| ^^^
|
help: consider importing this macro
|
1 + use core::arch::asm;
|

同样地,在src/trap/mod.rs里边加入use core::arch::global_asm;:

error: cannot find macro `global_asm` in this scope
--> src/trap/mod.rs:3:1
|
3 | global_asm!(include_str!("trap.S"));
| ^^^^^^^^^^
|
help: consider importing one of these items
|
3 + use core::arch::global_asm;
|
3 + use crate::global_asm;
|

batch.rs加入use crate::trap::TrapContext;,这时候我们发现实际上在src/trap/mod.rs里也没有声明TrapContext则在里边声明mod context;:

error[E0412]: cannot find type `TrapContext` in this scope
--> src/batch.rs:34:36
|
34 | pub fn push_context(&self, cx: TrapContext) -> &'static mut TrapContext {
| ^^^^^^^^^^^ not found in this scope

后续有很多找不到TrapContext的问题,可能都会解决.

src/sync/up.rs里加入use core::cell::{RefCell, RefMut};:

error[E0412]: cannot find type `RefCell` in this scope
--> src/sync/up.rs:5:12
|
5 | inner: RefCell<T>,
| ^^^^^^^ not found in this scope
|
help: consider importing this struct
|
3 + use core::cell::RefCell;
|
error[E0412]: cannot find type `RefMut` in this scope
--> src/sync/up.rs:17:39
|
17 | pub fn exclusive_access(&self) -> RefMut<'_, T> {
| ^^^^^^ not found in this scope
|
help: consider importing this struct
|
3 + use core::cell::RefMut;
|

这里还有一个比较难搞的依赖问题,如果这个module不是自己实现的,那么一般考虑外部依赖问题,

error[E0433]: failed to resolve: use of undeclared crate or module `riscv`
--> src/trap/context.rs:2:5
|
2 | use riscv::register::sstatus::{self, Sstatus, SPP};
| ^^^^^ use of undeclared crate or module `riscv`

Cargo.toml加入riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }

同理,把所有的这种依赖性问题都解决, 不一定 是对应着这个报错列表来,而是可以选择根据rust-analyzer自动报错的内容,顺便改一下.

再次编译一下,发现有很多类似的报错:

error: missing documentation for an associated function

这意味着你在编译一个 Rust 项目时启用了某个 lint (编译时检查规则),该 lint 要求所有关联函数都必须有文档注释.

那么我们只需要给这些函数加上注释就行了.

还有一个新的问题:

error: unused variable: `metadata`
--> src/logging.rs:9:23
|
9 | fn enabled(&self, metadata: &Metadata) -> bool
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_metadata`
|

因为这个metadataenbaled函数中没有被调用,因此需要在其前面加一个下划线_,从而声明这个参数是故意不被调用的.

另外.trap.S需要被链接到.text部分,并且需要声明__alltraps__restore,因此需要加入这个.

    .section .text
.globl __alltraps
.globl __restore

最终得到的trap.S为:

.altmacro
.macro SAVE_GP n
sd x\n, \n*8(sp)
.endm
.macro LOAD_GP n
ld x\n, \n*8(sp)
.endm
.section .text
.globl __alltraps
.globl __restore
.align 2
__alltraps:
csrrw sp, sscratch, sp
# now sp->kernel stack, sscratch->user stack
# allocate a TrapContext on kernel stack
addi sp, sp, -34*8
# save general-purpose registers
sd x1, 1*8(sp)
# skip sp(x2), we will save it later
sd x3, 3*8(sp)
# skip tp(x4), application does not use it
# save x5~x31
.set n, 5
.rept 27
SAVE_GP %n
.set n, n+1
.endr
# we can use t0/t1/t2 freely, because they were saved on kernel stack
csrr t0, sstatus
csrr t1, sepc
sd t0, 32*8(sp)
sd t1, 33*8(sp)
# read user stack from sscratch and save it on the kernel stack
csrr t2, sscratch
sd t2, 2*8(sp)
# set input argument of trap_handler(cx: &mut TrapContext)
mv a0, sp
call trap_handler __restore:
# case1: start running app by __restore
# case2: back to U after handling trap
mv sp, a0
# now sp->kernel stack(after allocated), sscratch->user stack
# restore sstatus/sepc
ld t0, 32*8(sp)
ld t1, 33*8(sp)
ld t2, 2*8(sp)
csrw sstatus, t0
csrw sepc, t1
csrw sscratch, t2
# restore general-purpuse registers except sp/tp
ld x1, 1*8(sp)
ld x3, 3*8(sp)
.set n, 5
.rept 27
LOAD_GP %n
.set n, n+1
.endr
# release TrapContext on kernel stack
addi sp, sp, 34*8
# now sp->kernel stack, sscratch->user stack
csrrw sp, sscratch, sp
sret

最后运行结果是:

[rustsbi] RustSBI version 0.3.1, adapting to RISC-V SBI v1.0.0
.______ __ __ _______.___________. _______..______ __
| _ \ | | | | / | | / || _ \ | |
| |_) | | | | | | (----`---| |----`| (----`| |_) || |
| / | | | | \ \ | | \ \ | _ < | |
| |\ \----.| `--' |.----) | | | .----) | | |_) || |
| _| `._____| \______/ |_______/ |__| |_______/ |______/ |__|
[rustsbi] Implementation : RustSBI-QEMU Version 0.2.0-alpha.2
[rustsbi] Platform Name : riscv-virtio,qemu
[rustsbi] Platform SMP : 1
[rustsbi] Platform Memory : 0x80000000..0x88000000
[rustsbi] Boot HART : 0
[rustsbi] Device Tree Region : 0x87000000..0x87000f02
[rustsbi] Firmware Address : 0x80000000
[rustsbi] Supervisor Address : 0x80200000
[rustsbi] pmp01: 0x00000000..0x80000000 (-wr)
[rustsbi] pmp02: 0x80000000..0x80200000 (---)
[rustsbi] pmp03: 0x80200000..0x88000000 (xwr)
[rustsbi] pmp04: 0x88000000..0x00000000 (-wr)
[kernel] Hello, world!
[kernel] num_app = 5
[kernel] app_0 [0x8020a038, 0x8020b360)
[kernel] app_1 [0x8020b360, 0x8020c730)
[kernel] app_2 [0x8020c730, 0x8020dcd8)
[kernel] app_3 [0x8020dcd8, 0x8020f090)
[kernel] app_4 [0x8020f090, 0x80210440)
[kernel] Loading app_0
Hello, world!
[kernel] Application exited with code 0
[kernel] Loading app_1
Into Test store_fault, we will insert an invalid store operation...
Kernel should kill this application!
[kernel] PageFault in application, kernel killed it.
[kernel] Loading app_2
3^10000=5079(MOD 10007)
3^20000=8202(MOD 10007)
3^30000=8824(MOD 10007)
3^40000=5750(MOD 10007)
3^50000=3824(MOD 10007)
3^60000=8516(MOD 10007)
3^70000=2510(MOD 10007)
3^80000=9379(MOD 10007)
3^90000=2621(MOD 10007)
3^100000=2749(MOD 10007)
Test power OK!
[kernel] Application exited with code 0
[kernel] Loading app_3
Try to execute privileged instruction in U Mode
Kernel should kill this application!
[kernel] IllegalInstruction in application, kernel killed it.
[kernel] Loading app_4
Try to access privileged CSR in U Mode
Kernel should kill this application!
[kernel] IllegalInstruction in application, kernel killed it.
All applications completed!

可以看到启动了批处理系统之后,一个个APP运行,然后会想起用户层lib.rs中为每个app写得启动部分:

#[no_mangle]
#[link_section = ".text.entry"]
pub extern "C" fn _start() -> ! {
clear_bss();
exit(main());
panic!("unreachable after sys_exit!");
}

每次运行之后,

  1. 因为触发了异常而退出
  2. 直接由exit(main());退出

都会陷入trap,然后在trap_handler里处理,只要不出现没有预期到的Expectation都会调用run_next_app,因此所有的app按顺序运行.

最后完美结束了这一章,我真是一条懒狗,怎么什么坑都要踩一遍.

[rCore学习笔记 019]在main中测试本章实现的更多相关文章

  1. C# 动态生成word文档 [C#学习笔记3]关于Main(string[ ] args)中args命令行参数 实现DataTables搜索框查询结果高亮显示 二维码神器QRCoder Asp.net MVC 中 CodeFirst 开发模式实例

    C# 动态生成word文档 本文以一个简单的小例子,简述利用C#语言开发word表格相关的知识,仅供学习分享使用,如有不足之处,还请指正. 在工程中引用word的动态库 在项目中,点击项目名称右键-- ...

  2. Hadoop源码学习笔记(2) ——进入main函数打印包信息

    Hadoop源码学习笔记(2) ——进入main函数打印包信息 找到了main函数,也建立了快速启动的方法,然后我们就进去看一看. 进入NameNode和DataNode的主函数后,发现形式差不多: ...

  3. 《python基础教程(第二版)》学习笔记 文件和素材(第11章)

    <python基础教程(第二版)>学习笔记 文件和素材(第11章) 打开文件:open(filename[,mode[,buffering]]) mode是读写文件的模式f=open(r' ...

  4. 《python基础教程(第二版)》学习笔记 语句/循环/条件(第5章)

    <python基础教程(第二版)>学习笔记 语句/循环/条件(第5章) print 'AB', 123 ==> AB 123 # 插入了一个空格print 'AB', 'CD' == ...

  5. 《python基础教程(第二版)》学习笔记 类和对象(第7章)

    <python基础教程(第二版)>学习笔记 类和对象(第7章) 定义类class Person:    def setName(self,name):        self.name=n ...

  6. [C#学习笔记3]关于Main(string[ ] args)中args命令行参数

    Main(string[] args)方法是C#程序的入口,程序从这里开始执行,在这里结束.C#代码逻辑要包含在一个类型(Type)中,游离的.全局的变量或函数是不存在的,这里的类型包括类(class ...

  7. Android(java)学习笔记167:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  8. [C#] 类型学习笔记一:CLR中的类型,装箱和拆箱

    在学习.NET的时候,因为一些疑问,让我打算把.NET的类型篇做一个总结.总结以三篇博文的形式呈现. 这篇博文,作为三篇博文的第一篇,主要探讨了.NET Framework中的基本类型,以及这些类型一 ...

  9. Android(java)学习笔记110:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  10. Docker学习笔记之-在CentOS中安装Docker

    上一节演示了如何 通过Xshell连接CentOS服务,链接:Docker学习笔记之-通过Xshell连接 CentOS服务 本节将演示 如何在CentOS中安装 Docker 第一步:更新系统包到最 ...

随机推荐

  1. 机器学习策略篇:详解如何改善你的模型的表现(Improving your model performance)

    如何改善模型的表现 学过正交化,如何设立开发集和测试集,用人类水平错误率来估计贝叶斯错误率以及如何估计可避免偏差和方差.现在把它们全部组合起来写成一套指导方针,如何提高学习算法性能的指导方针. 所以想 ...

  2. 阿里bxet逆向

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 目标网站 x82y 分析过 ...

  3. 剑指Offer-59.按之字形顺序打印二叉树(C++/Java)

    题目: 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推. 分析: 实际上是二叉树的层次遍历,只不过每一行 ...

  4. java springboot 读取自定义配置文件

    java springboot 读取自定义配置文件 application.properties.test.properties maven中引用 : <dependency> <g ...

  5. filebeat实战

    1.打开filebeat支持nginx模块 [root@es-node1 /etc/filebeat]#ls fields.yml filebeat.reference.yml filebeat.ym ...

  6. Vue3:介绍

    Vue 3 相较于 Vue 2 在多个方面进行了改进和优化,主要优势包括但不限于以下几个方面: 响应式系统优化: Vue 3 引入了基于 Proxy 的响应式系统,取代了 Vue 2 中基于 Obje ...

  7. ConvertLatOrLonFilter-经纬度格式转换-保留6位

    ConvertLatOrLonFilter-经纬度格式转换-保留6位 /** * 转换经纬度 * 小数点最后最多为6位 * @param latOrLon * @return */ private S ...

  8. python 动态导入模块并结合反射,动态获取类、方法(反射太好用),动态执行方法

    背景: 关键字驱动框架,不同的关键字方法分别定义在不同的类,真正执行关键字方法又在不同的类(简称A),这样就需要在执行前,要在文件A下import要使用的模块,如果有很多页面操作或很多模块时,就需要每 ...

  9. 『vulnhub系列』Hack Me Please-1

    『vulnhub系列』Hack Me Please-1 下载地址: https://www.vulnhub.com/entry/hack-me-please-1,731/ 信息搜集: 使用nmap进行 ...

  10. 【ClickHouse】0:clickhouse学习2之数据类型

    一 :如何查看clickhouse具体支持哪些数据类型? 1:查看官方文档:https://clickhouse.tech/docs/en/sql-reference/data-types/ 2:查看 ...