面试常见手撕代码

目录

1.线程池 and 数据库连接池

2.生产者,消费者问题

3.排序算法


1.线程池 and 数据库连接池

线程池

#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>class ThreadPool
{
public:ThreadPool(size_t numThreads) : stop(false){for (size_t i = 0; i < numThreads; ++i){workers.emplace_back([this]{while (true) {std::function<void()> task;{std::unique_lock<std::mutex> lock(queueMutex);condition.wait(lock, [this] { return stop || !tasks.empty(); });if (stop && tasks.empty()) return;task = tasks.front();tasks.pop();}//取出任务队列中执行该任务task();} });}}template <class F>void enqueue(F &&f){{std::unique_lock<std::mutex> lock(queueMutex);tasks.emplace(std::forward<F>(f));}condition.notify_one();}~ThreadPool(){{std::unique_lock<std::mutex> lock(queueMutex);stop = true;}condition.notify_all();for (std::thread &worker : workers){worker.join();}}private:std::vector<std::thread> workers;std::queue<std::function<void()>> tasks;std::mutex queueMutex;std::condition_variable condition;bool stop;
};int main()
{ThreadPool pool(4);for (int i = 0; i < 8; ++i){pool.enqueue([i]{ std::cout << "Task " << i << " executed by thread " << std::this_thread::get_id() << std::endl; });}this_thread::sleep_for(chrono::seconds(1));system("pause");return 0;
}

说明:

1. **初始化线程池**:在创建线程池对象时,通过构造函数指定线程池中的线程数量。线程池会创建相应数量的工作线程,并启动这些线程等待任务。

2. **添加任务**:通过 `enqueue` 函数向线程池中添加任务。每个任务都是一个可调用对象,可以是函数、lambda 表达式或者其他可调用对象。添加任务时,会将任务移动到任务队列中,并通过条件变量通知等待中的工作线程有新任务可以执行。

3. **工作线程执行任务**:每个工作线程会循环执行以下操作:
   - 等待条件变量的通知,一旦有新任务到来或者线程池被停止,就会被唤醒。
   - 从任务队列中取出一个任务并执行。如果任务队列为空且线程池未被停止,线程会继续等待新任务的到来。
   - 执行完任务后,继续循环等待新任务。

4. **停止线程池**:当需要销毁线程池时,调用析构函数或者手动调用停止函数。停止函数会将停止标志设置为 `true`,并通过条件变量通知所有工作线程线程池即将停止。
工作线程在收到停止通知后会执行完当前任务并退出线程。

5. **资源回收**:在线程池被销毁时,会等待所有工作线程执行完当前任务并回收资源。这包括等待所有工作线程结束并调用 `join` 函数等待线程结束。
 

数据库连接池

        


#include <iostream>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <chrono>// 模拟数据库连接类
class Connection {
public:void executeQuery(const std::string& query) {std::cout << "Executing query: " << query << std::endl;// 模拟执行查询操作std::this_thread::sleep_for(std::chrono::seconds(1));}
};class ConnectionPool {
private:std::queue<Connection*> connections;std::mutex mtx;std::condition_variable cv;const int poolSize;public:ConnectionPool(int size) : poolSize(size) {for (int i = 0; i < poolSize; ++i) {connections.push(new Connection());}}Connection* getConnection() {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, [this] { return !connections.empty(); });Connection* conn = connections.front();connections.pop();return conn;}void releaseConnection(Connection* conn) {std::lock_guard<std::mutex> lock(mtx);connections.push(conn);cv.notify_one();}~ConnectionPool() {while (!connections.empty()) {delete connections.front();connections.pop();}}
};int main() {ConnectionPool pool(5);// 从连接池中获取连接并执行查询Connection* conn1 = pool.getConnection();conn1->executeQuery("SELECT * FROM table1");pool.releaseConnection(conn1);// 可以继续获取连接并执行其他操作return 0;
}
  1. Connection类模拟了一个数据库连接,其中有一个executeQuery方法用于执行查询操作。在这个方法中,会输出要执行的查询语句,并通过std::this_thread::sleep_for来模拟查询操作需要的时间。

  2. ConnectionPool类是连接池类,其中包含了一个连接队列connections,一个互斥锁mtx用于保护对连接队列的访问,一个条件变量cv用于在连接队列为空时等待新连接的到来,以及连接池的大小poolSize

  3. ConnectionPool的构造函数中,会初始化指定数量的连接对象并放入连接队列中。

  4. getConnection方法用于从连接池中获取连接。首先会对互斥锁进行加锁,然后通过条件变量等待直到连接队列不为空。一旦有可用连接,就从队列中取出一个连接并返回。

  5. releaseConnection方法用于释放连接,将连接放回连接队列中,并通过条件变量通知等待的线程有新的连接可用。

  6. main函数中,首先创建了一个大小为5的连接池pool。然后从连接池中获取一个连接conn1,执行了一个查询操作,最后通过releaseConnection方法将连接放回连接池中。

这样,通过连接池可以有效地管理数据库连接,避免频繁地创建和销毁连接,提高了数据库操作的效率和性能。

2.生产者,消费者问题

#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
using namespace std;
#define PRODUCT_SIZE 2
#define CUSTUM_SIZE 2
#define POOL_SIZE 3
mutex m;
condition_variable cv;
queue<int> que;
int num = 0;//生产者线程。
void producter()
{while (true){std::unique_lock<std::mutex> lck(m);while (que.size() >= POOL_SIZE){cv.wait(lck);}int data = num++;que.push(data);cout << this_thread::get_id() << "produce " << data << endl;cv.notify_all();}
}
void customer()
{while (true){std::unique_lock<std::mutex> lck(m);while (que.empty()){cv.wait(lck);}cout << this_thread::get_id() << "consume " << que.front() << endl;que.pop();cv.notify_all();}
}int main()
{vector<thread> pools;//将生产者线程加入线程容器中。for (int i = 0; i < PRODUCT_SIZE; i++){pools.push_back(thread(producter));}//将消费者线程加入线程容器中。for (int j = 0; j < CUSTUM_SIZE; j++){pools.push_back(thread(customer));}//等待线程池中,所有线程都执行完毕。for (int i = 0; i < PRODUCT_SIZE + CUSTUM_SIZE; i++){pools[i].join();}cin.get();return 0;
}

3.排序算法

冒泡排序:N个数需要进⾏N-1次冒泡,每次冒泡确定⼀个最⼤值位置。元素交换次数为原数组逆序度。

void bubbleSort(std::vector<int> &nums, int n)
{for (int i = 1; i < n; ++i){ // 冒泡次数bool is_swap = false;for (int j = 1; j < n - i + 1; ++j){if (nums[j] < nums[j - 1]){std::swap(nums[j], nums[j - 1]);is_swap = true;}}if (!is_swap)break;}
}
插⼊排序:分为已排序和未排序,初始化已排序区间只有数组第⼀个元素。遍历未排序的每⼀个元素, 倒序⽐较与已排序区间的⼤⼩关系,确定当前未排序元素的位置。元素交换次数为原数组逆序度
void insertSort(std::vector<int> &nums, int n)
{for (int i = 1; i < n; ++i){for (int j = i; j > 0 && nums[j] < nums[j - 1]; --j){std::swap(nums[j], nums[j - 1]);}}
}
选择排序:从头开始遍历数组,然后将该元素与其后⾯的区间进⾏⽐较,选择最⼩的元素并交换

void selectSort(std::vector<int> &nums, int n)
{for (int i = 0; i < n - 1; ++i){int k = i;for (int j = i + 1; j < n; ++j){if (nums[j] < nums[k]){k = j;}}std::swap(nums[k], nums[i]);}
}
快速排序:先找到⼀个枢纽,然后在当前数组中把⽐这个枢纽⼩的元素放左边,⼤的元素放右边,两部 分数据依次递归排序下去直到有序。
归并排序:⾸先将数组等分递归排序,然后通过⼀个临时数组,⽐较两个数组的⼤⼩从⽽合并两个数组
int partition(vector<int> &v, int low, int high)
{int pivot = v[high];int index = low;for (int i = low; i < high; i++){if (v[i] < pivot){swap(v[index++], v[i]);}}swap(v[index], v[high]);return index;
}void quickSort(vector<int> &v, int low, int high)
{if (low < high){int index = partition(v, low, high);quickSort(v, low, index - 1);quickSort(v, index + 1, high);}}int main()
{vector<int> v = {1, 19, 97, 9, 17, 8};// vector<int> v = {1, 20, 2, 3, 4, 5};quickSort(v, 0, v.size() - 1);for (auto i : v){cout << i << endl;}system("pause");return 0;
}
归并排序:⾸先将数组等分递归排序,然后通过⼀个临时数组,⽐较两个数组的⼤⼩从⽽合并两个数组
void mergeSort(std::vector<int> &nums, int l, int r)
{if (l < r){int mid = l + (r - l) / 2;mergeSort(nums, l, mid);mergeSort(nums, mid + 1, r);vector<int> tmp(r - l + 1);int i = l, j = mid + 1;int k = 0;while (i <= mid && j <= r){if (nums[i] < nums[j]){tmp[k++] = nums[i++];}else{tmp[k++] = nums[j++];}}while (i <= mid){tmp[k++] = nums[i++];}while (j <= r){tmp[k++] = nums[j++];}for (int p = 0; p < k; ++p){nums[l + p] = tmp[p];}}
}
堆排序:从最后⼀个⽗节点逆序构建最⼤堆(根节点/0下标值为最⼤),然后循环N-1次,不断将0下标与最后下标数交换,并调整堆(其中堆越来越⼩)

 

void heapify(vector<int> &nums, int f, int n)
{int left = f * 2 + 1;int right = left + 1;while (left < n){int index = f;if (nums[index] < nums[left])index = left;if (right < n && nums[index] < nums[right])index = right;if (index == f){break;}else{swap(nums[f], nums[index]);f = index;left = f * 2 + 1;right = left + 1;}}
}
void heapSort(std::vector<int> &nums, int n)
{if (n < 2)return;// 从最后⼀个⽗节点调整为最⼤堆for (int i = n / 2 - 1; i >= 0; --i){heapify(nums, i, n);}// 最⼤值放最后,将剩下调整为堆for (int i = n - 1; i > 0; --i){std::swap(nums[0], nums[i]);heapify(nums, 0, i);}
}
桶排序:将数据分到有限数量的桶⾥,然后每个桶分别排序(可能使⽤其他排序算法),最后每个桶内数据合并
计数排序:获取数组最⼤manV和最⼩值mixV,然后⽣成manV-mixV+1⼤⼩的数组,分别计数对应值的次数,然后再恢复数值输出结果
基数排序:针对正整数排序,对每⼀个数补⻬最⻓位数,然后从低位开始排序,排序的过程类似于多次桶排序
希尔排序:从 len/2 步⻓开始排序,每次步⻓取半,直到最后成为插⼊排序

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/11306.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024第二届智慧教育和人类发展国际会议(ICSEHD2024)

2024第二届智慧教育和人类发展国际会议(ICSEHD2024) 会议简介 智慧教育对于提升教育质量、促进教育公平、推动教育现代化和数字化转型、培养创新人才以及推动教育理论的发展都具有重要的意义&#xff0c;对人类发展产生着深远的影响&#xff0c;人类发展是智慧教育的最终目的…

易图讯科技数字武装三维电子沙盘

深圳易图讯科技(www.3dgis.top)集成了高清卫星影像、地形数据、实景三维模型、基干民兵、普通民兵、重要目标、兵要地志、企业潜力 、行业潜力 、社会组织潜力 、特种装备器材潜力、敌情数据、现场环境数据、物联感知信息&#xff0c;构建一体化的数字孪生空间&#xff0c;实现…

美港通正规股票炒股市场又一新能车火了!上市首日,大涨34%

查查配大家早上好!昨夜今晨,又有很多大事发生! 美三大股指涨跌不一,美债收益率集体收涨;OpenAI或推AI语音助手;来自中国的新能源车品牌——极氪在美股上市,首日大涨超34%。 美港通证券以其专业的服务和较低的管理费用在市场中受到不少关注。该平台提供了实盘交易、止盈止损、…

element ui输入框后面带输入的字符数量

使用el-input的属性&#xff1a; maxlength&#xff1a;最长字符限制&#xff1b; show-word-limit&#xff1a;显示输入字符数量&#xff1b; 例&#xff1a; <el-input v-model"title" placeholder"请输入名称" maxlength"200" show-wor…

woffice– 内部网和外部网WordPress高端资讯主题

下载地址&#xff1a;https://m.gx.cn/site/3046.html 完全灵活&#xff0c;与最新的WordPress品牌兼容 翻译语言超过15种 使用最新技术设计快速web应用程序 所有这些都以谷歌材料设计为灵感&#xff0c;采用易于定制的设计&#xff0c;给人一种优美的现代感和易于导航的用户…

ERROR 1045 (28000) Access denied for user ‘root‘@‘IP‘(using password YES/NO)

查看权限 要查看MySQL用户的权限&#xff0c;您可以使用SHOW GRANTS语句。这将列出用户的权限&#xff0c;包括授予的权限和可以授予其他用户的权限。 以下是查看当前用户权限的SQL命令&#xff1a; SHOW GRANTS; 如果您想查看特定用户的权限&#xff0c;可以使用以下命令&…

让 CloudFlare 支持 Brotli 压缩算法 11 级压缩比,更节流!

站长们应该都知道 Brotli 压缩算法吧&#xff0c;这是一种通用的无损压缩算法。它结合使用 LZ77 算法的一个现代变体&#xff08;Lempel-Ziv 编码&#xff09;、霍夫曼编码和二阶上下文建模来压缩数据&#xff0c;提供了与当前最佳通用压缩方法相媲美的压缩比。2015 年 9 月谷歌…

笔记-跨域方式实现原理

websocket Websocket是HTML5的一个持久化的协议&#xff0c;它实现了浏览器与服务器的全双工通信&#xff0c;同时也是跨域的一种解决方案。WebSocket和HTTP都是应用层协议&#xff0c;都基于 TCP 协议。但是 WebSocket 是一种双向通信协议&#xff0c;在建立连接之后&#xff…

51-50 两万字长文解读ControlNet论文和代码,以及自定义模型训练和图片精确控制生成实验

今天咱们来看 ICCV2023 最佳论文Adding Conditional Control to Text-to-Image Diffusion Models&#xff0c;又称为ControlNet。提到图像生成Finetuning工程方法&#xff0c;有Textual inversion、DreamBooth、LoRA、T2I-Adapter以及ControlNet&#xff0c;其中最著名的当属Co…

Jupyter配置

一、修改Jupyter打开界面 &#xff08;1&#xff09;打开【Anaconda Prompt】&#xff0c;输入【jupyter notebook --generate-config】命令 从运行结果可知【jupyter_notebook_config.py】的位置 &#xff08;2&#xff09;使用【记事本】打开 找到# c.NotebookApp.noteb…

同城预约上门服务家政小程序

基于Thinkphp和原生微信小程序开发的一款同城预约、上门服务、到店核销家政系统&#xff0c;用户端、服务端、门店端各端相互依赖又相互独立&#xff0c;支持选择项目、选择服务人员、选择门店多种下单方式&#xff0c;支持上门服务和到店核销两种服务方式&#xff0c;支持自营…

瞬息全宇宙——平行宇宙终极教程,手把手教你做出百万点赞视频

最近一种叫“瞬息全宇宙”的视频火了&#xff0c;抖音一期视频百万赞&#xff0c;各个博主视频都在带瞬息全宇宙这个标签&#xff0c;于是就有很多朋友催我出教程了&#xff0c;在琢磨了几天之后&#xff0c;终于整出来了 教程包含了插件的安装&#xff0c;界面的讲解&#xff…

C语言 | Leetcode C语言题解之第80题删除有序数组中的重复项II

题目&#xff1a; 题解&#xff1a; int removeDuplicates(int* nums, int numsSize) {if (numsSize < 2) {return numsSize;}int slow 2, fast 2;while (fast < numsSize) {if (nums[slow - 2] ! nums[fast]) {nums[slow] nums[fast];slow;}fast;}return slow; }

python微信小程序 django+uniapp民宿房屋租赁短租系统

本课题主要基于微信小程序的民宿短租系统的设计&#xff0c;实现了在微信小程序里的民宿房屋的管理系统&#xff0c;系统将房屋信息发布&#xff0c;房屋租赁等功能集于一身&#xff0c;为热爱旅游的用户提供了多种多样的房屋租赁业务&#xff0c;同时也方便了房屋的拥有者发布…

问题解决记录 | 内存溢出

报错截图&#xff1a; 处理方式&#xff1a; 增大PDI工具的内存 打开Spoon.bat配置文件 修改配置

第六节笔记及作业----Lagent AgentLego 智能体应用搭建

关于 Agent 的相关理论 大语言模型存在一些局限性&#xff0c;比如会出现幻觉问题、有时效性问题以及可靠性问题。智能体的定义是具备感知、决策和行动能力的实体。智能体主要由感知部分、大脑部分和动作部分组成。智能体有多种类型&#xff0c;如 ReAct 类型&#xff08;侧重…

落地领域大模型应知必会 (1) :主要微调方法总览

在如今高速发展的人工智能领域&#xff0c;高效地利用大语言模型&#xff08;LLMs&#xff09;已经变得越来越重要。但是&#xff0c;利用大语言模型的方式太多了&#xff0c;如果你才刚刚开始接触它&#xff0c;可能会感到不知所措。 实质上&#xff0c;我们可以通过两种主要…

Github 2024-05-09 Go开源项目日报 Top10

根据Github Trendings的统计,今日(2024-05-09统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Go项目10Gin Web框架:高性能的Go HTTP框架 创建周期:3496 天开发语言:Go协议类型:MIT LicenseStar数量:73548 个Fork数量:7831 次关注人数…

信创应用软件之国产邮箱

信创应用软件之国产邮箱 文章目录 信创应用软件之国产邮箱采用信创邮箱的必要性信创邮箱采购需求国产邮箱业务形态国产邮箱代表性品牌CoremailRichmail安宁eyouUMail拓波 邮件安全的发展阶段 采用信创邮箱的必要性 邮箱是天然的数据存储空间&#xff0c;党政和央国企客户在使用…

软件3班20240513

java.util.PropertyResourceBundle4554617c package com.yanyu;import java.sql.*; import java.util.ResourceBundle;public class JDBCTest01 {public static void main(String[] args) throws SQLException { // 获取属性配置文件ResourceBundle bundle Res…