LOADING

加载过慢请开启缓存 浏览器默认开启

Mouz.CN

Sunshine鼠鼠的博客

记录日常的收获和发电

域名更新

2026/6/5

由于原来的域名过期了,
并且续费比新搞一个贵很多,我觉得买个好点的域名,以便以后把我的项目都挂起来。
故域名更改为mouz.cn

阅读全文

DarkBeach

2025/11/21

我梦到一片黑色的沙滩,上面中满着紫蔷薇,蔷薇是怎么活下去的呢,我不知道。
我在蔷薇中躺下,蔷薇是带刺的,衣服被划破了,紫蔷薇带红了。
但是紫蔷薇好香啊,香味和痛苦让我无法起身。
就在这里死去吧,让残躯滋润沙滩,下一世,我希望看到红色的玫瑰。

阅读全文

草原

2025/11/21

我看到一片草原,
草原上有个带着阳伞的白桌,
桌上放着面板牛奶和蜂蜜,
所有人都是穿着白衣在草原上跑和笑,
人们做的事情不用价值和效率衡量,
打开日历,今天就是今天,明天就是明天,不是什么截止日期也不是什么工作日休息日。

阅读全文

那就当盆友吧

2025/11/21

她问我爱她吗,我摇头。
我骗了她,我也骗了自己。
我暗示自己不爱任何人,却忍不住幻想有她的未来。
我嫉妒她的恋人,幻想她被背叛的时候找我哭诉,然后我把那个男人揍一顿。
然后她问我爱她吗,我还是摇头。

阅读全文

2025/11/21

有天我死了,我期待大家哭一场然后忘了我,
不用告诉她我爱她,告诉妈妈就行,
我希望把所有财产分给生命中重要的每个人,
然后把骨灰埋进土里面,然后上面种一棵小树。

阅读全文

堂吉诃德

2025/11/21

(写在前面,其实不是什么抑郁,就是半夜脑子爱乱想,
然后我觉得想出来的也不是垃圾,就还是记录一下吧,都是之前写的)
其实我要成为堂吉柯德了,
我幻想共享单车是风驰电掣的摩托,
我幻想亚力克立牌是最温柔美丽的妻子,
我幻想手里有把杀死恶人的枪,
我幻想生活是个伟岸的巨人而我手上也有把利剑,哦,谁愿当我人生的桑丘。

阅读全文

搞了个新电脑

2025/11/21

好吧,其实最近没咋更新。
一大原因是沟槽的软件学院B事情太多了。
另一方面是趁着最后的国补,用攒下来的钱买了个MacBook air M4 16+512,
代码和学习什么的都在MACOS上搞了,WINDOWS游戏本只在玩游戏的时候打开,
并且这个博客网站文件都在WIN机上,老是忘。
还别说MACOS虽然不习惯一些,但是干活学习什么的舒服多了,谁叫WIN11破毛病那么多。

阅读全文

C和Rust混合探索

2025/9/16

前言
先锋的同学鼓励对于C和Rust混合编程的探索,那就开始吧。
面试题内容之前我多多少少略有涉猎,但是Rust我还真没听过。
之前我一直认为C的恼人的手动管理内存和Java基本数据类型无法修改值等问题是存在于是就合理的,似乎是自它们诞生之初就无法改变的特点。但是目前看来Rust给了个解决方案。但是我觉得语言更不美了 :joy:
C和Rust混合探索
Java、Python和C++ 之间的互调用常常依赖于各自的外部函数接口(FFI)或特定的绑定库。
但是ABI主要用于静态编译(源码转机器码,机器码转可执行文件)的语言,例如 C 和 C++。所以C和Rust使用ABI进行互相调用咯。
调用问题(上)
Rust调用C
在Rust中,先要链接c文件(夹)

#[link(name = "your_c")]

需要使用extern “C”来声明”我要调用c咯”

extern "C" {
    fn add_numbers(a: i32, b: i32) -> i32;//问题:这是什么?
}

调用C语言代码时,Rust编译器无法保证内存安全,因为C语言没有内置的内存安全机制。因此,所有的调用都必须放在unsafe{ }里面。

fn main() {
    unsafe {
        let result = add_numbers(10, 20);
        println!("sum: {}", result);
    }
}

数据类型映射
好的,我们不得不先解决数据映射的问题。:worried:
众所周知,rust整数类型按位长度划分(如i8/i16/i32…u8/u16/u32…)且整数常量默认为i32,因此里面的a、b就是属于系统默认的整数类型,跟C里面的int很像对吧。
Rust的标准库提供了许多与C语言类型对应的类型,数据类型互通正如货币互通,这样两边才好说话吧。
直接叫ai帮忙造个表格~~~~懒得手打~~

