All posts by runner2011

《我看见的世界》By 李飞飞 – 读后感

  • 有些东西看起简单,实则负责,比如人的视觉机制。
  • 比如ImageNet竞赛规则看似规则很简单,实则需要花几周详细设计
  • 现代AI(机器学习)的内核是:自我进化。
  • 曾经看到一句话,程序员最喜欢跑评分。这句话的背景是在2020年AI浪潮后说的。从ImageNet的故事不难看出,这在AI浪潮下的必然趋势。“黑猫白猫,抓到老鼠的就是好猫”,抓到老鼠就是评分。我们期望给予更多的自由,评分就是一种给予自由方式,不去限制过程。
  • 李飞飞实验室,辛顿实验室都在押注,都有可能赌错。
  • 一个无比困难的,大家不相信的问题,花了数年(还有站在巨人的肩膀,前人断断续续的几十年)有了重大突破(天时地利,多方协作),产生巨大的价值
  • 拥有目标,获取到任何发现,这趟旅程都是值得的

  • 几乎所有的成就都需要借助前人的成果,可能是几十年前前人的成果。
  • 也就是说,所有创新都有reference。 换句话说,去找(吸取)Reference,是创新的重要方法论。
  • 不能老是追寻学习别人的成果(意思也不大),还是要利用自己的背景做出贡献和价值

《我看见的世界》By 李飞飞 – Notes

注:Notes绝大部分为中译本原文,tag: [runner2011]下的notes是我的评论

[从数据中推断模式]
神经网络算法的目标不是用离散的规则来描述笔迹(1是直的,2是弯的,3是对称的,诸如此类),而是从数据中推断出模式。

[人工智能-从“通过明确编程来解决问题”转变“从示例中发现模式”]
此前的几代人试图用规则详尽描述智能,算法相对僵化,这种人工智能通常被称 “符号人工智能”(symbolic AI);20 世纪80年代未到90年代初,潮流开始转向更自然的方法。杨立昆的成果就预示着一个大胆的未来。随着时间的推移,行业研究重点从“通过明确编程来解决问题”转变“从示例中发现模式”。换言之,算法不是被告知该做什么,而是去学习该做什么。研究人员给它起了一个贴切的名字:“机器学习”(machine learning ).

[图灵]
机器学习的历史可以说是人工智能发展历史中不太为人所知的章节。尽管图灵本人很早就认可过机器学习,但这一概念相对来说仍然比较小众。1950年,图灵发表了一篇题为《计算机器与智能》的论文,简要对比了“基于规则的人工智能”(rule-based AI)和机器学习。基于规则的人工智能是指从零开始构建具有智能行力能力的完整体,而机器学习指的是允许智能体自主发展

[神经元-生物学原理数学化深远影响 ]
1943 年,研究人员沃伦·麦卡洛克(Warren S. McCulloch)和沃尔特·皮茨(Walter Pitts)共同发表文章,介绍了一项关于大脑基本单位“神经元”的新探索,把其中的生物学原理简化为数学的本质概念,从而推动了神经科学的重要进展。他们的方法的关键在于抽象化:通过剔除真实大脑中变幻莫测的电化学过程,将神经元简化为相对简单的信号交换。这种纯粹的交换性分析——输入什么、输出什么,以及两者之间如何相互关联——产生了深远的影响。不同于身体的其他部位,也不同于任何已知的自然结构,大脑似乎是唯一适合处理信息的器官。从某种意义上说,这个发现相当于神经科学领域的原子裂变,它揭示了在整个大脑中重复出现的根本模式, 展现出惊人的一致性和稳定性:大脑可以被看作由简单元素组成的大型网络,元素之间的联系可以随着时间的推移而改变;通过将复杂的行为分布于网络中,我们几乎可以完成无限的任务,并且可以不断学习新的任务,即使到了晚年也可以。

