<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[xy_learning的博客]]></title><description><![CDATA[]]></description><link>https://blog.csdn.net/xy_learning</link><language>zh-cn</language><generator>https://blog.csdn.net/</generator><copyright><![CDATA[Copyright &copy; xy_learning]]></copyright><item><title><![CDATA[Pytorch进阶训练技巧]]></title><link>https://blog.csdn.net/xy_learning/article/details/123579423</link><guid>https://blog.csdn.net/xy_learning/article/details/123579423</guid><author>xy_learning</author><pubDate>Fri, 18 Mar 2022 16:54:08 +0800</pubDate><description><![CDATA[当pytorch提供的内置损失函数无法实现需求时，可以通过自定义损失函数来实现目标。内置损失函数定义在torch.nn中，常用的有MSELoss(),L1Loss(),CrossEntropyLoss()等。自定义损失函数常通过类实现，像自定义神经网络一样，继承nn.Module()并且实现__init__()和forward()函数，在使用时，直接实例化类对象即可，这样实现的好处是全程用pytorch内置的数据结构进行处理，规范统一。

动态调整学习率的目的是让减少网络训练中震荡，是loss继续下降，模型]]></description><category></category></item><item><title><![CDATA[在C#方法中使用using的意义]]></title><link>https://blog.csdn.net/xy_learning/article/details/114176723</link><guid>https://blog.csdn.net/xy_learning/article/details/114176723</guid><author>xy_learning</author><pubDate>Sat, 27 Feb 2021 15:31:43 +0800</pubDate><description><![CDATA[在C#函数方法体中使用using，表明一个类只能在当前方法体中存在，出了方法体就会调用该函数的析构函数。

但是该类必须实现了IDisposable接口，并且除非该类的析构函数定义为虚函数且子类重写了，否则都只会调用该类的析构函数，并不会像C++释放全部内存，依然还是要CLR去管理。

与C++基类定义为虚函数了，子类析构则自动调用子类析构再父类析构不同，C++基类析构定义为虚函数则是后绑定，动态联编，会释放全部内存。

C#：


    class A : IDisposable
    {
     ]]></description><category></category></item><item><title><![CDATA[关于sizeof()空间计算和索引-1的记录]]></title><link>https://blog.csdn.net/xy_learning/article/details/108672323</link><guid>https://blog.csdn.net/xy_learning/article/details/108672323</guid><author>xy_learning</author><pubDate>Fri, 18 Sep 2020 20:27:00 +0800</pubDate><description><![CDATA[问题一：



结果为4,4,1；如果去掉虚函数func2()，则结果为1,1,1

说明两个问题，加了虚函数则有了虚函数表，则父类和子类都变为4个字节(一个指针大小)，如果为空类，则占用一个字节。

静态数据放在静态区，不参与sizeof的运算。

如果将静态换为非静态，无论是public还是private，结果都为8,8,1

问题二：

[-1]表示指针向前移动一位，如果未定义则是野指针，否则会正常输出值



结果返回ed

计算过程为 str指针移动4位到hi，再回退一位到ed
...]]></description><category></category></item><item><title><![CDATA[关于位运算的记录]]></title><link>https://blog.csdn.net/xy_learning/article/details/108670742</link><guid>https://blog.csdn.net/xy_learning/article/details/108670742</guid><author>xy_learning</author><pubDate>Fri, 18 Sep 2020 18:23:05 +0800</pubDate><description><![CDATA[正数的位运算就是转二进制后直接运算，包括与或非和左右移等。

负数的位运算，要先转二进制：最高位为1，然后剩余7位按正数处理，然后取反，得到反码，然后加1，得到补码。

利用补码进行二进制运算，如果得到结果最高位为0，则输出结果。

如果最高位为1，则逆向运算，先减一，再取反，得到负数值。

对于左移和右移的操作，不管该数为正或者负，都是增大或减小2^n倍（溢出位舍弃）
...]]></description><category></category></item><item><title><![CDATA[C++类型转换]]></title><link>https://blog.csdn.net/xy_learning/article/details/108166813</link><guid>https://blog.csdn.net/xy_learning/article/details/108166813</guid><author>xy_learning</author><pubDate>Sat, 22 Aug 2020 13:04:59 +0800</pubDate><description><![CDATA[静态转换：static_cast，最常用的转换，用于基础数据类型和子类父类之前的引用或者指针转换。

动态转换：dynamic_cast，最安全的转换，对于转换要求很严格，例如丢失精度等都不允许。

