zhoumrdewo - 2024年12月
type: channel
link: https://www.zhoumrdewo.com.cn/index.php/2024/12/
description: Your description here.
items: TrinityCore环境配置
items: 软件设计师中级考试经验贴
items: C++八股2
items: C++八股1
items: nodejs实习面试题

TrinityCore环境配置
type: item
date: 2024-12-20T04:03:00+08:00
description: Ubuntu24版本(安装配置不多介绍)(注意一定要4核心以上,4内存以上,45G以上)(如果外存没配对后面会不够用,可以用Disks扩容,核心不够安装会卡)安装完之后sudo apt-get update sudo apt-get install mysql-server //这个下的是8.0版本的 sudo apt-get install git clang cmake make gcc g++ libmysqlclient-dev libssl-dev libbz2-dev libreadline-dev libncurses-dev libboost-all-dev p7zip //编译项目要用的东西 sudo update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100 //使用clang编译 sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang 100 //使用clang编译 之后新建一个文件夹game,再创建一个bin文件夹在game里面git clone -b 3.3.5 https://github.com/TrinityCore/TrinityCore.git 在game文件夹里面创建一个build目录cmake ../ -DCMAKE_INSTALL_PREFIX=/home/coffee-candy/game -DCONF_DIR=/home/coffee-candy/game/bin make -j$(nproc) sudo make install 然后去下载魔兽世界客户端源码链接：https://pan.baidu.com/s/1jVQ4qoJ4qGNDHOBUzicIjg 提取码：imbo注意要全部下下来才能解压,解压完删掉就行然后就是Ubuntu和window建立共享文件夹(vmtool)如果在/mnt/hgfs没有找到共享的文件可以设置/usr/bin/vmhgfs-fuse .host:/ /mnt/hgfs -o subtype=vmhgfs-fuse,allow_other 然后在game的同级目录下创建res,把客户端里面的Data文件和Interface文件拉进去然后在res那边运行../game/bin/mapextractor ../game/bin/vmap4extractor ../game/bin/mapextractor ../game/bin/vmap4extractor 然后添加数据库信息source /home/coffee-candy/game/TrinityCore/sql/create/create_mysql.sql看到被选中的文件夹,你没有的就是要拷贝.dist文件cp worldserver.conf.dist worldserver.conf //比如 然后启动,在./worldserver看到报错./worldserver ./authserver 比如我上面写的是TDB_full_world_335.24111_2024_11_22.sql找不到那么就是下这个,压缩包下下来之后解压去gitbub,release下载对应的sql文件 https://github.com/TrinityCore/TrinityCore/releases登录sql执行source /home/coffee-candy/game/TrinityCore/sql/create/create_mysql.sql use auth; update realmlist set address ='192.168.168.140' where id=1; //这address写自己的ip,vm虚拟机的ip或者你服务器的ip 然后再./worldserver服务的TC>创建账号account create coffee_candy 1234 //create 后面是账号,密码 然后去到你的客户端找到wow.exe的同级目录创建init_connect.bat,里面的内容如下,里面的ip写你自己的echo y | rd /s "Cache" echo SET realmlist "192.168.168.140" > Data\zhTW\realmlist.wtf echo SET realmlist "192.168.168.140" > Data\enTW\realmlist.wtf echo SET realmlist "192.168.168.140" > Data\zhCN\realmlist.wtf echo SET realm…

软件设计师中级考试经验贴
type: item
date: 2024-12-12T22:06:00+08:00
description: 我的评价是so easy有手就行考点主要涉及408基础,网络安全,软件工程,数据库原理,编程语言方面涉及(python,c++,c,java)以前是分上下午题也就是选择题和大题,24年改机试后现在上下午题一起写,选择题和大题满分各75,要求每一科>=458:30开始考4个小时,前2小时考选择题,1.5小时后可以提交选择题做大题(一定要注意不要选离场这个时候,选继续作答),这个时候就有2.5小时做大题推介up zst_2001 b站链接学习资料可以看这个up的贴子资料链接考试报名与流程报名网站上半年一般在5月考下半年一般在11月考,一般提前3个月报名,注意留意报名通知注意这里有个模拟练习,一般是考前7天开放的,具体操作可以看up的视频,一定要在考前试一次模拟练习平台它和你的考试环境是一样的学习方法首先一定要记住不要特地去看知识点视频,做题做真题,真题做烂为止,报名完之后的3个月时间完全足够了遇到真题不会的去看up视频,边做真题边记真题知识点就是这一栏,全部看完做题的顺序先做两个月选择题,先是两天一套选择题可以用这个网站做题51cto或者51cto也是有小程序的选择题做过半了之后开始做大题,也是两天一套,这个时候选择题开始有点底了就可以一天一套的大题最好是用纸质版或者平板做题,然后在做大题之前,先听一年的大题讲解先对大题有个大概的概念然后偶尔复习一下错题(用51cto的小程序) 好嘞祝各位考试顺利,一次过