[大脑复杂但优雅,把复杂性都掩藏]
人类大脑的复杂性远远超越已知宇宙中的任何其他事物,但其构造又极其优雅,几乎把复杂性全部掩藏。汽车或手机都是由清晰区分的零件组装而成,这是人类设计师认为直观的形式。但大脑的构造与此不同,它是由近 1000 亿个神经元构成的巨大网络,其中神经元就是一个个互相连接的微小单元,可以在电化学传输中精细聚焦。尽管整个大脑中的神经元行为受到类似概念的支配(至少在麦卡洛克和皮茨的模型层面上是如此),但神经无可以形成不同的网络,其排列和位置各不相同,可以应对各类挑战,如视觉、听觉、运动,甚至进行抽系思考。此外,大脑在最初在子宫内形成后的很长时间里。才通过学习形成了(或者至少是逐渐完善了)这些网络结构。这就是为什么尽管我们的灰质在解剖学上看起来并无二致,但每个人的个性、技能和记忆都是独一无二的。

[模型的意义]
有了这样清晰的模型,技术进步迟早会赶上研究界的好奇心。

[感知机-学习的本质-归类或逆熵]
认为,有些输入对神经元行为的影响更大,这就好比不同的读者可能会对阅读的内容产生不同程度的信任和怀疑。如果允许这些影响随着时间的推移而变化,随着任务的成功或失败而增强或减弱,那么从本质上看,神经元网络本质上就可以进行学习了。

[专注-持续]
在学习方面,我还是一如既往地专注于数学和物理学—它们首先是我的激情所在,其次才是大学先修课程。过去三年,我一直夜以继日地学习、工作,现在刚刚克服了英语障碍。我感觉可以适当放慢脚步了–这也许是我有生以来第一次这么想.

[在道路行进中发现]
虽然干洗行业本身利润微薄,但改衣业务却是有利可图

[真切的置身其中的感觉]
我甚至养成了每周五参加高等研究院员工下午茶的习惯。虽然我跟高等研究院没什么关系,但这个下午茶活动并不是严格意义上的闭门研讨会。有时,我会遇到一些研究生,可以一起讨论学业。但我真正渴望的是一种真切的置身其中的感觉,

[智慧的描述-可以基于规则和原则-计算的哲学意义]
更重要的是,正是从这两本书中,我首次接触到了“用离散的数学术语来理解心智”这一观点。它们都提出了令人信服的理由:从本质上说,对智慧的全面描述揭示的不是魔法,而是一种过程,是规则和原则的运作。这些规则和原则在可测量的量上,以可理解甚至可预测的方式发挥作用。换句话说,它们为我揭示了计算所包含的哲学意义。

科学史往往是曲折、讽刺而又残酷的。新的思想被发现,然后被丢弃,接着又有新的思想被发现。被几代人视为基石的范式有时会在一夜之间被推翻,而推翻这一切的常常是显而易见的观察结果。恰恰因为这些观察太过简单,反而更容易被领域内最杰出的人物所忽视,从而为局外人发起革命创造了条件。正是这种既和谐又冲突的摇摆节奏,才使得科学追求如此戏剧化。

[runner2011- 进步可能无法一蹴而就]
进步可能无法一蹴而就, 如同感知机和杨立昆的成就虽然是正确的方向, 但由于缺乏计算条件(天时地利人和), 而被暂时的搁置. 因为往往无法一蹴而就, 做事可能无法考虑所有, 而是去产生价值. 专注自己的领域, 静待花开.

[量变引起质变]
尽管构成大脑大部分结构的神经元相对简单,但大脑也许是最能充分诠释“量变引起质变”这一公理的例子。当神经元以千亿计的数量级复制,当它们之间的连接达到10的11次方时,质变就发生了。物质变成了思维,产生了爱、喜悦、悲伤、愤怒、恐惧和欢笑,也造就了我们在科学、艺术、音乐和数学等方面的能力。

[淘汰-幸存-形成新的基线-淘汰来自秩序的改变]
生命进化是在一连串动荡中颠覆自然秩序,然后在新的基线上稳固下来,并很快在此基础上建立起更强大的能力