常量转化：const_cast，只能对指针或者引用进行操作，将数据在const和非const之间进行转换。


...]]></description><category></category></item><item><title><![CDATA[C++类模板的基本使用]]></title><link>https://blog.csdn.net/xy_learning/article/details/108163925</link><guid>https://blog.csdn.net/xy_learning/article/details/108163925</guid><author>xy_learning</author><pubDate>Sat, 22 Aug 2020 11:28:46 +0800</pubDate><description><![CDATA[类模板与函数模板最大的区别在于类模板不支持类型推导，需要显示指定参数类型：



当模板类作为参数传递时，有如下三种方式：



模板类的继承时，如果子类不是模板类，则需要显示指定基类类型（否则子类实例化时不知道基类的类型），如果子类也是模板类，那么可以设置模板参数来分别标识子类和基类的成员。



模板类不要做分文件编写，都写在一个文件中，最后将该文件改写为.hpp后缀，然后主文件就include该.hpp文件。原因是模板类的声明和实现分文件编写不能链接上
...]]></description><category></category></item><item><title><![CDATA[C++函数模板的基本使用]]></title><link>https://blog.csdn.net/xy_learning/article/details/108039203</link><guid>https://blog.csdn.net/xy_learning/article/details/108039203</guid><author>xy_learning</author><pubDate>Sun, 16 Aug 2020 18:01:11 +0800</pubDate><description><![CDATA[函数模板类似于C#泛型，使用时编译器优先寻找普通函数。


//类或者方法（表示模板类或者模板方法）
template&lt;class T&gt;
void InsertSort(T nums[],int len)
{
	for (int i = 1; i &lt; len; ++i)
	{
		int tmp = nums[i];
		int j;
		for (j = i - 1; j &gt;= 0; --j)
		{
			if (nums[j] &gt; tmp)
			{
				nums[j]]></description><category></category></item><item><title><![CDATA[C++向上向下类型转换的安全性问题]]></title><link>https://blog.csdn.net/xy_learning/article/details/108024526</link><guid>https://blog.csdn.net/xy_learning/article/details/108024526</guid><author>xy_learning</author><pubDate>Sun, 16 Aug 2020 17:17:19 +0800</pubDate><description><![CDATA[向上类型转换是指子类对象转为父类对象，向下类型转换是指父类对象转换为子类对象。（父辈在上）

如果没有发生多态（父类指针指向子类对象），那么向下转换是不安全的，向上转换是安全的。

Animal* anim = new Animal;基类转派生类

Cat* cat = (Cat*)anim;这样是不安全的，因为Cat所占大小比Animal更大，而申请空间只有Animal大小，指针转换后可能会导致越界。

如果发生多态，Animal* anim = new Cat; Cat* cat = (Cat*)ani]]></description><category></category></item><item><title><![CDATA[C++抽象基类和纯虚函数、虚析构和纯虚析构]]></title><link>https://blog.csdn.net/xy_learning/article/details/107750999</link><guid>https://blog.csdn.net/xy_learning/article/details/107750999</guid><author>xy_learning</author><pubDate>Sun, 02 Aug 2020 21:02:11 +0800</pubDate><description><![CDATA[C++中抽象基类的定义与C#中的abstract描述的类相似，只不过C++中没有abstract关键字，而是通过在类中声明一个纯虚函数，从而达到该类是抽象基类的目的。

所谓纯虚函数，就是只有声明而没有定义，所有继承该类的子类都必须重写该函数，在C++中的写法就是 virtual void func01() = 0；虚函数等于0表示是纯虚函数。
...]]></description><category></category></item><item><title><![CDATA[C++菱形继承、虚继承和虚基类]]></title><link>https://blog.csdn.net/xy_learning/article/details/107750668</link><guid>https://blog.csdn.net/xy_learning/article/details/107750668</guid><author>xy_learning</author><pubDate>Sun, 02 Aug 2020 20:43:48 +0800</pubDate><description><![CDATA[所谓菱形继承，就是一个父类有两个子类对象，然后又有一个类继承了这两个子类对象。

这样会导致该类中有两份数据，造成数据的浪费，一个解决办法就是使用虚继承。