C 语言类型 Rust 对应类型 备注
char c_char 通常为 i8u8
int c_int 通常为 i32
float c_float 相当于 f32
double c_double 相当于 f64
void c_void 用于指针,如 void * 对应 *mut c_void
char * *mut c_char 指向 C 字符串的可变指针。
const char * *const c_char 指向 C 字符串的不可变指针。
struct #[repr(C)]struct 必须使用 #[repr(C)] 宏保证内存布局兼容。
enum #[repr(C)]enum 必须使用 #[repr(C)] 宏保证大小和布局兼容。

调用问题(下)
好的好的,数据类型映射问题暂时解决了,继续。
C语言调用Rust函数时,首先需要将Rust函数暴露为C语言兼容的ABI。
具体方式是使用#[no_mangle]和extern “C”这两个属性来修饰函数。

#[no_mangle]//告诉编译器不要对函数名进行“名字重整”
pub extern "C" //按照C语言来编订这个函数
fn add_numbers(a: i32, b: i32) -> i32 {
    a + b
}

第二步将Rust代码编译成一个C动态链接库或者静态链接库(这样C语言才能调用)如示例:

[lib]
name = "rust_lib"
crate-type = ["cdylib"]

然后运行

cargo build --release

生成的库文件将默认位于target/release/目录下。(先锋示例好像没有,是要我自己来吗?)
最后,在C语言代码中,就可以像调用其他C函数一样调用这个Rust函数。

extern int rust_add(int a, int b);// 记得声明Rust函数

但是,先锋示例也不是这样喵。
方法是提供了个头文件,有点像接口。

// rust_functions.h
#ifndef RUST_FUNCTIONS_H
#define RUST_FUNCTIONS_H

int add_numbers(int a, int b);
int multiply_numbers(int a, int b);
#endif

这样其他文件只需要 #include 这个头文件就行了,可以调用了。好吧,这也是种省事的方法。

阅读全文

galgame尝试小记

2025/8/6

一直以来都有自己制作galgame的想法…
暑假花了一些时间尝试使用Ren’Py引擎制作自己的同人galgame《期末周与欧娜尼》
不得不说Ren’Py的语法真的好简单,几乎没啥技术门槛(可能是我不够深入)
为了配音,我还学习了GPT-SoVITS-v2pro训练ai语音的方法(还做了个五字神人小视频)
虽然配音听起来ai味确实很重,但作为练手是足够了
游戏的demo版本已经上传到github上了,感兴趣的可以尝尝(虽然比较粗糙)…

PS:JAVA期末拾遗还是比较成功的,最后拿了4.0.

阅读全文

Java期末拾遗-下半

2025/7/3

1.编译器和解释器的区别
编译器是“一次性翻译,整体执行”,解释器是“一边翻译,一边执行”。
对比图(改自GPT):

对比项 编译器(Compiler) 解释器(Interpreter)
翻译方式 一次性将整个源代码编译成可执行文件 逐行解释源代码并立即执行
输出结果 可执行文件(如 .exe.class 等) 无独立可执行文件,直接运行
执行效率 高(编译后运行快) 较低(每次运行都要解释)
调试方便程度 不易定位具体错误行(需要整个编译过程) 容易定位(出错立即停止)
第一次运行速度 慢(需要先编译) 快(直接运行)
依赖环境 编译后可独立运行,不再依赖编译器 每次运行都依赖解释器
常见语言 C、C++、Java(先编译成字节码) Python、JavaScript、Ruby

需要注意的是:Java既是编译型又是解释型语言。
这句话看起来矛盾,其实是因为 Java 有两个阶段的执行过程,结合了编译型语言和解释型语言的特点。
第一步:编译(Compiler)
Java 源代码(.java 文件)会先被 编译器(javac) 编译成 字节码文件(.class),这个过程是一次性编译,类似于 C、C++ 的编译阶段。
第二步:解释(Interpreter)或即时编译(JIT)
编译后的 .class 文件不是直接执行的,而是由 Java 虚拟机(JVM) 来运行:
JVM 内部会用 解释器 把字节码一行一行“翻译”成机器指令并执行。
同时,JVM 的 JIT(Just-In-Time)编译器 会把频繁执行的字节码“临时编译”为本地机器码,提高效率。

2.static变量
static 变量(也叫静态变量),是属于类(class)而不是对象(object)的变量。
static能够修饰成员变量和方法,内部类,也可以形成静态static代码块,不能修饰局部变量。
静态代码块:定义在成员位置,使用static修饰的代码块{},随着类的加载而执行,且执行一次,优先于main方法和构造方法的执行。
static 变量在内存中只存在一份,它是随着类的加载而加载的,且只加载一次。例如:
Java 程序的入口方法 main是一个 static(静态)方法。