[随着物理条件的逐渐满足, 新的范式形成]
神经网络(*注:原文这里的神经网络上下文是生物学的神经网络)是一种生物电系统,原理简单,但功能强大。

[runner2011- 环境的变化, 对生物进化的巨大影响]
生物进化这一章, 展示了环境的变化, 对生物进化的巨大影响.

数字世界的机会也不胜枚举。

[runner2011]
脑科学的研究结果应该对神经网络架构设计提供了重要帮助。包括不限于:

– 神经元

– 视觉神经关联结构,特定的皮质区域对视觉神经的感知处理

– 学习影响神经元的连接(神经网络:学习过程中对神经元参数的调节)

– 注意力机制

[单样本学习]
我们选择的机器学习算法的数学核心是“贝叶斯网络”,这是一种概率技术。

数据被公然视为一种惰性商品,只有在算法需要时才重要,虽然这种观点并不稀奇,单我开始意识到,有一些重要的东西一直都被低估了。

我们算法的决定特征是能够从只看过一次的图像中学习新的事物类别,而这一特征对数据的依赖极大。

[背景:大约2005左右,重视算法,轻视数据]
生物智能与算法存在区别–前者是进化而来的,而进化的本质是环境对生物产生影响。

李凯教授是微处理器架构领域的领军人物。微处理器架构是一门将数百万纳米级晶体管排列到世界上最复杂的设备中的艺术,因此他比大多数人都更了解指数思维的力量

[保持谦卑-意外之力]
ImageNet 之所以能够存在,要归功于互联网、数码相机和搜索引擎等众多技术的融合。现在,一个一年前还几乎不存在的平台提供的众包服务,成为让我们的项目臻于圆满的关键因素。这件事就是最好的例证,它让我深刻了解到,任何一个科学家的默认立场都应该是绝对谦卑,他们应该明白,没有哪个个体的智慧能有意外之力一半强大。

亚马逊土耳其机器人拯救了ImageNet项目(成本和时间)

[图像数据集-计算机视觉的语言-概念的集合]
如果说可以把图像数据集视为计算机视觉的语言(也就是算法及其开发人员可以探索的概念集合),那么ImageNet就是词汇量的突然爆发性增长。(runner2011: 如果数据集是语言,那么算法应该就是思想,如何去组织语言)

[数据标准]
我一直在思考这次的获胜算法。它的识别准确率高达85%,比上一年的冠军高出10个百分点,创造了计算机视觉领域的世界纪录。

[卷积神经网络]
卷积神经网络的叫法源于图形卷积过程。在这个过程中,一系列滤波器在图上上扫过,寻找与网络所识别事物相应的特征。这是一种独特的有机设计,灵感来自休伯尔和威塞尔对哺乳动物视觉系统的观察,即视觉处理在多个层次上进行。

在经过,140万轮标注后,最后几张图片与其说是一场磨炼,不如说是一场加冕礼。网络的焦点穿过像素,随着熟悉模式的识别而亮起,并传递到下一层,与其他模式相结合,形成越来越强大的感知。

受生物学启发的算法几十年来一直凝视着我们,它只是需要适当的挑战,才能充分展现出来。

[生物视觉和机器视觉]
生物视觉的出现导致远古海洋波涛下的寒武纪大爆发,距今已经5亿年。而如今,我们很难不去联想:我们是不是正处于一个类似拐点的边缘?机器视觉的兴起是否会引发一轮数字进化新浪潮呢?

把视觉敏锐度和百科全书式的知识深度结合,可以带来一种全新的能力。这种新能力是什么尚不可知,但我相信,它绝不仅仅是机器版的人眼。它是一种全新的存在,是一种更深入、更精细的透镜,能够从我们从未想象过的角度揭示这个世界。

[目标-收获-值得]
我们能如愿以偿、得到回报吗?我们没有浪费时间去担心这个问题,而是选择拥抱世界,接受世界的真实面貌,不妥协、不简化——仅仅是这一点,就让我们觉得这是一项值得为之献身的使命。无论我们了解世界的窗口是汽车模型、鸟类物种,还是其他事物(也许我们的下一个项目将探索各种铺设道路、爬行动物的鳞片、小提琴的饰面),每一步都让人感觉距离用全新的眼光看待现实的时刻更近了一点。无论我们发现了什么,我都相信这趟旅程是值得的。