让两个子类virtual继承父类，那么则会保留两个虚基类指针，在类继承这两个对象时，则会保留这个虚基类指针，同时数据也会只有一份，可以通过虚基类指针在虚基类表中找到数据的位置。
...]]></description><category></category></item><item><title><![CDATA[C++虚函数指针与虚函数表]]></title><link>https://blog.csdn.net/xy_learning/article/details/107701739</link><guid>https://blog.csdn.net/xy_learning/article/details/107701739</guid><author>xy_learning</author><pubDate>Thu, 30 Jul 2020 22:22:44 +0800</pubDate><description><![CDATA[当父类中某个方法有virtual关键字修饰，则该方法被放入虚函数表中，同时，有一个指针指向该父类的虚函数表。
	当子类继承父类后，子类会继承父类的虚函数指针和虚函数表，（在子类构造函数调用时）会将自己的虚函数指针指向自己的虚函数表，但是如果子类重写了该方法(加virtual或者不加都可以，但是方法必须完全相同包括返回值)，那么子类的虚函数表中的函数则会改变。
	父类指针指向子类对象时，发生动态联编，如果虚函数表被重写，则调用父类虚函数会指向被重写的方法，否则父类指针指向自身的方法，是静态联编。


当父类.]]></description><category></category></item><item><title><![CDATA[C++继承方式、继承中的对象模型、继承中的同名处理]]></title><link>https://blog.csdn.net/xy_learning/article/details/107646512</link><guid>https://blog.csdn.net/xy_learning/article/details/107646512</guid><author>xy_learning</author><pubDate>Tue, 28 Jul 2020 22:40:14 +0800</pubDate><description><![CDATA[继承方式共有继承、保护继承、私有继承
	继承中的对象模型，子类会继承基类全部内容，而且包括私有成员，但是编译器不会让我们看到。
	继承中的同名处理
	同名的属性 调用子类属性时会默认调用子类的，如果想访问父类的属性，则需要调用父类然后用作用域运算符得到父类属性。
		同名的方法 调用子类的方法时会默认隐藏父类的方法，如果想调用父类的方法，一样需要调用父类然后使用作用域运算符获取
		son.MyBase::show(10);
	
	继承中静态成员同名的处理 类似非静态的属性和方法，默认也是隐藏了父类的方法.]]></description><category></category></item><item><title><![CDATA[C++常函数、常对象、单例模式、友元、引用的本质、this指针的本质]]></title><link>https://blog.csdn.net/xy_learning/article/details/107599246</link><guid>https://blog.csdn.net/xy_learning/article/details/107599246</guid><author>xy_learning</author><pubDate>Sun, 26 Jul 2020 20:59:03 +0800</pubDate><description><![CDATA[用const修饰类的成员函数，那么该成员函数就不能修改类中的属性值，该函数又称常函数。原因是类的成员函数有隐式的this指针，this指针本质是指针常量，加了const变为常量指针常量，不允许修改指针所指向的内容。

用const修饰类的对象，那么该对象不允许修改其属性值，同时也只能调用该对象的常函数，该对象又称常对象。



C++中写单例模式需要将默认构造函数、默认拷贝构造函数设置为私有，并设置私有的静态指针

然后再设置共有的静态方法，用来获取其中私有的静态指针，然后再在类的外部实例化出静态指针。
.]]></description><category></category></item><item><title><![CDATA[指针常量和常量指针以及右值引用]]></title><link>https://blog.csdn.net/xy_learning/article/details/107585696</link><guid>https://blog.csdn.net/xy_learning/article/details/107585696</guid><author>xy_learning</author><pubDate>Sat, 25 Jul 2020 21:49:26 +0800</pubDate><description><![CDATA[]]></description><category></category></item><item><title><![CDATA[SP专场问题整理（一）]]></title><link>https://blog.csdn.net/xy_learning/article/details/107238915</link><guid>https://blog.csdn.net/xy_learning/article/details/107238915</guid><author>xy_learning</author><pubDate>Thu, 09 Jul 2020 22:07:31 +0800</pubDate><description><![CDATA[1.C#中协程的原理是什么？线程和协程的区别是什么？协程的底层实现原理是什么？如果同时运行多个协程需要注意什么？

进程是系统资源分配的最小单位，线程是任务调度的最小单位，可以理解协程是一种用户态的轻量级线程，它提供了由程序员来控制的何时开启并在何时暂停的机制。

协程拥有自己的寄存器上下文和栈，协程调度切换时，会将当前的寄存器上下文和栈保存在另一个地方，在切换回来的恢复之前的寄存器上下文和栈，由于是直接操作栈，所以性能高效。