public static void main(String[] args){}

它优先于对象存在,所以,可以被所有对象共享。
需要注意的是:静态方法不能访问非静态变量,因为它没有 this 对象。
静态方法在没有任何对象的情况下就可以被调用,而非静态变量属于某个对象,必须通过 this 才能访问。
this 代表当前对象的引用,而静态方法属于类本身,不属于任何对象,所以它没有 this。

static void print() {
    System.out.println(name); // ❌ 错误,name 是非静态变量
}

3.多态、重写与重载
重写:
重写是实现多态的必要前提之一。
子类出现重名的成员方法(返回值类型,方法名和参数列表都相同),访问是特殊情况,声明不变,将父类方法重新实现。
需要注意:1.子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。
2.子类方法覆盖父类方法,必须要保证权限大于等于父类权限(例如父类是 public,子类不能是 protected),
子类抛出的异常不能比父类方法更宽泛。
例如:

class Animal {
    void makeSound() {
        System.out.println("Animal sound");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Bark");
    }
}

重载:
在一个类中方法名相同,但参数不同(类型或个数),返回类型可以相同或不同的多个方法。

特性 内容
是否需要继承 无需继承,可在同一个类中定义
方法名 相同
参数列表 必须不同(类型、数量或顺序不同)
返回类型 可以不同,但不能靠返回类型区分方法

例如:

class Calculator {
    int add(int a, int b) {
        return a + b;
    }

    double add(double a, double b) {
        return a + b;
    }

    int add(int a, int b, int c) {
        return a + b + c;
    }
}

需要注意的是:Java支持构造函数重载(Constructor Overloading),即一个类可以有多个构造函数,只要它们的参数列表不同(参数类型、顺序或数量不同)。
多态:
多态是指同一行为,具有多个不同的表现形式。
即父类定义了一个方法,而子类方法重写该方法时方法主体不一样,
这样在不同子类里面这个方法的实现形式就不一样,能让程序更有扩展性。
需要注意:当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误,不能调用子类拥有,而父类没有的方法。想要调用子类特有的方法,必须做向下转型。
多态例如:

class Animal {
    void makeSound() { }
}

class Dog extends Animal {
    @Override
    void makeSound() {  //对于Cat子类,makeSound方法是Bark
        System.out.println("Bark");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {  //对于Cat子类,makeSound方法是Hajimi
        System.out.println("Hajimi");
    }
}

4.关系
在画类图的时候,”is-a” 和 “has-a” 是两种最基础的关系。

  1. “is-a” 关系(继承/实现),包括子类 继承 父类,或类 实现 接口。
    继承(类 → 类):空心三角箭头(子类指向父类),如:Dog ──────▷ Animal
    实现(类 → 接口):虚线空心三角箭头 或 棒棒糖表示法,如:
    Dog ⤍ «interface» Runnable或Dog ───○ Runnable
  2. “has-a” 关系(组合/聚合/关联),表示一个类包含另一个类的对象。
    组合(Composition):强依赖,部分不能脱离整体存在(如 Car 和 Engine)。
    聚合(Aggregation):弱依赖,部分可以独立存在(如 University 和 Department)。
    关联(Association):普通的持有关系(如 Student 和 Course)。
    关系类型 符号 示例 说明
    组合 实心菱形 ◆── Car ◆── Engine 生命周期绑定,强依赖
    聚合 空心菱形 ◇── University ◇── Department 生命周期独立,弱依赖
    关联 实线箭头 ───> Student ───> Course 普通持有关系

5.java易忘英语单词汇总
inherit 继承 subclass(child class)子类 equivalent 等价的、同义的
signature 署名 coexist 共存 invoke 调用 instantiate 实例化 abnormalities紊乱
execute 执行 exception handler 异常处理器 stack trace 堆栈跟踪
scope 作用域 wrapper 包装 instance 实例 arguments 参数 集合Collection
accommodate 为…提供空间 aggregation 聚合关系 index 索引(下标)
attribute 属性

6.访问权限问题
对于父类来说:
private:仅当前类可访问(子类和其他类均不可见)。
default(包私有):同一包内的类可访问(子类如果在不同包则不能访问!)。
protected:同一包内的类 + 不同包的子类可访问。
public:所有类均可访问。

7.java文件中的注释问题

注释类型 语法 用途 是否生成 Javadoc
单行注释 // 临时注释或简短说明 ❌ 否
多行注释 /* ... */ 跨行注释,适合较长说明 ❌ 否
Javadoc /** ... */ 生成 API 文档(含 @param 等标签) ✅ 是
阅读全文
avatar
Sunshine

东北大学 软件学院
喜欢二次元、打游戏,努力学习中