无论是否准备就绪,这些问题都需要以商业速度加以解决。灭个问题单独来看都令人担忧,但它们共同指向了一个未来,其特点都是监督减少,不平等加剧,如果处理不当,甚至可能导致迫在眉睫的数字独裁主义问题。

即使是现代人工智能,也更接近于牛顿出现前伽利略和第谷•布拉赫所处的时代,当时人们正在对各种现象进行观察、归纳和预测,但统一的模型尚未正式形成。

它们之所以强大,是因为成千上万个才华横溢的人在同一个屋檐下共同努力。但公司只能利用这些人才,而无法塑造他们。

‘尊严’,这是我一直强调的关键词。最重要的问题就是,人工智能如何才能尊重人的尊严呢?

以人为本的人工智能。

最好的研究往往不是在我们各自领域的象牙塔中孤立完成的,而是在科学的整体共享空间中实现的,研究人员应该毫不犹豫地在全球范围内展开跨学科合作。

我的研究成果还非常初级,我到底应该拿多少脑力去研究伦理问题呢?(注:来自一学生)

我的导师门教会了我如何善用威严:要将其作为一种感召,而不是障碍。

如果你真的对这些事物充满热情,无论你是谁,无论你来自哪里,你都属于这里。让我们共同创造未来!(runner2011:热情来自教育的培养)

我早已摆脱了对“格格不入”的恐惧,因为我一路上遇到了太多真诚的人,它们给了我太多善意。移民之路并不平坦,但我始终心存感激。

最好的作品总是在边界上诞生,在哪里,思想永远被困在来去之间

我对微积分的重新学习(1)

微分与积分可以解决一个经典问题,求曲线下面积。

eg. $f(x) = x^2$

首先需要知道怎么求斜率。

斜率就是描述y对于x的变化。

$slope=\frac{y_1-y}{x_1 – x}$

${x_1 – x}$趋近于无限小,这个值我们用$\Delta x$表示

如果y对于x的变化率用函数 f(x)表示,

那么 $slope = \frac{f(x1) – f(x) } {\Delta x}$

因为$x_1$ 也等于 $x + \Delta x$

所以 $slope = \frac{f(x + \Delta x) -f(x)}{\Delta x}$

这就是斜率公式,也就是导数公式。

那我们用经典曲线函数$x^2$举例,斜率怎么求呢?

代入公式:

$slope=\frac{(x + \Delta x)^2 – x^2}{\Delta x}$

多项式展开:

$slope=\frac{x^2 + 2x\Delta x + \Delta x^2 – x^2} {\Delta x}$

消元 $\Delta x$

$slope=2x + \Delta x$

当$\Delta x$趋近于0时,

$slope=2x$

这就求得了函数$x^2于x点的瞬时斜率$

好,有了斜率下次看看怎么通过积分求面积

C++多线程编程1

来看一个例子,

#include <iostream>
#include <thread>
int a = 0;
int b = 0;
void printMessage() {
for (int i = 0; i < 100; i++)
{
std::cout << "Hello from thread A! "<< a++ << std::endl;
}
}

void printMessage1() {
for (int i = 0; i < 100; i++)
{
std::cout << "Hello from thread B! "<< b++ << std::endl;
}
}

int main() {
// 创建一个线程,运行 printMessage 函数
std::thread myThread(printMessage);
std::thread myThread1(printMessage1);

// 等待线程完成
myThread.join();
myThread1.join();

std::cout << "Hello from main thread!" << std::endl;
return 0;
}

Execute 1st output:

Hello from thread A! Hello from thread B! 0
Hello from thread A! 1
Hello from thread A! 2
... ... //输出省略掉了
Hello from thread A! 98
Hello from thread A! 99
0
Hello from thread B! 1
Hello from thread B! 2
... ... //输出省略掉了
Hello from thread B! 98
Hello from thread B! 99
Hello from main thread!