线程的执行涉及到同步与锁的问题，然而协程本身不是多线程，它和update函数一]]></description><category></category></item><item><title><![CDATA[C++ 野指针、指针悬挂以及内存泄漏的概念]]></title><link>https://blog.csdn.net/xy_learning/article/details/107021977</link><guid>https://blog.csdn.net/xy_learning/article/details/107021977</guid><author>xy_learning</author><pubDate>Mon, 29 Jun 2020 15:56:31 +0800</pubDate><description><![CDATA[野指针：指针没有做初始化操作，从而不明确指针所指向的位置，成为野指针。

指针悬挂：指针所指向的内存空间已经被删除，从而该指针所指向的空间就不确定了，容易导致错误或者崩溃。

内存泄漏（Memory Leak）：是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放，造成系统内存的浪费，导致程序运行速度减慢甚至系统崩溃等严重后果。
...]]></description><category></category></item><item><title><![CDATA[C# 值类型和引用类型的性能比较]]></title><link>https://blog.csdn.net/xy_learning/article/details/107018084</link><guid>https://blog.csdn.net/xy_learning/article/details/107018084</guid><author>xy_learning</author><pubDate>Mon, 29 Jun 2020 14:59:05 +0800</pubDate><description><![CDATA[值类型都继承自System.ValueType，引用类型的继承链上没有System.ValueType，但是System.object是所有类的基类。C#的结构类型，比如int32等。

结构类型不能继承，但是可以实现接口。

为什么说结构不能继承，但是又继承于System.ValueType，而结构是值类型，其根基类是引用类型？这主要是因为微软对值类型进行了特殊的处理，CLR会自动给值类型分配栈上空间，引用类型分配堆内存。

在介绍值类型和引用类型的性能之前，我们需要先知道堆和栈空间：

对于一个32位操]]></description><category></category></item><item><title><![CDATA[C# 引用类型和值类型的堆栈分布]]></title><link>https://blog.csdn.net/xy_learning/article/details/107017977</link><guid>https://blog.csdn.net/xy_learning/article/details/107017977</guid><author>xy_learning</author><pubDate>Mon, 29 Jun 2020 12:38:00 +0800</pubDate><description><![CDATA[一、引用类型一定放在堆上吗？

面试官提到这个问题的时候，我第一反应当然说不是，然后我就说引用类型可能持有值类型的对象，而该对象存放在栈上……然后我开始觉得不妥……面试官接着问，那么在方法体结束后，栈上的临时空间释放了，那么该引用类型所持有的对象去哪里了呢……这时候意识到可能回答错误了，但是我就着这个问题回答，如果引用类型持有了某个值类型对象，那么会将其装箱在引用类型的堆内存中，当栈上空间释放后引用类型的值类型对象还是存在只不过其值为空……（那么该引用类型所持有的值对象不是一样在堆上了吗）

可能面试官就是]]></description><category></category></item><item><title><![CDATA[C#实现对象的深拷贝与浅拷贝（正确打开方式）]]></title><link>https://blog.csdn.net/xy_learning/article/details/107004807</link><guid>https://blog.csdn.net/xy_learning/article/details/107004807</guid><author>xy_learning</author><pubDate>Sun, 28 Jun 2020 17:59:00 +0800</pubDate><description><![CDATA[首先吐槽一下部分CSDNer，不要照抄，要有自己的思想，网上传的C#四种实现深拷贝的方法都属于比较偏的方法了，然而C#有内置的实现深拷贝和浅拷贝的方法，大家何必另辟蹊径，还全部都不加思索的就复制粘贴……

1.实现默认的拷贝构造函数（复制构造函数）

这一部分请看官方文档：

https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/how-to-write-a-copy-constructor
]]></description><category></category></item><item><title><![CDATA[记录3-C++拷贝构造函数的意义]]></title><link>https://blog.csdn.net/xy_learning/article/details/107003672</link><guid>https://blog.csdn.net/xy_learning/article/details/107003672</guid><author>xy_learning</author><pubDate>Sun, 28 Jun 2020 17:25:18 +0800</pubDate><description><![CDATA[拷贝构造函数的目的就是完成对一个对象的拷贝，一般在一下三种场景下会调用该对象的拷贝构造函数：

1.函数返回类型是类的对象时

2.函数的参数是类的对象，调用该函数时会调用该类的拷贝构造函数

3.使用一个对象去初始化类的另一个对象时 F a = new F(1,2); F b = a; / F b(a) 注意必须要在类的初始化中使用，不是类的赋值

拷贝构造函数的关键意义在与可以实现深拷贝，即实现申请新的内存空间并复制其值。默认拷贝构造函数实现的是浅拷贝，即完成对象的一一辅助但该对象还是指向堆中同一个对象]]></description><category></category></item></channel></rss>