C++八股2
type: item
date: 2024-12-10T02:28:00+08:00
description: 操作系统阻塞IO和非阻塞IO阻塞的文件描述符为阻塞IO非阻塞的文件描述符为非阻塞IO同步IO和异步IO同步IO向应用程序通知的是IO就绪事件。要求用户代码自行执行读写操作，将数据从内核缓冲区读入用户缓冲区。异步IO向应用程序通知的是IO完成事件 。由内核来执行IO读写操作。在linux环境下，aio.h头文件定义的函数提供了对异步IO的支持。事件处理模式reactor 同步IO模型通常用于实现reactor模式。要求主线程只负责监听文件描述符是否有事件发生，有的话就立即将该事件通知工作线程。proactor 异步IO模型通常用于实现proactor模式。也可以用同步IO模拟出proactor模式。proactor将所有IO操作都交给主线程和内核来处理，工作线程仅仅负责业务逻辑。Reactor模式的工作流程主线程往epoll内核事件表中注册socket上的就绪事件。主线程调用epoll_wait等待socket上有数据可读。当socket上有数据可读时，epoll_wait通知主线程。主线程将socket可读事件放入请求队列。睡眠在请求队列上的某个工作线程被唤醒，它从socket读取数据，并处理客户请求，然后往epoll内核事件表中注册该socket上的写就绪事件。主线程调用epoll_wait等待socket可写。当socket可写时，epoll_wait通知主线程。主线程将socket可写事件放入请求队列。睡眠在请求队列上的某个工作线程被唤醒，它往socket上写入服务器处理客户请求的结果。并发模式半同步半异步模式：同步线程用于处理客户逻辑，异步线程用于处理IO事件。异步线程监听到客户请求后，就将其封装成请求对象并插入到请求队列中，请求队列将通知某个工作在同步模式下的工作线程来读取并处理该请求对象。半同步半反应堆模式采用的事件处理模式是reactor模式：它要求工作线程自己从socket上读取客户请求和往socket写入服务器应答。半同步半反应堆也可以模拟proactor模式，即由主线程来完成数据的读写。在这种情况下，主线程会将应用程序数据，任务类型等信息封装为一个任务对象，然后将其插入请求队列。工作线程从请求对象取得任务对象以后，可直接处理无需执行读写操作。问题：主线程和工作线程共享请求队列需要加锁。工作线程较少时可能产生请求任务堆积。领导者追随者模式在IO模型中，同步和异步区分的是内核向应用程序通知的是何种事件，是就绪事件还是完成事件，以及该由谁来完成IO读写，是应用程序还是内核。在并发模式中，同步指的是程序完全按照代码序列的顺序执行。异步指的是程序的执行需要由系统事件来驱动。常见的系统事件包括中断和信号。虚拟地址空间虚拟地址是操作系统管理内存的一种方式。方便不同进程使用的虚拟地址彼此隔离。方便物理内存中不相邻的内存在虚拟地址上视为连续的来使用。虚拟地址和物理地址的映射是通过MMU页表进行的。虚拟内存对实际内存有保护作用。什么是进程进程是系统进行资源分配的基本单位，是程序加载到内存后的执行过程。进程一般由数据段，代码段和进程控制块三部分组成。系统通过进程控制块感知进程的存在并对进程进行控制。由于进程之间空间相互独立，多进程比多线程更安全，一个进程基本上不会影响另外一个进程。进程三种状态创建：创建PCB就绪运行阻塞终止: 归还PCB什么是线程线程是CPU调度的基本单位。一个进程可以包含多个线程，线程自己基本不拥有系统资源，但是它可以和同属于一个进程的其他线程共享进程所拥有的全部资源。多线程之间对内存共享，线程间通信可以直接基于共享内存来实现，比多进程之间通信更轻量。多线程之间切换不需要切换虚拟内存空间、文件描述符等，所以线程的上下文切换也比多进程轻量。进程fork以后，遵循读时共享写时复制的机制。父子进程长期共享：文件描述符和mmap建立的映射区。子进程的进程ID，定时器，未决信号集和父进程不同。多进程和多线程的应用场景一般不同任务间需要大量的通信，使用多线程的场景比多进程多。IO密集型。但是多进程有更高的容错性，一个进程的崩溃不会导致整个系统的崩溃，在任务安全性较高的情况下，采用多进程。CPU密集型。## 进程线程的本质区别进程更安全，一个进程完全不会影响另外的进程。进程间通信比线程间通信的性能差很多。线程切换开销更低。IPC进程间通信55555555555无名管道pipe（血缘关系的进程）有名管道fifo （无血缘关系的进程）共享内存信号(开销小)消息队列信号量套接字进程间同步文件锁信号量线程间同步互斥锁读写锁(读时共享，写时互斥)条件变量信号量(互斥锁的升级版)自旋锁(可以避免进程或线程上下文的开销)线程共享资源文件描述符表（打开的文件）进程用户ID和进程组ID进程的内存地址空间.text代码段 .data数据段 .…