Execute 2rd output:

Hello from thread A! Hello from thread B! 00
Hello from thread A! 1
Hello from thread A! 2
... ... //输出省略掉了
Hello from thread A! 98
Hello from thread A! 99
//这里有一个程序输出的空格
Hello from thread B! 1
Hello from thread B! 2
... ... //输出省略掉了
Hello from thread B! 98
Hello from thread B! 99
Hello from main thread!

可以看到两次输出不一致。实际上把循环加到1000,两个线程的交叉执行调用会更频繁。因为这里程序是并发(Concurrency)执行,即线程在一个核上以’时间切片’的方式交替执行[1]。

Hello from thread A! Hello from thread B! 0
Hello from thread B! 1
Hello from thread B! 1
... ... //输出省略掉了
Hello from thread B! 299
0
Hello from thread A! 1
Hello from thread A! 2
... ... //输出省略掉了
Hello from thread A! 154
Hello from thread A! 155Hello from thread B! 300
Hello from thread B! 301
... ... //输出省略掉了
Hello from thread B! 999
//这里有一个程序输出的空格
Hello from thread A! 156
Hello from thread A! 157
... ... //输出省略掉了
Hello from thread A! 999
Hello from main thread!

[1]参考C++ Concurrency in Action: Practical Multithreading第一章

2023个人最佳

硬件

Dell 键盘 KB216t

今年买了IQUNIX的机械键OG80尝试,觉得机械键盘键程太长。 发现这款便宜Dell的键盘用得更习惯。键程短,键帽不晃动。

软件

Trello

image from Atlassian

很好的事务管理软件,原本是项目管理用,发现做个人事务管理也很不错

电影

灌篮高手


今年电影院看的电影个人觉得有几部不错的,年会不能停,奥本海默,疯狂元素城,满江红。疯狂元素城故事较薄弱但是渲染技术我认为又有了进步。综合还是选灌篮高手,也许是情怀 ;p。

关于做决定的思考

今天早上看到一篇关于雷军年度演讲的新闻报道,https://mp.weixin.qq.com/s/mnC8q5bCCpJDlu2t9tjalA?poc_token=HF8Dm2ajrfktxxTPMqhWI5EBqg0lqoWtgqEu7y4f

其中提到

  • 2021 年他在《我的梦想 我的选择》演讲中鼓励道,「不要怕做选择,干了再说」;

我看到这里突然有些感悟。因为我以前挺不擅长做选择的,感觉自己有选择困难症。会为做一个选择拖上几个周。

现在工作多年经历了更多事件选择后,多了几分感悟。关于选择决定有了一些总结,思考和别人的分享有不谋而合之处。

「不要怕做选择,干了再说」

2021年左右小米应该是对外宣布造车左右的时间点,雷军这篇演讲应该是切合小米造车这个选择做的演讲。造车应该也是小米公司内部一个重大决定,雷军分享这个决定小米开了21天会。

我想开再多的会,做再多的调研,数据支撑。都是对做决定起一个辅助作用,而不是决定性作用。决定性作用的是人。有些决定必然有很多利弊,牵扯到各个因素,怎么去衡量它们,然后拍板呢?我想对大企业来说恐怕也很难,但还是要去做选择。

重要的决定做了调查后,有了数据支撑后,但是无法衡量到所有方面的,需要勇敢的走出那一步。至于后果,后果后面有办法去处理。选择一个选项去做,也比停留在选择面前拖延原地踏步好。因为一旦养成了选择拖延的习惯,容易生活中处处选择拖延,自己过的累不说,而且你的人生容量因为拖延减少了,成长得更少,别人快速做决定做了100件事,你处处选择拖延,做事效率降低,只做了60件事。别人100件事里选择错了20件,你60件里选择错了12件。那别人作对了80件,你作对了48件。1. 因为在做了分析后,做出的选择差别就没有那么大了 2. 错误的选择不代表就没有意义,错误的决定积累经验,困难的道路有时也可以磨练意志。

