String常用的方法(面试和工作会用到)

Java字符串操作大全
本文详细介绍Java中字符串的各种操作方法,包括长度获取、数组转换、内容判断、内容修改及位置查找等,是Java开发者必备的字符串处理指南。

一、和长度有关的方法:

       返回类型      方法名               作用
              int         length()            得到一个字符串的字符个数(一个中文是一个字符,一个英文是一个字符,一个转义字符是一个

二、和数组有关的方法:

返回类型        方法名                   作用
byte[]        getBytes()             将一个字符串转换成字节数组
char[]        toCharArray()       将一个字符串转换成字符数组(上次面试问的那个字符串翻转)
String[]      split(String)          将一个字符串按照指定内容劈开

三、和判断有关的方法:

返回类型        方法名                                            作用
boolean       equals(String)                             判断两个字符串的内容是否一模一样
boolean       equalsIgnoreCase(String)          忽略大小写的比较两个字符串的内容是否一模一样
boolean       contains(String)                          判断一个字符串里面是否包含指定的内容
boolean       startsWith(String)                       判断一个字符串是否以指定的内容开头
boolean       endsWith(String)                        判断一个字符串是否以指定的内容结尾


四、和改变内容有关的方法

    和改变内容有关的方法,都不会直接操作原本的字符串    而是将符合条件的字符串返回给我们,所以注意接收

返回类型        方法名                              作用
String        toUpperCase()                      将一个字符串全部转换成大写
String        toLowerCase()                      将一个字符串全部转换成小写
String        replace(String,String)           将某个内容全部替换成指定内容
String        replaceAll(String,String)       将某个内容全部替换成指定内容,支持正则
String        repalceFirst(String,String)    将第一次出现的某个内容替换成指定的内容
String        substring(int)                        从指定下标开始一直截取到字符串的最后
String        substring(int,int)                   从下标x截取到下标y-1对应的元素
String        trim()                                    去除一个字符串的前后空格

五、和位置有关的方法

返回类型        方法名                     作用
char          charAt(int)                      得到指定下标位置对应的字符
int           indexOf(String)                 得到指定内容第一次出现的下标
int           lastIndexOf(String)           得到指定内容最后一次出现的下标

<think>我们继续深入C++面试工作中的常见问题,重点放在实际开发中高频使用的知识点上,并给出详细解释代码示例。 ### 1. **RAII(Resource Acquisition Is Initialization)** **问题**:什么是RAII?它在C++中如何应用? **解答**: RAII是C++资源管理的核心思想:资源在构造函数中获取,在析构函数中释放。确保即使发生异常,资源也能被正确释放。 **应用场景**: - 内存管理(智能指针) - 文件句柄(`std::fstream`) - 互斥锁(`std::lock_guard`) ```cpp #include <fstream> #include <iostream> #include <stdexcept> class FileHandler { std::fstream file; public: FileHandler(const std::string& filename) : file(filename) { if (!file.is_open()) throw std::runtime_error("File open failed"); } ~FileHandler() { file.close(); } // 析构时自动关闭文件 void write(const std::string& data) { file << data; } }; int main() { try { FileHandler fh("test.txt"); fh.write("Hello RAII"); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; } // 文件在fh离开作用域时自动关闭 } ``` ### 2. **类型推导(auto decltype)** **问题**:`auto` `decltype` 的区别及使用场景? **解答**: - `auto`:根据初始化表达式推导类型,忽略引用顶层const - `decltype`:返回表达式的精确类型(包括引用const) ```cpp int x = 10; const int& rx = x; auto a1 = rx; // a1 类型为 int (忽略const引用) decltype(rx) d1 = x; // d1 类型为 const int& // 使用场景1:简化迭代器类型 std::vector<std::string> vs; for (auto it = vs.begin(); it != vs.end(); ++it) {} // 使用场景2:推导函数返回类型(C++14) template <typename T1, typename T2> auto add(T1 a, T2 b) -> decltype(a + b) { return a + b; } ``` ### 3. **Lambda 表达式** **问题**:Lambda表达式如何捕获外部变量? **解答**:捕获方式决定lambda如何访问外部作用域变量: - `[]`:不捕获 - `[=]`:值捕获(副本) - `[&]`:引用捕获 - `[this]`:捕获当前类成员 - `[a, &b]`:混合捕获(a值捕获,b引用捕获) ```cpp int main() { int x = 10, y = 20; auto lambda1 = [x, &y]() { // x 是只读副本(不可修改),y 可修改 y += x; return y; }; std::cout << lambda1(); // 输出 30 // mutable 允许修改值捕获的变量 auto lambda2 = [x]() mutable { x *= 2; // 修改副本 return x; }; std::cout << lambda2(); // 输出 20(不影响外部x) } ``` ### 4. **异常安全(Exception Safety)** **问题**:什么是强异常安全保证?如何实现? **解答**:强异常安全(事务安全)指操作要么完全成功,要么保持原始状态。实现方法: 1. 先分配新资源再替换旧资源(copy-and-swap) 2. 使用智能指针管理资源 ```cpp class SafeVector { std::vector<int> data; public: void insert(int value) { auto newData = data; // 1. 拷贝构造(可能抛异常) newData.push_back(value); // 2. 修改副本(可能抛异常) std::swap(data, newData); // 3. 无异常交换 } }; ``` ### 5. **完美转发(Perfect Forwarding)** **问题**:`std::forward` 的作用是什么? **解答**:保持参数原始值类别(左值/右值),用于泛型函数模板中转参数: - 结合万能引用(`T&&`)使用 - 避免转发时发生不必要的拷贝 ```cpp template <typename T> void wrapper(T&& arg) { // 使用 std::forward 保持 arg 的原始值类别 worker(std::forward<T>(arg)); } void worker(int& x) { std::cout << "lvalue\n"; } void worker(int&& x) { std::cout << "rvalue\n"; } int main() { int a = 10; wrapper(a); // 输出 "lvalue" wrapper(10); // 输出 "rvalue" } ``` ### 6. **并发编程(std::thread 与 std::async)** **问题**:如何选择 `std::thread` `std::async`? **解答**: - `std::thread`:直接控制线程(需手动管理生命周期) - `std::async`:自动管理线程,可返回`std::future`获取结果 ```cpp #include <future> #include <thread> // 使用 std::async 异步执行任务 auto future = std::async([]() { return 42; }); std::cout << future.get(); // 阻塞直到获取结果 // 使用 std::thread 创建线程 std::thread t([]() { std::cout << "Thread running\n"; }); t.join(); // 必须等待线程结束 ``` ### 7. **C++17 结构化绑定(Structured Binding)** **问题**:如何简化多返回值处理? **解答**:直接从元组、结构体或数组解包变量: ```cpp std::tuple<int, double, std::string> getData() { return {42, 3.14, "hello"}; } int main() { auto [id, value, name] = getData(); // 结构化绑定 std::cout << id << value << name; } ``` --- §§相关问题§§: 1. RAII 如何避免资源泄漏?请举例说明。 2. 在 lambda 表达式中,值捕获引用捕获的主要风险是什么? 3. 实现强异常安全保证的 copy-and-swap 技术的关键步骤是什么? 4. 完美转发中,为什么需要 `std::forward` 而不是直接使用 `std::move`?</think>### C++工作场景高频面试问题解析 #### 1. **智能指针的实际应用** **问题**:如何用 `shared_ptr` 管理第三方库资源? **解决方案**:使用自定义删除器 ```cpp #include <memory> #include <libxml/parser.h> // 假设是XML解析库 void xmlDeleter(xmlDocPtr doc) { if (doc) xmlFreeDoc(doc); // 第三方资源释放函数 } int main() { // 创建时指定自定义删除器 std::shared_ptr<xmlDoc> doc( xmlParseFile("config.xml"), xmlDeleter ); // 自动调用 xmlDeleter 释放资源 return 0; } ``` **关键点**: - 避免手动管理资源导致泄漏 - 确保异常安全 - 兼容C风格API #### 2. **移动语义优化性能** **问题**:如何用移动语义优化大对象传递? **解决方案**: ```cpp class DataPacket { std::vector<uint8_t> payload; public: // 移动构造函数 DataPacket(DataPacket&& other) noexcept : payload(std::move(other.payload)) {} // 移动赋值运算符 DataPacket& operator=(DataPacket&& other) noexcept { payload = std::move(other.payload); return *this; } // 工厂函数返回右值 static DataPacket create() { DataPacket packet; // 填充数据... return packet; // 触发NRVO或移动语义 } }; void process(DataPacket&& packet) { // 接收右值引用 // 处理数据... } int main() { process(DataPacket::create()); // 零拷贝传递 return 0; } ``` **性能收益**: - 避免大数据拷贝(时间复杂度从O(n)到O(1)) - 适用场景:网络数据包、图像处理、科学计算 #### 3. **constexpr 编译时计算** **问题**:如何用constexpr优化运行时性能? **解决方案**: ```cpp constexpr int factorial(int n) { return (n <= 1) ? 1 : (n * factorial(n - 1)); } class CryptoHelper { public: // 编译时生成加密表 static constexpr std::array<uint8_t, 256> generateSBox() { std::array<uint8_t, 256> sbox{}; for (int i = 0; i < 256; ++i) { sbox[i] = transform(i); // 变换函数 } return sbox; } // 编译期常量表 static constexpr auto SBOX = generateSBox(); }; int main() { // 编译时已计算完成 constexpr int fib20 = factorial(20); uint8_t val = CryptoHelper::SBOX[0xA3]; // 直接查表 } ``` **优势**: - 替代宏定义,类型安全 - 减少运行时开销 - 适用:加密算法、数学常数、配置参数 #### 4. **类型擦除的实际应用** **问题**:如何实现跨类型回调系统? **解决方案**: ```cpp class Callback { struct Concept { virtual ~Concept() = default; virtual void execute() = 0; }; template<typename T> struct Model : Concept { T callable; Model(T&& f) : callable(std::forward<T>(f)) {} void execute() override { callable(); } }; std::unique_ptr<Concept> impl; public: template<typename F> Callback(F&& f) : impl(new Model<F>(std::forward<F>(f))) {} void operator()() { impl->execute(); } }; int main() { // 存储不同类型回调 std::vector<Callback> callbacks; callbacks.emplace_back([] { std::cout << "Lambda 1\n"; }); struct Functor { void operator()() { std::cout << "Functor\n"; } }; callbacks.emplace_back(Functor{}); for (auto& cb : callbacks) cb(); // 统一调用 } ``` **应用场景**: - 事件处理系统 - 异步任务队列 - 插件架构 #### 5. **CRTP 静态多态** **问题**:如何避免虚函数开销实现多态? **解决方案**: ```cpp template <typename Derived> class Shape { public: void draw() const { static_cast<const Derived*>(this)->drawImpl(); } }; class Circle : public Shape<Circle> { public: void drawImpl() const { std::cout << "Drawing circle\n"; } }; class Square : public Shape<Square> { public: void drawImpl() const { std::cout << "Drawing square\n"; } }; template<typename T> void render(const Shape<T>& shape) { shape.draw(); // 静态分派 } int main() { render(Circle{}); // 无虚函数表开销 render(Square{}); } ``` **性能对比**: - 虚函数:运行时查表(约5-10周期) - CRTP:编译期绑定(0额外开销) - 适用:高性能图形渲染、游戏引擎 #### 6. **内存对齐优化** **问题**:如何优化SIMD数据结构? **解决方案**: ```cpp #include <immintrin.h> // AVX指令集 // 确保32字节对齐(AVX要求) struct alignas(32) Vector4D { __m256 x; // 8个float __m256 y; __m256 z; __m256 w; Vector4D operator+(const Vector4D& other) const { return { _mm256_add_ps(x, other.x), _mm256_add_ps(y, other.y), _mm256_add_ps(z, other.z), _mm256_add_ps(w, other.w) }; } }; int main() { // 对齐内存分配 auto* vectors = static_cast<Vector4D*>( _mm_malloc(100 * sizeof(Vector4D), 32) ); // SIMD操作(比标量快8倍) for (int i = 0; i < 99; ++i) { vectors[i] = vectors[i] + vectors[i+1]; } _mm_free(vectors); } ``` **关键点**: - `alignas` 控制对象对齐 - `_mm_malloc` 分配对齐内存 - 适用:科学计算、游戏物理引擎、AI推理 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值