C++八股1
type: item
date: 2024-12-10T02:20:00+08:00
description: C/C++基础1. 智能指针实现原理智能指针通过 RAII 原则，利用 C++ 栈的生命周期来管理堆内存的动态分配和释放，避免手动 delete 操作。unique_ptr：管理独占资源，仅支持移动语义，不能复制。shared_ptr：通过引用计数实现多个对象共享同一资源。weak_ptr：辅助 shared_ptr，解决循环引用问题。2. 智能指针的计数器何时改变shared_ptr 的引用计数在：新的 shared_ptr 指向同一资源时增加。shared_ptr 被销毁或赋值为其他对象时减少。当引用计数为 0 时，释放资源。3. 智能指针和管理对象分别在哪个区智能指针本身存储在栈区。它所管理的资源存储在堆区。4. 面向对象的特性：多态原理多态通过虚函数实现，允许不同类型的对象使用相同的接口。底层实现：虚函数通过虚表（vtable）实现。每个包含虚函数的类都有一个虚表指针（vptr），在对象创建时初始化。调用虚函数时，依据 vptr 定位到具体类的虚表，执行相应的函数。5. 介绍虚函数及其实现虚函数是通过 vtable 实现的。vtable 存储了虚函数的地址。每个对象都有一个指向其类的 vtable 的指针 vptr。运行时通过 vptr 查找函数地址，实现动态绑定。6. 多态和继承在什么情况下使用多态：当需要根据不同子类行为实现动态调用时使用。继承：当需要复用父类代码，且子类与父类有 "is-a" 关系时使用。7. 除了多态和继承还有什么面向对象方法封装：通过访问修饰符（public、protected、private）隐藏数据细节。抽象：定义抽象类或接口，强调对象的行为而非实现。8. C++ 内存分布栈区：局部变量、函数调用信息。堆区：动态分配的内存。全局区：全局变量、静态变量。常量区：字符串字面值、常量。代码区：存储程序的二进制代码。9. C++ 内存管理（RAII）RAII 是通过构造函数获取资源，通过析构函数释放资源的设计模式。常用类包括：std::unique_ptr 和 std::shared_ptr。文件流（如 std::fstream）。10. C++ 从源程序到可执行程序的过程预处理：处理宏定义和头文件。编译：将 C++ 源代码转换为汇编代码。汇编：将汇编代码转换为机器代码。链接：将多个目标文件和库合并为可执行程序。11. 一个对象 = 另一个对象会发生什么调用赋值运算符（operator=），默认行为是逐成员赋值。可以重载该运算符以实现深拷贝。12. new 出错直接 return 会导致内存泄漏，怎么办使用智能指针（如 std::unique_ptr）来管理动态资源。利用 RAII 确保异常时资源自动释放。13. C++11 的智能指针及循环引用智能指针：unique_ptr：独占资源。shared_ptr：共享资源。weak_ptr：避免循环引用。循环引用：两个 shared_ptr 相互引用，引用计数无法归零。通过 weak_ptr 打破循环。14. 多进程 fork 后的共享资源共享资源：程序代码段。打开的文件描述符。不共享：堆、栈。15. 多线程同步方式互斥锁（std::mutex）读写锁（std::shared_mutex）条件变量（std::condition_variable）原子变量（std::atomic）16. sizeof 是在编译期还是运行期确定编译期：sizeof 是一个编译期操作符，确定类型或对象的大小。17. 函数重载机制重载基于函数签名（函数名+参数类型）。通过编译期的名称修饰（name mangling）实现。18. 指针常量与常量指针指针常量（T* const）：指针地址不可变，但指向的内容可变。常量指针（const T*）：指针指向的内容不可变，但地址可变。19. vector 的原理与扩容原理：基于动态数组。扩容：当容量不足时，分配更大的内存块并迁移数据。20. const 的作用修饰变量：只读变量。修饰函数：保护成员变量不被修改。修饰指针：见问题 18。21. 引用与指针的区别引用必须初始化，指针可以为空。引用不可改变绑定的对象，指针可以。22. C++11 新特性智能指针（unique_ptr、shared_ptr）。右值引用与移动语义。auto、decltype。Lambda 表达式。继续解答 C/C++ 基础部分的问题：23. 类型转换C++ 提供以下类型转换方式：C 风格强制转换：(T)value。C++ 风格强制转换：static_cast：常规转换，如基本类型间转换、子类到父类的转换。dynamic_cast：用于多态类型，运行时检查安全性。const_cast：用于去除或添加 const 修饰。reinterpret_cast：直接改变类型的…