往往你经历得更多,做的事更多,你的经验更多,能力会更强。

我大学刚毕业那会,自己想去北京工作看一下,自己也坐飞机到北京找到了工作机会。可是回到成都后,却犯难了。父母说北京竞争大,我一个只身过去困难。我自己则考虑我目前新换的工作内容其实也还不错。我的领导说项目前景不错,希望我至少再多看一年再走不迟。多方的选择让我无所适从。刚毕业工作没多久的我,没有做过对我当时的我来说这么大这么难以选择的决定。因此我没有上班为了做这个决定花了2到3周来思考。

最后的结果是去了北京,工作了3年。去北京这段选择,收获了一些东西,当然可以看到也失去了一些东西,无从知晓留在成都会怎样,现在也如同当时一样也无法说哪个选择一定更好。所以两者都可以。

因为人生是一条由各种事件决定构成时间线,不应该因为某个选择原地踏步。所有的这些决定,都构成了你。

再说两个最近的选择:

我最近硬盘掉盘坏掉了,我找了一家淘宝店维修,可是店家收到货后不是开始说好的一口价,而是跟我打了几十分钟的电话,沟通我这个1T的固态盘怎么处理麻烦,重新沟通价格和处理方式。我从言语间感受到商家的一些不坦诚和前后矛盾的地方。我就说把盘退回来(商家标称评估后随时可退),商家又挽留且说筛选数据的方案。我又再淘宝上问了一家,这家坚定的说一口价,且店铺的销售额更好。

我其实有点犯难了,一是花了很多时间沟通,第一个商家也答应用选数据的方式给弄,并且预估成功率也有些保证。二是商家给我不坦率的感觉,还怕他因为我想退货花了他的时间,万一不厚道的做些手脚可能性。三是因为我没有数据恢复的经历,这方面的信息有限,没有太多可帮助选择的信息。让我很犹豫。

因为是否恢复需要给别人一个答复,我和我老婆简单沟通了一下。还是因为商家的不坦诚的印象,让我决定把硬盘退回来。后面结果是第二家拿到盘在最初的报价范围内,淘宝上聊了几句,没有找我电话沟通,很快的两三天就完整的恢复出了数据。

我当然不以结果论推导选择,但可以说的是,做出了决定走出去往往更好,各种结果都有方法去应对,我当时想最坏的后果是数据恢复不出来,对我有影响,但不是致命的影响。

第二个是更小的一个事, 因为这个坏硬盘还在保修期内,我要试试找京东看还能售后不。京东两个取件时间都可能会打乱我的周末时间计划(我们这更改取件时间比较麻烦),也让我没法按已有的信息立刻分辨出哪个时间对我的影响更小。这时我的经历告诉我这种小事,应该快速做决定,因为选择的影响有限。过后来看,选哪个时间其实差别都不大。

去战斗吧,趁还有精力的时候。不要把时间荒废在躺在沙发上,担心未来上,人生由脚步书写。干了再说,不论结果如何,后面有办法去处理。

最后,分享一个关于做决定的视频:How to make faster decisions | The Way We Work, a TED series

https://www.youtube.com/watch?v=cTIUiN6inIQ

P.S. 我还看到一种说法,重大的决定当然不容易。为了减缓这种不容易的决定,应该把做决定的影响因素尽量的分担到平时。让拆解出来这些小的选择和结果来帮助你大的决定,让大的决定成为一个自然的选择,不再困难。

P.S.S. 不要怕做选择不意味这对自己的决定可以不做思考,不负责任。成年人对自己的承担所有结果。而青少年有时不是所有结果都由自己承担,一部分也会由父母承担。青少年做某些决定应当征询父母的意见。

Compiling UnrealEngine Project by Command

I found sometimes I just want to tune a little code. Open full solution file of Visual studio is annoying. If you’re same, you can use below command to compile unreal project code:

UnrealBuildTool.exe YourProjectName Platform BuildConfig -project="[Path]\YourProjectName.uproject"

UnrealBuildTool in the \Engine\Binaries\DotNET folder in your Unreal Engine.

