前端技术
HTML
CSS
Javascript
前端框架和UI库
VUE
ReactJS
AngularJS
JQuery
NodeJS
JSON
Element-UI
Bootstrap
Material UI
服务端和客户端
Java
Python
PHP
Golang
Scala
Kotlin
Groovy
Ruby
Lua
.net
c#
c++
后端WEB和工程框架
SpringBoot
SpringCloud
Struts2
MyBatis
Hibernate
Tornado
Beego
Go-Spring
Go Gin
Go Iris
Dubbo
HessianRPC
Maven
Gradle
数据库
MySQL
Oracle
Mongo
中间件与web容器
Redis
MemCache
Etcd
Cassandra
Kafka
RabbitMQ
RocketMQ
ActiveMQ
Nacos
Consul
Tomcat
Nginx
Netty
大数据技术
Hive
Impala
ClickHouse
DorisDB
Greenplum
PostgreSQL
HBase
Kylin
Hadoop
Apache Pig
ZooKeeper
SeaTunnel
Sqoop
Datax
Flink
Spark
Mahout
数据搜索与日志
ElasticSearch
Apache Lucene
Apache Solr
Kibana
Logstash
数据可视化与OLAP
Apache Atlas
Superset
Saiku
Tesseract
系统与容器
Linux
Shell
Docker
Kubernetes
[路径配置问题修复指南]的搜索结果
这里是文章列表。热门标签的颜色随机变换,标签颜色没有特殊含义。
点击某个标签可搜索标签相关的文章。
点击某个标签可搜索标签相关的文章。
Golang
..."内存不够用了"这种问题(就是那个ErrOutOfMemoryError)的时候,也难免会感到一阵头大,心里头那股挫败感蹭蹭往上涨。这事儿就像个不讲理的怪兽,你明明代码写得挺顺溜,却偏偏在这儿卡壳了,真是让人又急又恼。嘿,兄弟!这篇文章就是想带你一起深挖这个问题的奥秘,不光是告诉你怎么解决,还会给你分享一些超级实用的小秘诀和实战经验。就像老朋友在你耳边悄悄告诉你那些能让你事半功倍的小窍门,让你在面对挑战时更有底气! 二、深入浅出 理解Golang中的内存管理机制 在Golang中,内存管理是一个自动且复杂的系统。它通过垃圾回收(Garbage Collection, GC)机制来释放不再使用的内存,从而避免了传统的手动内存管理带来的种种问题。嘿,你知道吗?这个系统啊,虽然挺厉害的,但是也不是无敌的!特别是当我们用它来处理超多数据或者同时进行好多操作的时候,如果程序设计不当,就可能会遇到内存不够的问题。就像是你家的冰箱,容量有限,放太多东西就会爆满一样。所以,咱们在使用的时候可得小心点,别让程序“吃”掉所有内存! 三、案例分析 内存泄漏的陷阱 示例代码1: go package main import "fmt" func main() { var largeArray [1000000]int // 创建一个大数组 for i := 0; i < 1000000; i++ { largeArray[i] = i i // 每个元素都是i的平方 } fmt.Println("Memory usage:", memoryUsage()) // 打印内存使用情况 } // 计算当前进程的内存使用量 func memoryUsage() int64 { // 实际的内存计算函数,这里简化为返回固定值 return 1024 1024 10 // 单位为字节 } 这段代码看似简单,却隐藏着内存泄漏的陷阱。哎呀,你瞧这大数组largeArray在循环里头转悠,占了满满一屋子的空间呢!可别小看了这事儿,要是循环一结束,咱们不赶紧把用过的资源还回去,那这些宝贵的空间就白白浪费了,慢慢地,咱们手里的内存就像水龙头的水一样,越用越少,到最后可能连最基本的运行都成问题啦!所以啊,记得干完活儿就收工,别让资源闲置! 四、应对策略 识别并解决内存问题 策略1:合理使用内存池(Memory Pool) 内存池是一种预先分配并管理内存块的方法,可以减少频繁的内存分配和释放带来的性能损耗。在Golang中,可以通过sync.Pool来实现内存池的功能。 go package main import ( "sync" ) var pool = sync.Pool{ New: func() interface{} { return make([]int, 1000) }, } func main() { for i := 0; i < 1000; i++ { data := pool.Get().([]int) // 从内存池获取数据 defer pool.Put(data) // 使用完毕后归还到内存池 // 对数据进行操作... } } 策略2:优化数据结构和算法 在处理大量数据时,选择合适的数据结构和算法对于降低内存消耗至关重要。例如,使用链表而非数组,可以避免一次性分配大量内存。 策略3:使用Go的内置工具检查内存使用情况 利用pprof工具可以深入了解程序的内存使用情况,帮助定位内存泄漏点。 sh go tool pprof ./your_binary 五、实战演练 构建一个安全的并发处理程序 在并发场景下,内存管理变得更加复杂。错误的并发控制策略可能导致死锁或内存泄露。 示例代码2: go package main import ( "sync" "time" ) var wg sync.WaitGroup var mutex sync.Mutex func worker(id int) { defer wg.Done() time.Sleep(5 time.Second) mutex.Lock() defer mutex.Unlock() fmt.Printf("Worker %d finished\n", id) } func main() { for i := 0; i < 10; i++ { wg.Add(1) go worker(i) } wg.Wait() } 通过合理使用sync.WaitGroup和sync.Mutex,我们可以确保所有工作线程安全地执行,并最终正确地关闭所有资源。 六、结语 从错误中学习,不断进步 面对“内存不足错误”,关键在于理解其背后的原因,而不是简单的错误提示。通过实践、分析和优化,我们不仅能解决眼前的问题,还能提升代码质量和效率。记住,每一次挑战都是成长的机会,让我们带着对技术的好奇心和探索精神,不断前进吧! --- 本文旨在提供一个全面的视角,帮助开发者理解和解决Golang中的内存管理问题。嘿,无论你是编程界的菜鸟还是老司机,记得,内存管理这事儿,可得放在心上!就像开车得注意油表一样,编程时管理好内存,能让你的程序跑得又快又好,不卡顿,不崩盘。别怕,多练练手,多看看教程,慢慢你就成了那个内存管理的小能手。记住,学无止境,技术提升也是这样,一点一滴积累,你的编程技能肯定能上一个大台阶!
2024-08-14 16:30:03
115
青春印记
c++
...们经常遇到各种各样的问题,其中资源管理是至关重要的一个环节。哎呀,你猜怎么着?要是你对内存、文件啊,或者是网络连接这些玩意儿管得不好,那可就麻烦大了!搞不好程序就直接崩了,辛辛苦苦弄的数据全都没了,还有可能给坏蛋们留下可乘之机,让他们钻安全漏洞的空子。所以啊,咱们在这些事儿上可得细心点儿,别让它们成为你的大麻烦!哎呀,你瞧这C++,简直就是编程界的超级英雄嘛!它手里的工具可多啦,能让开发者们在写代码的时候,就像盖高楼大厦一样稳稳当当,既安全又可靠。想象一下,你用C++编程,就像是在用魔法,不仅能够创造出超酷的软件,还能让这些软件运行得比闪电还快,稳定性那就更不用说了,简直是无敌的存在!所以啊,如果你是个编程小能手,那C++绝对是你不可错过的神器!在这篇文章中,我们将探讨如何利用C++的特性,特别是资源管理机制,来构建异常安全的程序设计。 第一部分:资源管理的重要性 资源管理是程序设计中不可或缺的一部分,它关乎程序的稳定性和安全性。哎呀,你要是写代码的时候,不小心没把那些用到的资源,比如文件夹的小钥匙、数据库的密码本或者网线插头啥的,都给好好放回原位,那可是大麻烦啊!不光是浪费了电脑里的宝贵空间,程序要是遇到点啥意外,就像没关紧的水龙头,没法好好休息,容易出故障。更糟糕的是,这些乱糟糟的资源可能还会给坏人提供机会,让他们偷偷溜进你的系统里捣乱。所以,记得每次用完资源,都要好好收好,别让它们乱跑!因此,确保资源在不再需要时被正确地释放,对于构建健壮和可靠的软件至关重要。 第二部分:C++中的资源管理方法 C++提供了几种不同的方式来管理资源,包括智能指针、RAII(Resource Acquisition Is Initialization)原则以及手动管理资源的方法。在这篇文章中,我们将重点介绍智能指针,尤其是std::unique_ptr和std::shared_ptr,它们是现代C++中实现资源管理的强大工具。 代码示例 1: 使用 std::unique_ptr 管理资源 cpp include include class Resource { public: Resource() { std::cout << "Resource created." << std::endl; } ~Resource() { std::cout << "Resource destroyed." << std::endl; } }; int main() { std::unique_ptr resource = std::make_unique(); // 使用资源... return 0; } 在这个例子中,当 resource 对象离开作用域时(即函数执行完毕),Resource 的析构函数会被自动调用,确保资源被正确释放。这就是RAII原则的一个简单应用,它使得资源管理变得简洁且易于理解。 代码示例 2: 使用 std::shared_ptr 实现共享所有权 cpp include include class SharedResource { public: SharedResource() { std::cout << "SharedResource created." << std::endl; } ~SharedResource() { std::cout << "SharedResource destroyed." << std::endl; } }; int main() { std::shared_ptr shared_resource1 = std::make_shared(); std::shared_ptr shared_resource2 = shared_resource1; // 共享资源... return 0; } 这里展示了 std::shared_ptr 如何允许多个对象共享对同一资源的所有权。当最后一个持有 shared_resource1 的引用消失时,资源才会被释放。这种机制有助于避免内存泄漏,并确保资源在适当的时候被释放。 第三部分:异常安全的资源管理 在C++中,异常安全的资源管理尤为重要。当程序中包含可能抛出异常的操作时,确保资源在异常发生时也能得到妥善处理,是非常关键的。智能指针提供了一种自然的方式来实现这一点,因为它们会在异常发生时自动释放资源,而无需额外的保护措施。 代码示例 3: 异常安全的资源管理示例 cpp include include include class CriticalResource { public: CriticalResource() { std::cout << "CriticalResource created." << std::endl; } ~CriticalResource() { std::cout << "CriticalResource destroyed." << std::endl; } void criticalOperation() { throw std::runtime_error("An error occurred during critical operation."); } }; int main() { try { std::unique_ptr critical_resource = std::make_unique(); critical_resource->criticalOperation(); } catch (const std::exception& e) { std::cerr << "Exception caught: " << e.what() << std::endl; } return 0; } 在上述代码中,critical_operation 可能会抛出异常。哎呀,你知道的,critical_resource 这个家伙可是被 std::unique_ptr 给罩着呢!这可真是太好了,因为这样,如果程序里突然蹦出个异常来,critical_resource 就能自动被释放掉,不会出现啥乱七八糟、不靠谱的行为。这下子,咱们就不用操心资源没清理干净这种事儿啦! 第四部分:结论 通过使用C++的智能指针和RAII原则,我们可以轻松地实现异常安全的资源管理,这大大增强了程序的可靠性和稳定性。哎呀,兄弟,你要是想让你的代码跑得顺畅,资源管理这事儿可得好好抓牢!别小瞧了它,这玩意儿能防住好多坑,比如内存漏了或者资源没收好,那程序一不小心就卡死或者出bug,用户体验直接掉分。还有啊,万一程序遇到点啥意外,比如服务器突然断电啥的,资源管理做得好,程序就能像小猫一样,优雅地处理问题,然后自己蹦跶回来,用户一点都感觉不到。这样一来,不光用户体验上去了,系统的稳定性和质量也跟着水涨船高,你说值不值! 总之,资源管理是构建强大、安全和高效的C++程序的关键。嘿!兄弟,学了这些技术后,你就能像大厨炒菜一样,把程序做得既美味又营养。这样一来,修修补补的工作就少多了,就像不用天天洗碗一样爽快!而且,你的代码就像是一本好书,别人一看就懂,就像看《哈利·波特》一样过瘾。最后,用户得到的服务就像五星级餐厅的餐点,稳定又可靠,他们吃得开心,你也跟着美滋滋!
2024-10-05 16:01:00
48
春暖花开
转载文章
...果你有任何编程方面的问题,可以加我微信交流 2501902696(备注编程) by:年糕妈妈qcl 转载于:https://juejin.im/post/5ca30ad1e51d4514c01634f1 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_34150503/article/details/91475198。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-07-29 13:55:00
322
转载
转载文章
... 要上传的文件,包括路径 @throws FileNotFoundException @throws SftpException @throws Exception/public void upload(String directory, String uploadFile) throws FileNotFoundException, SftpException{File file = new File(uploadFile);upload(directory, file.getName(), new FileInputStream(file));}/ 将byte[]上传到sftp,作为文件。注意:从String生成byte[]是,要指定字符集。 @param directory 上传到sftp目录 @param sftpFileName 文件在sftp端的命名 @param byteArr 要上传的字节数组 @throws SftpException @throws Exception/public void upload(String directory, String sftpFileName, byte[] byteArr) throws SftpException{upload(directory, sftpFileName, new ByteArrayInputStream(byteArr));}/ 将字符串按照指定的字符编码上传到sftp @param directory 上传到sftp目录 @param sftpFileName 文件在sftp端的命名 @param dataStr 待上传的数据 @param charsetName sftp上的文件,按该字符编码保存 @throws UnsupportedEncodingException @throws SftpException @throws Exception/public void upload(String directory, String sftpFileName, String dataStr, String charsetName) throws UnsupportedEncodingException, SftpException{upload(directory, sftpFileName, new ByteArrayInputStream(dataStr.getBytes(charsetName)));}/ 下载文件 @param directory 下载目录 @param downloadFile 下载的文件 @param saveFile 存在本地的路径 @throws SftpException @throws Exception/public void download(String directory, String downloadFile, String saveFile) throws SftpException, FileNotFoundException{if (directory != null && !"".equals(directory)) {sftp.cd(directory);}File file = new File(saveFile);sftp.get(downloadFile, new FileOutputStream(file));log.info("file:{} is download successful" , downloadFile);}/ 下载文件 @param directory 下载目录 @param downloadFile 下载的文件名 @return 字节数组 @throws SftpException @throws Exception/public byte[] download(String directory, String downloadFile) throws SftpException, IOException {if (directory != null && !"".equals(directory)) {sftp.cd(directory);}InputStream is = sftp.get(downloadFile);byte[] fileData = IOUtils.toByteArray(is);log.info("file:{} is download successful" , downloadFile);return fileData;}/ 删除文件 @param directory 要删除文件所在目录 @param deleteFile 要删除的文件 @throws SftpException @throws Exception/public void delete(String directory, String deleteFile) throws SftpException{sftp.cd(directory);sftp.rm(deleteFile);}/ 列出目录下的文件 @param directory 要列出的目录 @return @throws SftpException/public Vector<?> listFiles(String directory) throws SftpException {return sftp.ls(directory);}/public static void main(String[] args) throws SftpException, Exception {SFTPUtils sftp = new SFTPUtils("xxxx", "xxx", "upload.haha.com", 8888);sftp.login();InputStream inputStream = getInputStream("http://qiniu.xinxuanhaoke.com/keqianduwu_1.jpg");sftp.upload("/www/website/ancai/audio", "123.jpg", inputStream);sftp.logout();}/} 方式二、使用HuTool的工具类 先引入jar <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.4.0</version></dependency><dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.53</version></dependency> public static void main(String[] args) {Sftp sftp = JschUtil.createSftp("ip或者域名", 端口, "账号", "密码");ChannelSftp client = sftp.getClient();String cd = "/www/website/ancai/audio";//要上传的路径try {sftp.cd(cd); //进入指定目录} catch (Exception e) {log.warn("directory is not exist");sftp.mkdir(cd); //创建目录sftp.cd(cd); //进入目录}InputStream inputStream = urlInputStream("http://audio.xinxuanhaoke.com/50bda079e9ef3673bbaeda20321bf932.mp3");//将文件转成流client.put(String.valueOf(inputStream), "1.mp3");//开始上传。} 本文引自:https://www.cnblogs.com/ceshi2016/p/7519762.html 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_37862824/article/details/113530683。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-04-04 09:43:38
71
转载
转载文章
...整个过程出现几个较大问题: 没有地方做题。宣讲时不知道确切人数,很多同学都是站着,之后做题找不到地方,有的同学直接就在膝盖上完成了。在武大更是严重,人数较多,临时找做题的会议室,导致很多同学延迟半小时才开始答题,非常影响学生的答题心情。 试卷不够。同样因为宣讲不知道确切人数,拍脑袋一个方向打印了几十份试卷,结果有的无人问津,如DSP方向;有的则没有试卷,如软件工程师;一些同学发挥才智,直接写答案在自带的空白稿纸上。这也非常影响学生的答题心情。 筛选时间不足。晚上要根据试题和简历筛选出面试人选,并通知到。只有3个小时时间,2百多简历,平均1份不到1分钟,连逐题评分都没有时间。筛选只能跑马观花,看看卷面、答题内容、学校等,个人觉得这种筛选方式非常草率,容易漏掉不善于书写、或发挥不好的其他学校学生。面试中,就有2位同学认为试题答得很好,要求面试。 已将向人事部反应,推荐参考其他公司的,先投简历,初步筛选后,再确定笔试人数,然后再筛选,面试。虽然会多花1天时间,但做题、筛选会更有效率和质量。回复本年度招聘流程就这样了,后续再改进。 2. 与企业职位要求符合度低 与进入面试的学生交谈,主要了解一下课题、自己做的内容,以及与公司职位相关的能力准备。交谈中,发现很多同学对符合职位的特点不能有效突出,从课题项目,转向企业工程化的要求也准备不足。以下是一些问题记录: 课题目的描述不清。一些同学对自己课题的背景、目的、意义描述不清楚,只知道是老师让做的,就去做了。其实硕士期间纯粹研究课题时间只有1年多(2年硕士更少),都要研究出实用东西不太可能,但至少要对自己做的事情有一个系统认识。成人学习过程,只有知道“为什么”,才能学得明白。 课题中自己负责的事情描述不具体。简历中描述的课题常规都很大,不大可能是一个人完成。那就有分模块,模块之间有接口、有通信协议什么的。自己做的这一块,起什么作用,上下游都是干啥的,等等。如果自圆其说都办不到,后续工作任务也会存在问题。 不能突出匹配企业职位的要求。以软件工程师为例,简历上写熟悉面向对象、精通C++,只能说出多态、继承几个名词,用过vector、string;学习C和C++除了谭老的书,就很少自己看其他的;想从事软件工程师,连“新手圣经”代码大全没有听说过。在面试的20多人中,没有一个人拿着笔记本来演示他写的程序,我们都是干说。 对比较适合的人,我都建议他们先看看代码大全、设计模式,不管是否来我们公司。其实,一个真正对某件事情感兴趣的同学,他会主动去找资源,深入理解,不会等到应聘的时候再抱佛脚,找借口。 3. 招聘是体力活 外出前就有些感冒,招聘过程中,拿带子断掉的易拉宝宣传盒子,提数斤重的简历试题,在酒店昏暗灯光中阅卷,坐在椅子中一天且不停地说话,做5小时高铁。。。最后感觉都是机械式的动作,实在是体力活,感冒在武汉有加重倾向,回到深圳后,在草窝中睡了一天,第2天就好了一半。 离开武汉5年多了,本次去武汉招聘,趁着晚上休息时刻,去拜访老师和室友。好久不去,武汉修了环城路,打车都找不到地方,只能到附近的金三利酒店,再重温上学的路。在老师家品尝了招牌的红烧武昌鱼,木耳鸡翅膀,见识老师几十年的工作成果奖励。去室友家,他家公子见到生人就不停的哭,呵呵。回到酒店想一想,时间不在了,记忆模糊了,唯有文字记录之。 节后,我们还要继续后续的校园招聘。(北京、哈尔滨校园招聘记录) 本篇文章为转载内容。原文链接:https://blog.csdn.net/zhouyulu/article/details/8033464。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2024-02-02 13:16:24
524
转载
转载文章
....6以上版本,安装与配置 2、下载mybatis-3.2.0版:https://repo1.maven.org/maven2/org/mybatis/mybatis/ 3、下载mybatis-spring-1.2.1版:https://repo1.maven.org/maven2/org/mybatis/mybatis-spring/ 4、Spring-4.0.0的版本 5、tomacat6.x以上版本即可 当然,这些jar还不够,还需要MySQL数据库与驱动,log4j的jar等等。下面我们开始今天的旅行: 第一步:创建数据库表 在Navicat下执行如下sql命令创建数据库mybatis和表t_user [sql] view plaincopy print? CREATE DATABASE IF NOT EXISTS mybatis; [sql] view plaincopy print? USE mybatis; [sql] view plaincopy print? create table t_user ( user_id int(11) NOT NULL AUTO_INCREMENT, user_name varchar(20) not null, user_age varchar(20) not null, PRIMARY KEY (user_id) )ENGINE=InnoDB DEFAULT CHARSET=utf8; 我们先看一下项目的完整目录,再继续下面的内容 第二步:添加jar包 对于下面代码的内容,我们就不再一一贴出来,只是把最重要的内容贴出来,大家可以下载源码。 第三步:创建model 创建一个model包并在其下创建一个User.Java文件。 [java] view plaincopy print? package com.tgb.model; / 用户 @author liang / public class User { private int id; private String age; private String userName; public User(){ super(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public User(int id, String age, String userName) { super(); this.id = id; this.age = age; this.userName = userName; } } 第四步:创建DAO接口 创建一个包mapper,并在其下创建一个UserMapper.java文件作为DAO接口。 [java] view plaincopy print? package com.tgb.mapper; import java.util.List; import com.tgb.model.User; public interface UserMapper { void save(User user); boolean update(User user); boolean delete(int id); User findById(int id); List<User> findAll(); } 第五步:实现DAO接口 在dao包下创建一个UserMapper.xml文件作为上一步创建的DAO接口的实现。 [html] view plaincopy print? <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace:必须与对应的接口全类名一致 id:必须与对应接口的某个对应的方法名一致 --> <mapper namespace="com.tgb.mapper.UserMapper"> <insert id="save" parameterType="User"> insert into t_user(user_name,user_age) values({userName},{age}) </insert> <update id="update" parameterType="User"> update t_user set user_name={userName},user_age={age} where user_id={id} </update> <delete id="delete" parameterType="int"> delete from t_user where user_id={id} </delete> <!-- mybsits_config中配置的alias类别名,也可直接配置resultType为类路劲 --> <select id="findById" parameterType="int" resultType="User"> select user_id id,user_name userName,user_age age from t_user where user_id={id} </select> <select id="findAll" resultType="User"> select user_id id,user_name userName,user_age age from t_user </select> </mapper> 这里对这个xml文件作几点说明: 1、namespace必须与对应的接口全类名一致。 2、id必须与对应接口的某个对应的方法名一致即必须要和UserMapper.java接口中的方法同名。 第六步:Mybatis和Spring的整合 对于Mybatis和Spring的整合是这篇博文的重点,需要配置的内容在下面有详细的解释。 [html] view plaincopy print? <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <!-- 1. 数据源 : DriverManagerDataSource --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis" /> <property name="username" value="root" /> <property name="password" value="123456" /> </bean> <!-- 2. mybatis的SqlSession的工厂: SqlSessionFactoryBean dataSource:引用数据源 MyBatis定义数据源,同意加载配置 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:config/mybatis-config.xml" /> </bean> <!-- 3. mybatis自动扫描加载Sql映射文件/接口 : MapperScannerConfigurer sqlSessionFactory basePackage:指定sql映射文件/接口所在的包(自动扫描) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.tgb.mapper"></property> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean> <!-- 4. 事务管理 : DataSourceTransactionManager dataSource:引用上面定义的数据源 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 5. 使用声明式事务 transaction-manager:引用上面定义的事务管理器 --> <tx:annotation-driven transaction-manager="txManager" /> </beans> 第七步:mybatis的配置文件 [html] view plaincopy print? <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 实体类,简称 -设置别名 --> <typeAliases> <typeAlias alias="User" type="com.tgb.model.User" /> </typeAliases> <!-- 实体接口映射资源 --> <!-- 说明:如果xxMapper.xml配置文件放在和xxMapper.java统一目录下,mappers也可以省略,因为org.mybatis.spring.mapper.MapperFactoryBean默认会去查找与xxMapper.java相同目录和名称的xxMapper.xml --> <mappers> <mapper resource="com/tgb/mapper/userMapper.xml" /> </mappers> </configuration> 总结 Mybatis和Spring的集成相对而言还是很简单的,祝你成功。 源码下载:SpringMVC+Spring4+Mybatis3 下篇博文我们将Hibernate和Mybatis进行一下详细的对比。 本篇文章为转载内容。原文链接:https://blog.csdn.net/konglongaa/article/details/51706991。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-09-05 11:56:25
111
转载
c++
...不是特有成就感?那么问题来了——如果我只用最基本的积木(也就是类、对象和函数),能不能盖出一座功能齐全的房子呢?换句话说,我们能不能只学这些基础知识就完成一个C++项目? 其实啊,这个问题挺常见的。很多人刚接触编程时,都觉得自己只要掌握最基本的东西就够了,甚至觉得“深入学习”是浪费时间。哎呀,先别急着下结论!今天咱们就好好聊聊这个事儿,顺便给大家瞅一眼代码,保证让你恍然大悟,弄清楚到底是咋回事儿! --- 2. 类与对象 搭积木的基本单元 2.1 什么是类? 类就像是积木里的“模板”。它定义了某种东西的样子以及它的行为。比如说,你想造一辆车嘛,那就好比先画个“车”的模板,跟程序说清楚这辆车长啥样(比如什么颜色、跑多快),还能干啥(踩油门加速、踩刹车减速)。 cpp class Car { public: // 属性 string color; int speed; // 方法 void accelerate() { speed += 10; cout << "Car accelerated to " << speed << " km/h." << endl; } void brake() { speed -= 5; cout << "Car braked to " << speed << " km/h." << endl; } }; 这段代码定义了一个Car类,它有两个属性(颜色和速度)和两个方法(加速和刹车)。是不是很简单?这就是类的基础用法。 2.2 对象:具体实例 接下来,我们需要把类变成具体的“东西”,这就需要用到对象了。对象就是根据类创建出来的具体实例。比如,我们可以用Car类创建一辆红色的小汽车: cpp int main() { Car myCar; // 创建一个Car对象 myCar.color = "Red"; myCar.speed = 0; myCar.accelerate(); // 调用加速方法 myCar.brake(); // 调用刹车方法 return 0; } 运行这段代码后,你会看到输出: Car accelerated to 10 km/h. Car braked to 5 km/h. 瞧,通过类和对象,我们已经能够模拟一辆车的行为了!不过,光靠这些还不够,对吧?所以我们还得聊聊函数。 --- 3. 函数 积木之间的桥梁 3.1 函数的作用 函数就像是积木之间的桥梁,它能让不同的部分连接起来。比如说,在刚才那个例子里,accelerate(加速)和brake(刹车)都是Car类里的招数。可要是我想让好几辆车一起干活儿,这事儿就有点麻烦了。这时候就需要请个帮手——函数出场啦! 假设我们要写一个函数,用来比较两辆汽车的速度: cpp bool isFaster(Car car1, Car car2) { return car1.speed > car2.speed; } int main() { Car carA, carB; carA.speed = 60; carB.speed = 40; if (isFaster(carA, carB)) { cout << "Car A is faster than Car B!" << endl; } else { cout << "Car B is faster than Car A!" << endl; } return 0; } 这里,isFaster函数接收两个Car对象作为参数,并返回它们速度的比较结果。这样,我们就把类的功能扩展到了更复杂的场景中。 3.2 深度思考:函数的重要性 虽然我们可以通过类和对象完成很多任务,但函数的作用不可忽视。它们不仅可以让代码更加模块化,还能提高复用性。想象一下,如果你每次都要重复写类似的功能,那岂不是累死人了?所以,学会合理使用函数是非常重要的。 --- 4. 小项目实践 做一个简单的银行系统 现在,让我们试着用类、对象和函数做一个小项目——银行系统。这个系统包括客户信息管理、存款和取款等功能。 4.1 客户类定义 首先,我们定义一个Customer类,包含客户的姓名、账户余额等信息: cpp class Customer { private: string name; double balance; public: Customer(string n, double b) : name(n), balance(b) {} void deposit(double amount) { balance += amount; cout << name << "'s account has been credited with $" << amount << "." << endl; } void withdraw(double amount) { if (balance >= amount) { balance -= amount; cout << name << "'s account has been debited with $" << amount << "." << endl; } else { cout << name << " does not have sufficient funds." << endl; } } void displayBalance() const { cout << name << "'s current balance: $" << balance << endl; } }; 4.2 主程序实现 接着,我们在主程序中创建几个客户并进行操作: cpp int main() { Customer john("John Doe", 1000); Customer jane("Jane Smith", 500); john.deposit(200); jane.withdraw(300); john.displayBalance(); jane.displayBalance(); return 0; } 运行结果如下: John Doe's account has been credited with $200. Jane Smith's account has been debited with $300. John Doe's current balance: $1200 Jane Smith's current balance: $200 看到没?通过类、对象和函数,我们已经成功实现了一个简单的银行系统! --- 5. 总结 深入与否取决于需求 好了,朋友们,到这里我们差不多可以下结论了。如果你的目标只是做一些小型项目或者练习题,那么只用类、对象和函数确实足够了。不过呢,要是你想捣鼓那种超大又复杂的玩意儿,像游戏引擎或者那些企业专用的软件,那可得好好琢磨琢磨C++的各种花招了,什么指针啊、模板啊、STL啥的,这些东西绝对躲不掉,学精了才好办事! 记住,编程是一门艺术,也是一门科学。它既需要逻辑思维,也需要创造力。所以,与其纠结于要不要深入学习,不如问问自己:“我的目标是什么?”如果答案是“做一个有趣的小项目”,那么你就大胆地去尝试吧! 最后,祝大家在编程之路上越走越远,早日成为编程高手!如果你有任何疑问,欢迎随时来找我讨论哦~ 😊 --- 希望这篇文章对你有所帮助!
2025-03-25 15:39:59
10
幽谷听泉_
转载文章
Groovy
...了不支持的语法”这种问题,简直让我抓狂。Groovy看着像Java的“精简版”,但其实它自有一套玩法。你要是直接把Java的那一套搬过来用,准得翻车!比如说吧,我之前就干过这么个事儿——觉得Java的class关键字挺简单粗暴的,就直接把它塞进了Groovy脚本里。结果呢,编译器它不讲武德啊,直接给我甩了个“语法错误”,啪一下,很快啊!搞得我当时一脸懵,心想:“诶?这不都差不多嘛,怎么就不行了呢?”我当时就懵圈了:“这不就是一回事儿嘛,咋就不成呢?”后来才搞明白,Groovy 根本不用特意写类名,直接写函数就行啦! 所以啊,想要玩转Groovy,首先得搞清楚它的“脾气”。好嘞,接下来咱们就举几个例子,看看这个Groovy到底有啥不一样的地方! --- 二、语法差异 为什么我的代码突然不工作了? 示例1:没有public修饰符 先来说个最基础的吧——Groovy对访问修饰符的态度真的很随意。在Java里,你要是定义了一个方法,不加public的话,默认是包级私有的(package-private)。但在Groovy里,你完全可以省略掉这些修饰符。比如: groovy // Java风格的写法 public void sayHello() { println "Hello, World!" } // Groovy风格的写法 void sayHello() { println "Hello, World!" } 看到没?Groovy直接去掉了public,而且连分号都不要了!刚开始我还觉得这太随便了吧,但后来发现,这样反而让代码更简洁明了。不过嘛,这也引出了一个小麻烦:有时候我们一忙乎起来,就把那些多余的装饰符啥的忘得一干二净,结果一运行脚本,就蹦出个提示说“你这语法我不认啊”! 比如下面这段代码: groovy public int addNumbers(int a, int b) { return a + b; } 如果你就这么直接跑起来,Groovy会很严肃地告诉你:“兄弟,这里不需要public。”所以,以后写Groovy的时候,记得把Java的习惯改掉哦! --- 示例2:闭包与匿名函数的区别 再来说说闭包和匿名函数的事儿。Groovy的闭包功能非常强大,但它和Java的匿名函数还是有区别的。比如,Groovy允许你在闭包中省略参数类型,甚至完全不写参数。这听起来是不是很酷?但实际操作起来,可能会让你一头雾水。 比如,以下这段Java风格的代码: java Runnable task = new Runnable() { @Override public void run() { System.out.println("Running..."); } }; 换成Groovy后,你可以这样写: groovy def task = { println "Running..." } 是不是简单多了?但问题是,有些人可能会觉得既然这么方便,那就啥都省略掉吧。于是就有了这样的代码: groovy def task = { -> println "Running..." } 乍一看好像没问题,但实际上Groovy会提醒你:“兄弟,这里的箭头可以省略。所以说啊,在用闭包的时候可得留点心,别小看那些语法小细节,不然就可能出现“你这代码写的啥玩意儿,语法不支持!”的情况,那多尴尬啊! --- 三、进阶问题 动态类型与静态类型之争 Groovy的一大特点是支持动态类型,这意味着你可以在运行时改变变量的类型。这一点确实很灵活,但也容易让人误以为所有类型都可以自由转换。实际上,Groovy在某些情况下还是会严格检查类型的。 比如,下面这段代码: groovy int number = 10 number = "twenty" 在Java里,这种类型转换是绝对不允许的,但在Groovy里,你可能会天真地认为它会自动帮你搞定。不过呢,现实情况是,Groovy直接炸了,还特么甩出个异常,说:“喂喂喂,你是不是有病啊?这类型根本不搭吧!”所以啊,哪怕Groovy自称是动态类型的“自由之翼”,该注意的类型转换规矩还是得守着,别不当回事儿。 --- 四、总结 拥抱变化,享受编程的乐趣 写到这里,我想跟大家聊聊我的感受。Groovy虽然看似简单,但它的每一个设计都有其背后的逻辑。一开始上手的时候,肯定会被各种“不支持的语法”绊住脚,别担心,这其实就是我们学习的必经之路啊!每一次踩坑,都是一次成长的机会。 最后,送给大家一句话:编程不是为了追求完美,而是为了找到最适合自己的方式。如果你愿意花点时间去了解Groovy的独特之处,你会发现它不仅是一个工具,更是一种思维方式。所以,别怕犯错,勇敢地去尝试吧!
2025-03-13 16:20:58
61
笑傲江湖
转载文章
...,有帮助别人快速解决问题(trouble shooting)的能力。 此阶段你需要经历到7、8年左右的体验,中间要经历一段深刻自我历练的过程。 有时给人致命一击其实是心里的小蟊贼。一般人在5年前后遇到一个门槛,碰到天花板+彷徨期,或者你打心眼里不在喜欢编程,可尝试转为其它角色,如产品经理,售前售后支持等岗位,也不失为好选择。 当我们熬过这段儿,就会“山随平野尽,江入大荒流“,渐入佳境矣。 高级程序员定义软件功能、做开发计划推进和管理。可以带几个个帮手把产品规划的功能实现,你是团队中的”大手“,遇到难题也是你亲自攻艰克难。 所以,一个高级程序员,他的职责很清晰: 1、负责产品核心复杂功能的方案设计、编码实现 2、负责疑难BUG分析诊断、攻关解决 架构师 到了架构师级别,想必你已经学会降龙十八掌,可登堂入世,成为一位准(lao)专(you)家(tiao)。 我们大喊声:“单打独斗,老衲谁也不惧!“,遂开始领导一众技术高手,指点武功,来设计和完成一个系统,大多是分布式,高并发的系统架构平台。 架构师的任务是为公司产品的业务问题提供高质量技术解决方案,主要着眼于系统的"技术实现" 。 架构师的主要分类: 可能每条产品线都设置了架构师,也可能多条生产品线的的后端是由一个架构师设计的平台提供,所以架构师也是有所不同的,其分类如下: 软件架构师 信息架构师 网站架构师 其主要职责如下: 1、需求分析:“知彼”有时比“知已”还重要。管理市场,产品等的需求,确立关键需求。坚持技术上的优秀与需求的愿景统一,提升技术负债意识,提供技术选项,风险预判,工期等解决方案。 2、架构设计:在产品功能中抽取中非功能的需求,由关键需求变成概念型架构。列出功能树,分层治之,如用户界面层、系统交互层,数据管理层。达成高扩展,高可用,高性能,高安全,易运维,易部署,易接入等能力。 3、功能设计与实现:对架构设计的底层代码级别实现。如公共核心类,接口实现,应用发现规则、接口变更等。 技术经理 人生就是不断上升的过程,你已经到达经理的层次了。如今的你,需要不断提高领导力,需要定期召开团队会议讨论问题。 首先我们要更加自信,在工作中显示自己的功力,给讲话增添力量。如:“本次项目虽然有很大的困难,我们也需苦战到底。当然示先垂范,身先士卒,方能成功!” 技术经理有时候也可能叫系统分析员,一些小公司可能会整个公司或者部门有一个技术经理。技术经理承担的角色主要是系统分析、架构搭建、系统构建、代 码走查等工作,如果说项目经理是总统,那么技术经理就是总理。当然不是所有公司都是这样的,有些公司项目经理是不管技术团队的,只做需求、进度和同客户沟 通,那么这个时候的项目经理就好像工厂里的跟单人员了,这种情况在外包公司比较多。对于技术经理来说,着重于技术方面,你需要知道某种功能用哪些技术合 适,需要知道某项功能需要多长的开发时间等。同时,技术经理也应该承担提高团队整体技术水平的工作。 你需要和大家站在一起,因为人们也都有解决问题的能力,更需要有以下的能力与责任: 1、任务管理:开发工作量评估、定立开发流程、分配和追踪开发任务 2、质量管理:代码review、开发风险判断/报告/协调解决 3、效率提升:代码底层研发和培训、最佳代码实践规范总结与推广、自动化生产工具、自动化部署工具 4、技术能力提升:招聘面试、试题主拟、新人指导、项目复盘与改进 技术总监 如果一个研发团队超过20人,有多条产品线或业务量很大,这时已经有多个技术经理在负责每个业务,这时需要一位技术总监。 主要职责: 1、组建平台研发部,与架构师共建软件公共平台,方便各条产品业务线研发。 2、通过技术平台、通过高一层的职权,管理和协调公司各个部门与本部门各条线。现在每个产品线都应该有合格的技术经理和高级程序员。 结语:我们相信,每个人都能成为IT大神。现在开始,找个师兄带你入门,让你的学习之路不再迷茫。 这里推荐我们的前端学习交流圈:784783012,里面都是学习前端的从最基础的HTML+CSS+JS【炫酷特效,游戏,插件封装,设计模式】到移动端HTML5的项目实战的学习资料都有整理,送给每一位前端小伙伴。 最新技术,与企业需求同步。好友都在里面学习交流,每天都会有大牛定时讲解前端技术! 点击:前端技术分享 本篇文章为转载内容。原文链接:https://blog.csdn.net/webDk/article/details/88917912。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2024-05-10 13:13:48
755
转载
转载文章
转载文章
...非回文字符串这一编程问题后,我们可以进一步了解字符串处理与算法优化的最新研究进展。近日,《自然》杂志子刊《自然-通讯》发表了一篇关于“在线字符串编辑与动态回文判定”的研究报告。研究者提出了一种新颖的在线算法,能够在字符串实时更新过程中高效地判断其是否为回文,并能快速找到使字符串变为非回文所需的最少编辑操作。这一成果不仅对于文本处理、数据压缩等领域具有重要价值,也对解决类似的编程挑战提供了新的思路。 此外,在ACM国际大学生程序设计竞赛(ACM-ICPC)和谷歌代码 Jam 等全球顶级编程赛事中,频繁出现与回文串相关的题目,参赛者需灵活运用算法知识来解决实际问题。比如,有题目要求选手在最短时间内编写程序,找出将一个字符串转换为非回文串的最小操作次数,这与我们讨论的文章主题不谋而合,展现了理论与实践相结合的重要性。 同时,回文串在密码学、遗传学以及文学创作等多个领域均有应用。例如,在DNA序列分析中,回文结构往往关联着基因调控的重要区域;在密码学中,特定类型的回文串可用于构建加密算法的关键部分。深入理解并熟练掌握回文串的相关性质及处理方法,无疑有助于我们在这些领域取得更多的技术突破。 总之,从基础的编程题出发,我们可以洞察到字符串处理与算法优化在前沿科研和实际应用中的深远影响。通过持续关注和学习此类问题的最新研究成果与应用案例,我们能够不断提升自身的算法设计和问题解决能力。
2023-10-05 13:54:12
228
转载
转载文章
...制了=。=如果还是有问题,欢迎在评论里进行讨论。 关于描述符 还记得之前我们所提到的一个定义么: Descriptors 是一种特殊的对象,这种对象实现了 __get__ , __set__ , __delete__ 这三个特殊方法 。然后在 Python 官方文档的说明中,为了体现描述符的重要性,有这样一段话:“They are the mechanism behind properties, methods, static methods, class methods, and super(). They are used throughout Python itself to implement the new style classes introduced in version 2.2. ” 简而言之就是 先有描述符后有天,秒天秒地秒空气 。恩,在新式类中,属性,方法调用,静态方法,类方法等都是基于描述符的特定使用。 OK,你可能想问,为什么描述符是这么重要呢?别急,我们接着看 使用描述符 首先请看下一段代码 classA(object):注:在 Python 3.x 版本中,对于 new class 的使用不需要显式的指定从 object 类进行继承,如果在 Python 2.X(x>2)的版本中则需要defa(self): pass if__name__=="__main__": a=A() a.a() 大家都注意到了我们存在着这样一个语句 a.a() ,好的,现在请大家思考下,我们在调用这个方法的时候发生了什么? OK?想出来了么?没有?好的我们继续 首先我们调用一个属性的时候,不管是成员还是方法,我们都会触发这样一个方法用于调用属性 __getattribute__() ,在我们的 __getattribute__() 方法中,如果我们尝试调用的属性实现了我们的描述符协议,那么会产生这样一个调用过程 type(a).__dict__['a'].__get__(b,type(b)) 。好的这里我们又要给出一个结论了:“在这样一个调用过程中,有这样一个优先级顺序,如果我们所尝试调用属性是一个 data descriptors ,那么不管这个属性是否存在我们的实例的 __dict__ 字典中,优先调用我们描述符里的 __get__ 方法,如果我们所尝试调用属性是一个 non data descriptors ,那么我们优先调用我们实例里的 __dict__ 里的存在的属性,如果不存在,则依照相应原则往上查找我们类,父类中的 __dict__ 中所包含的属性,一旦属性存在,则调用 __get__ 方法,如果不存在则调用 __getattr__() 方法”。理解起来有点抽象?没事,我们马上会讲,不过在这里,我们先要解释下 data descriptors 与 non data descriptors ,再来看一个例子。什么是 data descriptors 与 non data descriptors 呢?其实很简单,在描述符中同时实现了 __get__ 与 __set__ 协议的描述符是 data descriptors ,如果只实现了 __get__ 协议的则是 non data descriptors 。好了我们现在来看个例子:importmath classlazyproperty: def__init__(self, func): self.func = func def__get__(self, instance, owner): ifinstanceisNone: returnself else: value = self.func(instance) setattr(instance, self.func.__name__, value) returnvalue classCircle: def__init__(self, radius): self.radius = radius pass @lazyproperty defarea(self): print("Com") returnmath.pi self.radius 2 deftest(self): pass if__name__=='__main__': c=Circle(4) print(c.area) 好的,让我们仔细来看看这段代码,首先类描述符 @lazyproperty 的替换过程,前面已经说了,我们不在重复。接着,在我们第一次调用 c.area 的时候,我们首先查询实例 c 的 __dict__ 中是否存在着 area 描述符,然后发现在 c 中既不存在描述符,也不存在这样一个属性,接着我们向上查询 Circle 中的 __dict__ ,然后查找到名为 area 的属性,同时这是一个 non data descriptors ,由于我们的实例字典内并不存在 area 属性,那么我们便调用类字典中的 area 的 __get__ 方法,并在 __get__ 方法中通过调用 setattr 方法为实例字典注册属性 area 。紧接着,我们在后续调用 c.area 的时候,我们能在实例字典中找到 area 属性的存在,且类字典中的 area 是一个 non data descriptors ,于是我们不会触发代码里所实现的 __get__ 方法,而是直接从实例的字典中直接获取属性值。 描述符的使用 描述符的使用面很广,不过其主要的目的在于让我们的调用过程变得可控。因此我们在一些需要对我们调用过程实行精细控制的时候,使用描述符,比如我们之前提到的这个例子classlazyproperty: def__init__(self, func): self.func = func def__get__(self, instance, owner): ifinstanceisNone: returnself else: value = self.func(instance) setattr(instance, self.func.__name__, value) returnvalue def__set__(self, instance, value=0): pass importmath classCircle: def__init__(self, radius): self.radius = radius pass @lazyproperty defarea(self, value=0): print("Com") ifvalue ==0andself.radius ==0: raiseTypeError("Something went wring") returnmath.pi value 2ifvalue !=0elsemath.pi self.radius 2 deftest(self): pass 利用描述符的特性实现懒加载,再比如,我们可以控制属性赋值的值classProperty(object): "Emulate PyProperty_Type() in Objects/descrobject.c" def__init__(self, fget=None, fset=None, fdel=None, doc=None): self.fget = fget self.fset = fset self.fdel = fdel ifdocisNoneandfgetisnotNone: doc = fget.__doc__ self.__doc__ = doc def__get__(self, obj, objtype=None): ifobjisNone: returnself ifself.fgetisNone: raiseAttributeError("unreadable attribute") returnself.fget(obj) def__set__(self, obj, value=None): ifvalueisNone: raiseTypeError("You cant to set value as None") ifself.fsetisNone: raiseAttributeError("can't set attribute") self.fset(obj, value) def__delete__(self, obj): ifself.fdelisNone: raiseAttributeError("can't delete attribute") self.fdel(obj) defgetter(self, fget): returntype(self)(fget, self.fset, self.fdel, self.__doc__) defsetter(self, fset): returntype(self)(self.fget, fset, self.fdel, self.__doc__) defdeleter(self, fdel): returntype(self)(self.fget, self.fset, fdel, self.__doc__) classtest(): def__init__(self, value): self.value = value @Property defValue(self): returnself.value @Value.setter deftest(self, x): self.value = x 如上面的例子所描述的一样,我们可以判断所传入的值是否有效等等。 以上就是Python 描述符(Descriptor)入门,更多相关文章请关注PHP中文网(www.gxlcms.com)! 本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉 本文系统来源:php中文网 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_39736934/article/details/112888600。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-05-07 19:03:49
94
转载
转载文章
...nection的关闭问题,在最后比较完善的数据库访问函数中(这是SQLHelper中的源代码),没有使用using()结构,也没有显示关闭,主要原因是调用ExecuteReader方法时,使用了参数 CommandBehavior 并将其设置为 CloseConnection: SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection); 根据MSDN的说法:如果创建了 SqlDataReader 并将 CommandBehavior 设置为 CloseConnection,则关闭 SqlDataReader 会自动关闭此连接。 参考网址:http://msdn.microsoft.com/zh-cn/library/y6wy5a0f(v=vs.80).aspx 版权所有©2012,WestGarden.欢迎转载,转载请注明出处.更多文章请参阅博客http://www.cnblogs.com/WestGarden/ 转载于:https://www.cnblogs.com/WestGarden/archive/2012/06/04/2533560.html 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_33697898/article/details/94471782。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-03-18 20:09:36
89
转载
转载文章
...S跃点,可拦截对已知问题站点的DNS请求,并且不提供任何服务。 Installation is trivial if you just run unread and untrusted code from the 'net ;) 如果您只是从'net;)运行未读和不受信任的代码,则安装很简单。 curl -sSL https://install.pi-hole.net | bash Otherwise, follow their instructions and download the installer, study it, and run it. 否则,请遵循他们的指示并下载安装程序,对其进行研究并运行。 I put my pi-hole installation on the metal, but there's also a very nice Docker Pi-hole setup if you prefer that. You can even go further, if, like me, you have Synology NAS which can also run Docker, which can in turn run a Pi-hole. 我将pi-hole安装在金属上,但是如果您愿意的话,还有一个非常好的Docker Pi-hole设置。 如果像我一样,如果您拥有也可以运行Docker的Synology NAS ,那么它甚至可以运行Pi-hole,您甚至可以走得更远。 Within the admin interface you can tail the logs for the entire network, which is also amazing to see. You think you know what's talking to the internet from your house - you don't. Everything is logged and listed. After installing the Pi-hole roughly 18% of the DNS queries heading out of my house were blocked. At one point over 23% were blocked. Oy. 在管理界面中,您可以跟踪整个网络的日志,这也很令人惊讶。 您认为自己知道从家里到互联网的谈话内容,而您却不知道。 一切都记录并列出。 安装完Pi漏洞后,大约有18%的DNS查询从我家出来。 一度超过23%被阻止。 哦 NOTE: If you're using an Amplifi HD or any "clever" router, you'll want to change the setting "Bypass DNS cache" otherwise the Amplifi will still remain the DNS lookup of choice on your network. This setting will also confuse the Pi-hole and you'll end up with just one "client" of the Pi-hole - the router itself. 注意:如果您使用Amplifi HD或任何“智能”路由器,则需要更改设置“绕过DNS缓存”,否则Amplifi仍将是您网络上首选的DNS查找。 此设置还会混淆PiKong,您最终只会得到PiKong的一个“客户端”,即路由器本身。 For me it's less about advertising - especially on small blogs or news sites I want to support - it's about just obnoxious tracking cookies and JavaScript. I'm going to keep using Pi-hole for a few months and see how it goes. Do be aware that some things WILL break. Could be a kid's iPhone free-to-play game that won't work unless it can download an add, could be your company's VPN. You'll need to log into http://pi.hole/admin (make sure you save your password when you first install, and you can only change it at the SSH command line with "pihole -a -p") and sometimes disable it for a few minutes to test, then whitelist certain domains. I suspect after a few weeks I'll have it nicely dialed in. 对我来说,它与广告无关,尤其是在我要支持的小型博客或新闻网站上,它只是关于令人讨厌的跟踪cookie和JavaScript。 我将继续使用Pi-hole几个月,看看效果如何。 请注意,有些事情会中断。 可能是一个孩子的iPhone免费游戏,除非可以下载附件,否则它将无法正常工作,可能是您公司的VPN。 您需要登录http://pi.hole/admin (确保在首次安装时保存密码,并且只能在SSH命令行中使用“ pihole -a -p”更改密码),有时将其禁用几分钟以进行测试,然后将某些域列入白名单。 我怀疑几周后我会拨好电话。 翻译自: https://www.hanselman.com/blog/blocking-ads-before-they-enter-your-house-at-the-dns-level-with-pihole-and-a-cheap-raspberry-pi pi-hole 本篇文章为转载内容。原文链接:https://blog.csdn.net/cunfusq0176/article/details/109051003。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-08-12 20:49:59
61
转载
转载文章
...中,我们主要解决以下问题: 在读取过程中,另外一个线程删除了一个节点。删除线程可以把这个节点从链表中移除,但它不能直接销毁这个节点,必须等到所有的线程读取完成以后,才进行销毁操作。RCU中把这个过程称为宽限期(Grace period)。 在读取过程中,另外一个线程插入了一个新节点,而读线程读到了这个节点,那么需要保证读到的这个节点是完整的。这里涉及到了发布-订阅机制(Publish-Subscribe Mechanism)。 保证读取链表的完整性。新增或者删除一个节点,不至于导致遍历一个链表从中间断开。但是RCU并不保证一定能读到新增的节点或者不读到要被删除的节点。 宽限期 通过这个例子,方便理解这个内容。以下例子修改于Paul的文章。 struct foo {int a;char b;long c;};DEFINE_SPINLOCK(foo_mutex);struct foo gbl_foo;void foo_read (void){foo fp = gbl_foo;if ( fp != NULL )dosomething(fp-》a, fp-》b , fp-》c );}void foo_update( foo new_fp ){spin_lock(&foo_mutex);foo old_fp = gbl_foo;gbl_foo = new_fp;spin_unlock(&foo_mutex);kfee(old_fp);} 如上的程序,是针对于全局变量gbl_foo的操作。假设以下场景。有两个线程同时运行 foo_ read和foo_update的时候,当foo_ read执行完赋值操作后,线程发生切换;此时另一个线程开始执行foo_update并执行完成。当foo_ read运行的进程切换回来后,运行dosomething 的时候,fp已经被删除,这将对系统造成危害。为了防止此类事件的发生,RCU里增加了一个新的概念叫宽限期(Grace period)。 如下图所示: 图中每行代表一个线程,最下面的一行是删除线程,当它执行完删除操作后,线程进入了宽限期。宽限期的意义是,在一个删除动作发生后,它必须等待所有在宽限期开始前已经开始的读线程结束,才可以进行销毁操作。这样做的原因是这些线程有可能读到了要删除的元素。图中的宽限期必须等待1和2结束;而读线程5在宽限期开始前已经结束,不需要考虑;而3,4,6也不需要考虑,因为在宽限期结束后开始后的线程不可能读到已删除的元素。为此RCU机制提供了相应的API来实现这个功能。 void foo_read(void){rcu_read_lock();foo fp = gbl_foo;if ( fp != NULL )dosomething(fp-》a,fp-》b,fp-》c);rcu_read_unlock();}void foo_update( foo new_fp ){spin_lock(&foo_mutex);foo old_fp = gbl_foo;gbl_foo = new_fp;spin_unlock(&foo_mutex);synchronize_rcu();kfee(old_fp);} 其中foo_read中增加了rcu_read_lock和rcu_read_unlock,这两个函数用来标记一个RCU读过程的开始和结束。其实作用就是帮助检测宽限期是否结束。 foo_update增加了一个函数synchronize_rcu(),调用该函数意味着一个宽限期的开始,而直到宽限期结束,该函数才会返回。我们再对比着图看一看,线程1和2,在synchronize_rcu之前可能得到了旧的gbl_foo,也就是foo_update中的old_fp,如果不等它们运行结束,就调用kfee(old_fp),极有可能造成系统崩溃。而3,4,6在synchronize_rcu之后运行,此时它们已经不可能得到old_fp,此次的kfee将不对它们产生影响。 宽限期是RCU实现中最复杂的部分,原因是在提高读数据性能的同时,删除数据的性能也不能太差。 订阅——发布机制 当前使用的编译器大多会对代码做一定程度的优化,CPU也会对执行指令做一些优化调整,目的是提高代码的执行效率,但这样的优化,有时候会带来不期望的结果。如例: void foo_update( foo new_fp ){spin_lock(&foo_mutex);foo old_fp = gbl_foo;new_fp-》a = 1;new_fp-》b = ‘b’;new_fp-》c = 100;gbl_foo = new_fp;spin_unlock(&foo_mutex);synchronize_rcu();kfee(old_fp);} 这段代码中,我们期望的是6,7,8行的代码在第10行代码之前执行。但优化后的代码并不会对执行顺序做出保证。在这种情形下,一个读线程很可能读到 new_fp,但new_fp的成员赋值还没执行完成。单独线程执行dosomething(fp-》a, fp-》b , fp-》c ) 的 这个时候,就有不确定的参数传入到dosomething,极有可能造成不期望的结果,甚至程序崩溃。可以通过优化屏障来解决该问题,RCU机制对优化屏障做了包装,提供了专用的API来解决该问题。这时候,第十行不再是直接的指针赋值,而应该改为 : rcu_assign_pointer(gbl_foo,new_fp);rcu_assign_pointer的实现比较简单,如下:define rcu_assign_pointer(p, v) \__rcu_assign_pointer((p), (v), __rcu)define __rcu_assign_pointer(p, v, space) \do { \smp_wmb(); \(p) = (typeof(v) __force space )(v); \} while (0) 我们可以看到它的实现只是在赋值之前加了优化屏障 smp_wmb来确保代码的执行顺序。另外就是宏中用到的__rcu,只是作为编译过程的检测条件来使用的。 在DEC Alpha CPU机器上还有一种更强悍的优化,如下所示: void foo_read(void){rcu_read_lock();foo fp = gbl_foo;if ( fp != NULL )dosomething(fp-》a, fp-》b ,fp-》c);rcu_read_unlock();} 第六行的 fp-》a,fp-》b,fp-》c会在第3行还没执行的时候就预先判断运行,当他和foo_update同时运行的时候,可能导致传入dosomething的一部分属于旧的gbl_foo,而另外的属于新的。这样会导致运行结果的错误。为了避免该类问题,RCU还是提供了宏来解决该问题: define rcu_dereference(p) rcu_dereference_check(p, 0)define rcu_dereference_check(p, c) \__rcu_dereference_check((p), rcu_read_lock_held() || (c), __rcu)define __rcu_dereference_check(p, c, space) \({ \typeof(p) _________p1 = (typeof(p)__force )ACCESS_ONCE(p); \rcu_lockdep_assert(c, “suspicious rcu_dereference_check()” \usage”); \rcu_dereference_sparse(p, space); \smp_read_barrier_depends(); \(typeof(p) __force __kernel )(_________p1)); \})staTIc inline int rcu_read_lock_held(void){if (!debug_lockdep_rcu_enabled())return 1;if (rcu_is_cpu_idle())return 0;if (!rcu_lockdep_current_cpu_online())return 0;return lock_is_held(&rcu_lock_map);} 这段代码中加入了调试信息,去除调试信息,可以是以下的形式(其实这也是旧版本中的代码): define rcu_dereference(p) ({ \typeof(p) _________p1 = p; \smp_read_barrier_depends(); \(_________p1); \}) 在赋值后加入优化屏障smp_read_barrier_depends()。我们之前的第四行代码改为 foo fp = rcu_dereference(gbl_foo);,就可以防止上述问题。 数据读取的完整性 还是通过例子来说明这个问题: 如图我们在原list中加入一个节点new到A之前,所要做的第一步是将new的指针指向A节点,第二步才是将Head的指针指向new。这样做的目的是当插入操作完成第一步的时候,对于链表的读取并不产生影响,而执行完第二步的时候,读线程如果读到new节点,也可以继续遍历链表。如果把这个过程反过来,第一步head指向new,而这时一个线程读到new,由于new的指针指向的是Null,这样将导致读线程无法读取到A,B等后续节点。从以上过程中,可以看出RCU并不保证读线程读取到new节点。如果该节点对程序产生影响,那么就需要外部调用来做相应的调整。如在文件系统中,通过RCU定位后,如果查找不到相应节点,就会进行其它形式的查找,相关内容等分析到文件系统的时候再进行叙述。 我们再看一下删除一个节点的例子: 如图我们希望删除B,这时候要做的就是将A的指针指向C,保持B的指针,然后删除程序将进入宽限期检测。由于B的内容并没有变更,读到B的线程仍然可以继续读取B的后续节点。B不能立即销毁,它必须等待宽限期结束后,才能进行相应销毁操作。由于A的节点已经指向了C,当宽限期开始之后所有的后续读操作通过A找到的是C,而B已经隐藏了,后续的读线程都不会读到它。这样就确保宽限期过后,删除B并不对系统造成影响。 小结 RCU的原理并不复杂,应用也很简单。但代码的实现确并不是那么容易,难点都集中在了宽限期的检测上,后续分析源代码的时候,我们可以看到一些极富技巧的实现方式。 本篇文章为转载内容。原文链接:https://blog.csdn.net/m0_50662680/article/details/128449401。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-09-25 09:31:10
105
转载
转载文章
...时不太关注的非常细的问题。 keep 爱运动的小伙伴相信都熟悉keep这款软件,目前keep的用户量已经破3亿。工作地点在万科时代中心。 薪资待遇行业中等,不过该有的服务也基本都有,包括六险一金、年终奖、股权等。 招聘岗位以java为主,各种级别都有。 雪球 国内知名的投资交流平台,2020年底完成1.2亿美元 E 轮融资,发展潜力巨大。工作地点在融新科技中心。 福利待遇在行业内属于中等水平,包括六险一金、年终奖、餐补、零食下午茶等。 招聘岗位以java为主,还有搜索研发、全栈开发等。 陌陌 陌生人社交平台,深受年轻人喜爱,18年陌陌全资收购了探探,规模进一步扩大,目前月活用户在1亿+,出海业务也做的非常好。 福利待遇属于行业中等偏上,互联网有的福利基本都有,包括六险一金、年终奖等。 招聘岗位很多,包括java、中间件、推荐算法、自然语言处理、安全、游戏开发、IOS等。 面试难度中等,会有手写sql、算法、linux命令的环节。 松果出行 松果出行主要业务是构建国内县域城市交通出行网络,目前主要是共享电单车和共享新能源汽车服务。目前业务已经覆盖全国21个省,5000个县。 福利待遇属于行业中等,五险一金、年终奖等,没有补充医疗保险。 招聘岗位很多,以JAVA为主,各种级别都有。也有物联网、传感器硬件相关的岗位。 小桔科技 目前研发团队主要做推荐、搜索系统,注册地在大连。 福利待遇行业中等,五险一金、年终奖,没有补充医疗保险。 招聘岗位包括JAVA、PHP、搜索算法、前端、数仓等。 理想汽车 智能电动车品牌,这两年在行业内名气比较大。 福利待遇行业中等偏上,六险一金、交通补贴等。 招聘岗位很多,以JAVA为主,各种级别都有。另外也招聘PaaS平台研发、搜索、车载语音、大数据等。 参加过理想汽车面试的同学反馈面试体验不太好,面试官没有耐心,给大家一个参考。 狮桥 智慧物流+普惠金融融资租赁业务。 福利待遇中等偏下,五险一金、年终奖,没有补充医疗保险。 招聘岗位主要是JAVA开发。 领创集团 海外金融业务,主要做印度市场。 福利待遇中等偏下,六险一金,年终奖,工作节奏慢。 招聘岗位主要是JAVA,招聘岗位主要是java。 面试过的同学反馈体验比较好,面试官比较nice,有手写代码环节。 总结 今天主要推荐了望京的16家值得加入的互联网公司,事实上,望京区域的互联网公司和其他科技公司至少有几百家,由于个人精力有限,主要梳理了业界比较知名和自己熟悉的公司。相信还有好多非常不错的公司值得加入,欢迎大家跟我交流讨论。 欢迎关注个人公众号,一起学习进步 本篇文章为转载内容。原文链接:https://blog.csdn.net/zjj2006/article/details/121412370。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-01-11 22:59:19
529
转载
转载文章
...足、社会保障不完善等问题。政府相关部门正积极采取措施,加大职业技能培训力度,推进农民工市民化进程,并通过立法手段保障农民工权益,如推动实施“新市民”政策,以期实现农民工与城市的深度融合。 此外,针对新生代农民工的生活状况,《中国青年农民工社会融入研究报告》指出,尽管收入水平有所提高,但他们在住房、子女教育、医疗等方面依然面临较大压力,对此,各地政府也在探索实施租赁住房补贴、随迁子女平等接受义务教育、建立覆盖农民工的社会保险体系等一系列改革措施,力求解决新生代农民工在城市化进程中的痛点难点问题。 综上所述,新生代农民工已成为我国经济社会发展中不可或缺的力量,其市民化过程不仅关乎个人命运变迁,更影响着新型城镇化乃至整个国家的发展走向。社会各界应密切关注这一群体的需求变化,提供更加全面的支持和服务,共同助力新生代农民工顺利融入城市,共享社会发展成果。
2023-06-28 17:16:54
62
转载
Javascript
...输出啊!这告诉我们出问题了,是个“AbortError”,简单说就是有某个操作被强行中断啦。 --- 二、AbortError的实际应用场景 说到AbortError的应用场景,我觉得最典型的就是网络请求了。你有没有过这样的经历?比如你在网页上点了个下载按钮,想看个大图或者视频啥的。刚点完没多久,就觉得“这速度也太磨叽了吧!再等下去我都快睡着了”,然后一狠心就直接取消了操作。哎呀,这就像是服务器那边正拼了命地给你打包数据呢,结果你这边的浏览器直接甩出一句:“兄弟,不用忙活了,我不等了!””这就是AbortError发挥作用的地方。 让我们来看一段代码: javascript async function fetchData() { const controller = new AbortController(); const signal = controller.signal; try { const response = await fetch('https://example.com/large-file', { signal }); console.log('数据已成功获取'); } catch (error) { if (error.name === 'AbortError') { console.log('请求被用户取消'); } else { console.error('发生了其他错误:', error); } } // 取消请求 controller.abort(); } fetchData(); 在这段代码里,我们使用AbortController来管理一个网络请求。如果用户决定取消请求,我们就调用controller.abort(),这时fetch函数会抛出一个AbortError。嘿嘿,简单来说呢,就是咱们逮住这个错误,看看它是不是个“AbortError”,如果是的话,就用一种超优雅的方式把它处理了,不搞什么大惊小怪的。 --- 三、AbortError与其他错误的区别 说到错误,难免要和其他错误比较一番。比如说嘛,就有人会好奇地问:“AbortError跟一般的错误到底有啥不一样呀?”说实话呢,这个问题我也琢磨了好久好久,头都快想大了! 首先,AbortError是一种特殊的错误类型,专门用于表示操作被人为中断的情况。其实很多小错误啊,就是程序员自己不小心搞出来的,像打字打错了变量名,或者一激动让数组越界了之类的,都是挺常见的乌龙事件。简单来说呢,这俩的区别就是——AbortError就像是个“计划内”的小插曲,咱们事先知道它可能会发生,也能提前做好准备去应对;但普通的错误嘛,就好比是突然从天而降的小麻烦,压根儿没得防备,让人措手不及! 举个例子: javascript function divide(a, b) { if (b === 0) { throw new Error('除数不能为零'); } return a / b; } try { console.log(divide(10, 0)); // 抛出普通错误 } catch (error) { console.error(error.message); // 输出 "除数不能为零" } 在这个例子中,divide函数因为传入了非法参数(即分母为0)而抛出了一个普通错误。而如果我们换成AbortError呢? javascript const controller = new AbortController(); function process() { setTimeout(() => { console.log('处理完成'); }, 5000); } process(); controller.abort(); // 中断处理 这里虽然也有中断操作的意思,但并没有抛出任何错误。这就像是说,AbortError不会自己偷偷跑出来捣乱,得咱们主动去点那个abort()按钮才行。就好比你得自己动手去按开关,灯才不会自己亮起来一样。 --- 四、深入探讨AbortError的优缺点 说到优点嘛,我觉得AbortError最大的好处就是它让我们的代码更加健壮和可控。比如说啊,在面对一堆同时涌来的请求时, AbortError 就像一个神奇的开关,能帮我们把那些没用的请求一键关掉,这样就不会白白浪费资源啦!对了,它还能帮咱们更贴心地照顾用户体验呢!比如说,当用户等得花儿都快谢了,就给个机会让他们干脆放弃这事儿,省得干着急。 但是呢,凡事都有两面性。AbortError也有它的局限性。首先,它只适用于那些支持AbortSignal接口的操作,比如fetch、XMLHttpRequest之类。如果你尝试在一个不支持AbortSignal的操作上使用它,那就会直接报错。另外啊,要是随便乱用 AbortError 可不好,比如说老是取消请求的话,系统可能就会被折腾得够呛,负担越来越重,你说是不是? 说到这里,我想起了之前开发的一个项目,当时为了优化性能,我给每个API请求都加了AbortController,结果发现有时候会导致页面加载速度反而变慢了。后来经过反复调试,我才意识到,频繁地取消请求其实是得不偿失的。所以啊,大家在使用AbortError的时候一定要权衡利弊,不能盲目追求“安全”。 --- 五、总结与展望 总的来说,AbortError是一个非常实用且有趣的错误类型。它不仅能让我们更轻松地搞定那些乱七八糟的异步任务,还能让代码变得更好懂、更靠谱!不过,就像任何工具一样,它也需要我们在实践中不断摸索和完善。 未来,随着前端开发越来越复杂,我相信AbortError会有更多的应用场景。不管是应对一大堆同时进行的任务,还是让咱们跟软件互动的时候更顺畅、更开心,它都绝对是我们离不开的得力助手!所以,各位小伙伴,不妨多尝试用它来解决实际问题,说不定哪天你会发现一个全新的解决方案呢! 好了,今天的分享就到这里啦。希望能给大家打开一点思路,也期待大家在评论区畅所欲言,分享你的想法!最后,祝大家coding愉快,早日成为编程界的高手!
2025-03-27 16:22:54
106
月影清风
转载文章
...-server 修改配置文件 sudo vim /etc/redis/redis.conf 重启 sudo systemctl restart redis sudo systemctl enable redis-server 10. 安装Nginx sudo apt-get install -y nginx 修改配置文件 sudo vim /etc/nginx/nginx.conf 重启 sudo systemctl restart nginx sudo systemctl enable nginx 11. 安装VMWare Workstation 下载 https://www.vmware.com/go/getworkstation-linux 放到文件夹,进入,执行 sudo chmod +x VMware-Workstation-Full-17.0.0-20800274.x86_64.bundle sudo ./VMware-Workstation-Full-17.0.0-20800274.x86_64.bundle 安装gcc sudo apt-get install -y gcc 进入控制台,找到VMWare,开始安装,安装过程同Windows 如果如果遇到build environment error错误,执行下列命令后再重新在控制台打开图标 sudo apt-get install -y libcanberra 如果还不行,执行 sudo vmware-modconfig --console --install-all 看看还缺什么 12. 安装百度网盘 官网下载Linux版本的软件:百度网盘 客户端下载 deepin的软件包格式为deb。安装: sudo dpkg -i baidunetdisk_3.5.0_amd64.deb 最新版本 sudo dpkg -i baidunetdisk_4.17.7_amd64.deb 如果报错,执行 sudo apt-get -f install 13. 安装WPS 官网下载Linux版本的软件:WPS Office 2019 for Linux-支持多版本下载_WPS官方网站 deepin的软件包格式为deb。安装: sudo dpkg -i wps-office_11.1.0.10702_amd64.deb 最新版本 sudo dpkg -i wps-office_11.1.0.11691_amd64.deb 如果报错执行 sudo apt-get -f install wps有可能会报缺字体,缺的字体如下,双击安装 百度网盘 请输入提取码 提取码:lexo 14. 安装VS Code 官网下载Linux版本的软件:Visual Studio Code - Code Editing. Redefined deepin的软件包格式为deb。安装: sudo dpkg -i code_1.61.1-1634175470_amd64.deb 最新版本 sudo dpkg -i code_1.76.0-1677667493_amd64.deb 如果报错执行 sudo apt-get -f install 15. 安装微信、QQ、迅雷 微信 sudo apt-get install -y com.qq.weixin.deepin QQ sudo apt-get install -y com.qq.im.deepin 迅雷 sudo apt-get install -y com.xunlei.download 16. 安装视频播放器 sudo apt-get -y install smplayer sudo apt-get -y install vlc 17. 安装SSH工具electerm 下载electerm的deb版本 deepin的软件包格式为deb。安装: https://github.com/electerm/electerm/releases/download/v1.25.16/electerm-1.25.16-linux-amd64.deb sudo dpkg -i electerm-1.25.16-linux-amd64.deb 18.安装FTP/SFTP工具FileZilla sudo apt-get -y install filezilla 19. 安装edge浏览器 下载edge浏览器 deepin的软件包格式为deb。安装: 下载 Microsoft Edge sudo apt-get -y install fonts-liberation sudo apt-get -y install libu2f-udev sudo dpkg -i microsoft-edge-beta_95.0.1020.30-1_amd64.deb 最新版本 sudo dpkg -i microsoft-edge-stable_110.0.1587.63-1_amd64.deb 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_42173947/article/details/119973703。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-11-15 19:14:44
54
转载
转载文章
...些惊人的东西.唯一的问题是,你需要跟上这个领域的发展脚步,因此,你必须不断的学习,不断的前进.本文将分享能够帮助您快速掌 ... HTML5教程之本地存储SessionStorage SessionStorage: 将数据保存在session对象中,所谓session是指用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间会话,也就是用户浏览这个网站所花费的时间就是sess ... 随机推荐 【转】MySQL索引背后的数据结构及算法原理 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ... IIS7 / IIS7.5 URL 重写 HTTP 重定向到 HTTPS(转) 转自: http://www.cnblogs.com/yipu/p/3880518.html 1.购买SSL证书,参考:http://www.cnblogs.com/yipu/p/3722135. ... OpenGL的glViewPort窗口设置函数实现分屏 之前实现过全景图片查看(OpenGL的几何变换3之内观察全景图),那么我们需要进行分屏该如何实现呢?如下图: 没错就是以前提过的glViewPort函数,废话不多说了,我直接上代码: //从这里开始进 ... hdu 4764 Stone (巴什博弈,披着狼皮的羊,小样,以为换了身皮就不认识啦) 今天(2013/9/28)长春站,最后一场网络赛! 3~5分钟后有队伍率先发现伪装了的签到题(博弈) 思路: 与取石头的巴什博弈对比 题目要求第一个人取数字在[1,k]间的某数x,后手取x加[1,k] ... android报表图形引擎(AChartEngine)demo解析与源码 AchartEngine支持多种图表样式,本文介绍两种:线状表和柱状表. AchartEngine有两种启动的方式:一种是通过ChartFactory.getView()方式来直接获取到view ... CSS长度单位及区别 em ex px pt in 1. css相对长度单位 Ø em 元素的字体高度 Ø ex 字体x的高度 Ø px ... es6的箭头函数 1.使用语法 : 参数 => 函数语句; 分为以下几种形式 : (1) ()=>语句 ( )=> statement 这是一种简写方法省略了花括号和return 相当于 ()=&g ... pdfplumber库解析pdf格式 参考地址:https://github.com/jsvine/pdfplumber 简单的pdf转换文本: import pdfplumber with pdfplumber.open(path) a ... KMP替代算法——字符串Hash 很久以前写的... 今天来谈谈一种用来替代KMP算法的奇葩算法--字符串Hash 例题:给你两个字符串p和s,求出p在s中出现的次数.(字符串长度小于等于1000000) 字符串的Hash 根据字面意 ... SSM_CRUD新手练习(5)测试mapper 上一篇我们使用逆向工程生成了所需要的bean.dao和对应的mapper.xml文件,并且修改好了我们需要的数据库查询方法. 现在我们来测试一下DAO层,在test包下新建一个MapperTest.j ... 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_35666639/article/details/118169985。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-07-16 11:42:34
252
转载
转载文章
...OC中最常出现的内存问题就是循环引用,如下面代码所示,A中引用B,B中引用A,spa和spb的强引用计数永远大于等于1,所以直到程序退出前都不会被退出,这种情况有时候在正常的业务逻辑中是不可避免的,而解决循环引用的方法最有效就是改用weak_ptr,具体可见下一章。 class A {public:shared_ptr<B> b;};class B {public:shared_ptr<A> a;};int main(int argc, const char argv[]) {shared_ptr<A> spa = make_shared<A>();shared_ptr<B> spb = make_shared<B>();spa->b = spb;spb->a = spa;return 0;} //main函数退出后,spa和spb强引用计数依然为1,无法释放 刚柔并济:weak_ptr 正如上一章提到,使用shared_ptr过程中有可能会出现循环引用,关键原因是使用shared_ptr引用一个指针时会导致强引用计数+1,从此该指针的生命周期就会取决于该shared_ptr的生命周期,然而,有些情况我们一个类A里面只是想引用一下另外一个类B的对象,类B对象的创建不在类A,因此类A也无需管理类B对象的释放,这个时候weak_ptr就应运而生了,使用shared_ptr赋值给一个weak_ptr不会增加强引用计数(strong_count),取而代之的是增加一个弱引用计数(weak_count),而弱引用计数不会影响到指针的生命周期,这就解开了循环引用,上一章最后的代码使用weak_ptr可改造为如下代码。 class A {public:shared_ptr<B> b;};class B {public:weak_ptr<A> a;};int main(int argc, const char argv[]) {shared_ptr<A> spa = make_shared<A>();shared_ptr<B> spb = make_shared<B>();spa->b = spb; //spb强引用计数为2,弱引用计数为1spb->a = spa; //spa强引用计数为1,弱引用计数为2return 0;} //main函数退出后,spa先释放,spb再释放,循环解开了使用weak_ptr也有需要注意的点,因为既然weak_ptr不负责裸指针的生命周期,那么weak_ptr也无法直接操作裸指针,我们需要先转化为shared_ptr,这就和OC的Strong-Weak Dance有点像了,具体操作如下:shared_ptr<int> spa = make_shared<int>(10);weak_ptr<int> spb = spa; //weak_ptr无法直接使用裸指针创建if (!spb.expired()) { //weak_ptr最好判断是否过期,使用expired或use_count方法,前者更快spb.lock() += 10; //调用weak_ptr转化为shared_ptr后再操作裸指针}cout << spa << endl; //20 智能指针原理 看到这里,智能指针的用法基本介绍完了,后面笔者来粗浅地分析一下为什么智能指针可以有效帮我们管理裸指针的生命周期。 使用栈对象管理堆对象 在C++中,内存会分为三部分,堆、栈和静态存储区,静态存储区会存放全局变量和静态变量,在程序加载时就初始化,而堆是由程序员自行分配,自行释放的,例如我们使用裸指针分配的内存;而最后栈是系统帮我们分配的,所以也会帮我们自动回收。因此,智能指针就是利用这一性质,通过一个栈上的对象(shared_ptr或unique_ptr)来管理一个堆上的对象(裸指针),在shared_ptr或unique_ptr的析构函数中判断当前裸指针的引用计数情况来决定是否释放裸指针。 shared_ptr引用计数的原理 一开始笔者以为引用计数是放在shared_ptr这个模板类中,但是细想了一下,如果这样将shared_ptr赋值给另一个shared_ptr时,是怎么做到两个shared_ptr的引用计数同时加1呢,让等号两边的shared_ptr中的引用计数同时加1?不对,如果还有第二个shared_ptr再赋值给第三个shared_ptr那怎么办呢?或许通过下面的类图便清楚个中奥秘。 [ boost中shared_ptr与weak_ptr类图 ] 我们重点关注shared_ptr<T>的类图,它就是我们可以直接操作的类,这里面包含裸指针T,还有一个shared_count的对象,而shared_count对象还不是最终的引用计数,它只是包含了一个指向sp_counted_base的指针,这应该就是真正存放引用计数的地方,包括强应用计数和弱引用计数,而且shared_count中包含的是sp_counted_base的指针,不是对象,这也就意味着假如shared_ptr<T> a = b,那么a和b底层pi_指针指向的是同一个sp_counted_base对象,这就很容易做到多个shared_ptr的引用计数永远保持一致了。 多线程安全 本章所说的线程安全有两种情况: 多个线程操作多个不同的shared_ptr对象 C++11中声明了shared_ptr的计数操作具有原子性,不管是赋值导致计数增加还是释放导致计数减少,都是原子性的,这个可以参考sp_counted_base的源码,因此,基于这个特性,假如有多个shared_ptr共同管理一个裸指针,那么多个线程分别通过不同的shared_ptr进行操作是线程安全的。 多个线程操作同一个shared_ptr对象 同样的道理,既然C++11只负责sp_counted_base的原子性,那么shared_ptr本身就没有保证线程安全了,加入两个线程同时访问同一个shared_ptr对象,一个进行释放(reset),另一个读取裸指针的值,那么最后的结果就不确定了,很有可能发生野指针访问crash。 作者:腾讯技术工程 https://mp.weixin.qq.com/s?__biz=MjM5ODYwMjI2MA==&mid=2649743462&idx=1&sn=c9d94ddc25449c6a0052dc48392a33c2&utm_source=tuicool&utm_medium=referralmp.weixin.qq.com 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_31467557/article/details/113049179。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-02-24 18:25:46
141
转载
站内搜索
用于搜索本网站内部文章,支持栏目切换。
知识学习
实践的时候请根据实际情况谨慎操作。
随机学习一条linux命令:
jobs
- 查看后台运行的任务列表。
推荐内容
推荐本栏目内的其它文章,看看还有哪些文章让你感兴趣。
2023-04-28
2023-08-09
2023-06-18
2023-04-14
2023-02-18
2023-04-17
2024-01-11
2023-10-03
2023-09-09
2023-06-13
2023-08-07
2023-03-11
历史内容
快速导航到对应月份的历史文章列表。
随便看看
拉到页底了吧,随便看看还有哪些文章你可能感兴趣。
时光飞逝
"流光容易把人抛,红了樱桃,绿了芭蕉。"