nodejs实习面试题
type: item
date: 2024-12-07T23:42:00+08:00
description: 我写的一坨大便的答案(没有包含MVC设计模式)shop.tsimport * as http from 'http'; const axios=require('axios') const express=require('express') // websocket,tcp,socket.io const socketio=require('socket.io') const fs = require('fs'); const path = require('path'); const jwt=require('jsonwebtoken') const {expressjwt} = require('express-jwt'); const app=express(); const server = http.createServer(app) const bodyParser = require('body-parser'); const io=socketio(server,{ path:'/socket.io/', pingTimeout: 1000 * 60,//超时时间 pingInterval: 1000 * 1,//ping的时间 transports: ['websocket', 'polling'],//传输方式 allowUpgrades: true,//传输是否升级 httpCompression: true,//是否加密 allowEIO3: true, cors:{ origin: "https://127.0.0.1:8080", // 必须和客户端请求的 origin 一致 methods: ["GET", "POST"], credentials: true }, connectionStateRecovery: { // the backup duration of the sessions and the packets maxDisconnectionDuration: 2 * 60 * 1000, // whether to skip middlewares upon successful recovery skipMiddlewares: true, } }); //测试用数据添加 import { ShopDataStructure } from './shopdatastructure'; let data_structure= [ { id: 1, name: "Chicken Wing", category: "Food", qty: 3, price: 10 }, { id: 2, name: "Pizza", category: "Food", qty: 1, price: 50 }, { id: 3, name: "Hamburger", category: "Food", qty: 1, price: 12 }, { id: 4, name: "Coca Cola", category: "Drink", qty: 2, price: 5 }, { id: 5, name: "Orange Juice", category: "Drink", qty: 1, price: 15 }, { id: 6, name: "Potato Chips", category: "Snack", qty: 1, price: 8 }, { id: 7, name: "tomato", category: "Vegetable", qty: 1, price: 2 }, ] let shopdatastructure=new ShopDataStructure(); shopdatastructure.InitShopDataStructure(data_structure) app.get('/all',(req:any,res:any)=>{ let alldata=shopdatastructure.GetIdAllData()//一个map let returndata:any[]=[]; for(let data of alldata) { returndata.push(data); } res.send({alldata:returndata}); }) app.get('/all/:id',(req:any,res:any)=>{ const id = parseInt(req.params.id); console.log(id) let alldata=shopdatastructure.GetIdAllData()//一个map console.log(alld…