Platform is like Win64, IOS, or Android and so on.

BuildConfig is Development, Debug, or Shipping and so on.

For eg.

UnrealBuildTool.exe MyTestProject Win64 Development -project="C:\UE_Projs\MyTestProject\MyTestProject.uproject"

Need Notice, above cmd is for Standalone, If you want to compile for Editor, should replace the target with [YourProjectNameEditor]

UnrealBuildTool.exe MyTestProjectEditor Win64 Development -project="C:\UE_Projs\MyTestProject\MyTestProject.uproject"

2024年再玩Kindom Rush

五一放假在家,重新玩了一下移动游戏Kindom Rush,只不过是第二代”Frontiers“。第一代已经是很多年前玩的了,第二代今天才玩。玩了一会儿,我感觉离一代13年发布,这么多年过去了,Kindom Rush(系列)依然是移动(手机)游戏的第一梯队。

手机作为移动设备,主要特点是自带便携电源导致电源,另外性能受限。所以不太适合太硬核的游戏。Kindom Rush 2 : Frontiers 在一个硬核程度适中的选择下,不论是玩法,画面,音乐,游戏策略性都做的不错,尤其能耗体验做得非常好。而Kindom Rush之后,手机游戏(主要指中国国产游戏)大多往硬核游戏的方向发展,但这并不是手机游戏所擅长的。所以这可能是我觉得这么多年后,Kindom Rush依然是我以为的手机游戏第一梯队的一个重要原因。

C#内存管理

值类型,引用类型

string,class为引用类型,其他是值类型。值类型分配在栈上[1],引用类型分配在堆上。


堆栈

值类型分配在栈上,局部变量直接存储值。引用类型分配在托管堆,栈上存储一个地址在局部变量引用堆内存。

例如:

Person foo = new Person();

foo存储一个4字节地址,引用堆内存Person分配的空间。

int bar = new int(); 

因为bar是值类型,所以new分配在栈上[2],并且值类型bar直接存储的数据。

[1]《深入理解C#》中提到, 值类型一定分配在栈上并不准确。值类型是跟声明的对象一起放在一起存储的,作为引用类型class的成员的时候跟着class放在堆上。

[2]这点和C++语言不同,new是堆分配关键字,调用new即分配在堆上。


垃圾回收

堆上的内存没有引用会在垃圾回收的时候回收,垃圾回收会暂停其他线程,会压缩重排堆内存以减少碎片。

装箱拆箱

装箱会在堆上分配内存,把栈上的值拷贝的堆上。

拆箱会在栈上分配对象,把堆上的内存拷贝到栈上。栈上的类型和拆箱的类型不一致会报错。

2D坐标系中旋转一个点

2D坐标系中一个点x, y逆时针旋转角度θ后新坐标点x’, y’位置。要用到三角和公式:

cos(Ф+θ) = cosФcosθ – sinФsinθ

sin(Ф+θ) = sinФcosθ + cosФsinθ

查看源图像
Image from 2-D Transformations. Kurt Akeley CS248 Lecture 7 

由上图,运用三角和公式后,将r·cosФ代入为x, r·sinФ代入为y,就可以通过x, y坐标得出新的x’, y’坐标了:

x’ = xcosθ – ysinθ

y’ = xsinθ + ycosθ

顺时针旋转可以理解为逆时针一个负角度,根据sin(),cos()的奇偶性,即sin(-θ)=-sin(θ),cos(-θ)=cos(θ),可得顺时针旋转的变换公式:

x’ = xcosθ + ysinθ

y’ = ycosθ – xsinθ

另一个问题,三角和公式怎么推导出来。下图用几何法证明了三角和公式的推导:

Reference:

平面内直角坐标系中坐标旋转变换公式https://blog.csdn.net/sinat_33425327/article/details/78333946

两角和差的正余弦公式的若干证明方法https://zhuanlan.zhihu.com/p/361839484

https://www.slideserve.com/kirima/chapter-4-2-d-transformations-cartesian-coordinates