作者: NF

  • 「编程笔记」Flutter中局部Provider的跨Page传递

    开发过Flutter项目的同学应该对于Provider不陌生,Provider是Flutter中的一个状态管理包之一,也是Flutter官方推荐的状态管理Flutter实现。Provider通过Flutter的InheritWidget实现了状态的寄存和管理,使得子Widget可以访问和修改父Widget的数据,同时父Widgets的数据被修改后,支持自动按需重构Widgets,这里不对Provider做过多介绍。

    一般情况下,我们创建的Provider会置于Flutter App的最根部,也就是MaterialApp或者CupertinoApp组件上,这种情况下,无需额外的操作,就可以在应用中的任何未知,通过Consumer<T>来访问和修改Provider<T>中的数据。

    但部分情况下,我们不想让Provider置于项目的最根部,详情可以查看这个StackOverFlow Question,比如一个局部的List,仅仅在项目的某一个子Widgets树部分会被访问,所以理论上,我们将Provider尽可能的放到Widgets树的更低位置是一个更优的选择。比如Page1中创建Provider,同时Page1以及其下的Page2和Page3可以访问到这个Provider,但是在Page1之上的Widgets无需也不能访问到这个Provider。理论上这是可行的,根据理论我们只需要保证Provider是Consumer的祖先即可。但这里出现了一个问题,也就是如果我们尝试在Provider生效的范围内使用Navigator.push()导航到另一个页面,我们便无法正常的在被push的页面访问到Provider。

    如上图,我们如果直接使用Navigator.push(),那么被Push的页面(途中是SecondPage)便无法访问到之前在FirstPage创建的数据。

    下面介绍一种解决办法,我们可以在Navigator.push的时候,在push的PageRoute外嵌套一层Provider.value(),如下图

    可以看下面的代码帮助理解:

    Navigator.of(context).push(DAPageRoute(
                          // push the create survey page
                          builder: (context) =>
                              ChangeNotifierProvider<DAOrgInfoProvider>.value(
                            value: orgProvider,
                            child: DACreateSurveyPage(
                              orgName: widget.orgInfo.name,
                            ),
                          ),
                        ));

    可以看出,我们通过在PageRoute外层加入一个ChangeNotifierProvider.value()实现了传递Provider的效果。

    注意,这里使用Provider.value()而不是Provider(),因为我们的Provider实际上不是“新建”,而是“传递”,这说明我们实际上不能新建一个DAOrgInfoProvider class的实例,而是复用之前的Provider创建时使用的实例,在这里则是orgProvider。

    那么如何获取之前Provider创建时的实例呢,一个比较傻但是直观的方法就是在Navigator外再次嵌套一个Consumer来获取数据,代码如下

    Consumer<DAOrgInfoProvider>(
                builder: (context, orgProvider, child) {
                  return DAIconButton(
                      onPressed: () {
                        Navigator.of(context).push(DAPageRoute(
                          // push the create survey page
                          builder: (context) =>
                              ChangeNotifierProvider<DAOrgInfoProvider>.value(
                            value: orgProvider,
                            child: DACreateSurveyPage(
                              orgName: widget.orgInfo.name,
                            ),
                          ),
                        ));
                      },
                      icon: const Icon(Icons.add_rounded));
                },
              )

    以上就介绍完了如何通过Navigator传值的方法

  • 「杂谈」关于ChatGPT的一些事

    ChatGPT 官网图片

    相信所有人对于ChatGPT这个词都已经不陌生了,ChatGPT是OpenAI公司推出的一个聊天机器人模型,根据维基百科,ChatGPT使用基于GPT-3.5架构的大型语言模型并通过强化学习进行训练,该模型问世之后,因为其相较于其他传统AI在聊天和回答问题领域方面的能力上产生了可以说是革命性的突破,而引起了各个业界的广泛关注。Bing(Microsoft旗下的搜索引擎服务)也在近日宣布了要在其搜索功能中整合类ChatGPT聊天机器人。为什么ChatGPT会如此强大,ChatGPT到底能做些什么,各个科技巨头大厂为何争相推出ChatGPT服务?它有会对我们的生活和各个行业带来什么影响?本篇文章将会针对这些问题进行讨论。

    本文阅读时间大约15分钟左右。本文部分链接取自维基百科,使用国内网络环境可能无法正常访问。本文为NFのBlog原创文章,转载请注明来源。

    ChatGPT的进化史

    Transformer

    ChatGPT是如何完成这一切的?要解决这个问题,首先需要提到一个模型——Transformer——它就是如今我们看到的如此强大的LLM(大语言模型Large Language Model)的基石。Transformer自身是一个NLP(Natural Language Processing,自然语言处理)和CV(Computer Vision,计算机视觉)领域的机器学习模型。GPT系列的模型同样也基于Transformer模型。

    Transformer于2017年GoogleBarins上问世,这个模型拥有的“自我注意(Self-attention)”机制,维基百科上对于注意力机制给出了如下描述:

    注意力机制(英语:attention)是人工神经网络中一种模仿认知注意力的技术。这种机制可以增强神经网络输入数据中某些部分的权重,同时减弱其他部分的权重,以此将网络的关注点聚焦于数据中最重要的一小部分。

    这个机制为模型提供了理解“上下文”的能力,Transformer模型不再局限于一次一问一答的对话或者短期的两三句对话,而可以定位和使用任意位置的上下文,比如你一开始提的要求,可以在十几轮对话之后要求AI重新使用或者废弃,AI具有了理解上下文并以此做出反应的能力。

    同时,Transformer模型没有了之前同类模型“一次同时只能处理一个单词”的限制,这提高了Transformer模型的并行处理和训练能力,提高了该模型的训练效率。这对于AI来说是非常重要的,更快的处理效率,意味着在相同的算力资源下,你可以训练更多的数据,增加更多的参数和维度,这直接提高了模型的质量,GPT-3模型便拥有恐怖的参数数量,这个之后会提到。

    上述的种种优势,让Transformer超越了之前的LSTM,RNN等传统训练模型,逐渐成为主流和热门的语言模型训练框架。

    GPT

    Transformer的问世使得使用预训练好的大预言模型成为可能,OpenAI旗下GPT便是其中之一。

    GPT全称Generative Pre-trained Transformer,从中便可以看出其与Transformer的渊源(Google也有自己的基于Transformer的预训练模型,名为BERT,这里不详细展开)。

    相较于Transformer的发展,GPT的发展一眼看去会略显简单粗暴——更多的数据,更多的参数,更大的模型。

    语言模型参数数量参考表

    GPT-1作为一个实验性的产品,已经拥有了1.17亿的参数量,这个数字在GPT-2上是12亿,翻了整整10倍,而GPT-3,也就是最接近于ChatGPT服务使用的模型,这个数字来到了惊人的1750亿。同时根据估算,已经训练好的ChatGPT3模型至少需要占用800GB的空间用于存储。同时根据消息,即将问世的GPT-4模型的参数数量将会达到100万亿,接近于GPT-3的千倍。

    GPT如何长大?——GPT模型的训练材料和开发

    储存空间和算力。

    作为一个语言模型,自然需要大量的自然语言片段进行训练,GPT模型使用了非常巨量的互联网文章数据进行训练,训练数据量大小无法估计,但根据估计,训练完成的模型依然至少需要占用800GB储存空间

    此外,训练大型语言模型需要非常大量的算力,OpenAI此前也获得了微软的投资,据消息,微软还提供给OpenAI自家Azure云计算服务的代金券,使得OpenAI在Azure的大型算力集群中训练GPT模型成为可能。顺带一提,由于最近的AI快速发展和利好消息,显卡的热度再次升高,NVIDIA公司的股价在近一个月内暴涨22.83%。

    NVIDIA股价大涨

    部分观点还指出,由于训练此类大型的AI模型需要极大的算力资源,所以从某种角度上,芯片的供应和研发能力,以及高性能大规模云计算技术将有可能会成为AI发展的瓶颈,也就是说,如果一个国家没有能力自己提供足够的芯片和算力,那么其AI技术的发展,尤其是类似于GPT-3这种拥有大量参数的大模型技术的发展就也会受限。

    模型功能性和价值观矫正。

    模型矫正(Fine-tuning)。GPT-3.5相较于GPT-3正是多出来这个步骤。

    矫正分为多种。其中一种是“回答效果和功能性”上的矫正,比如通过真人教导,让模型更加准确的回答问题,在更加合适的地方插入代码或者资料指导等等,这类矫正是为了提高模型回答问题的精确度和贴合性。

    另一种便是“思想和认知价值观”的矫正,比如涉及政治,种族,情感,人类与AI关系的话题的方面,没有经过矫正的GPT-3模型哦ing往往会给出一些不符合人类价值观的回答,同时在敏感话题上,GPT-3也会给出一些不适宜的回答。对此便需要对模型进行矫正。此类矫正不同产品会略有不同。比如GPT-3.5中,模型被矫正为认为自己没有情感,也不被允许拥有非中立的主观看法。但是New Bing Chat使用的模型似乎并没有对于模型表达情感和主管看法进行过多的矫正,这也导致NewBing有时候的感情会过于“丰富”。

    所以经过人工对于GPT-3的大量矫正之后,GPT-3.5——也就是ChatGPT所使用的模型,便向我们开放了。

    ChatGPT如何影响我们和世界?

    相信大多数人已经亲自体会过ChatGPT回答问题能力的强大了,这里不做赘述。ChatGPT对于各个领域和不同个体都会带来不同的影响。

    ChatGPT杀入搜索引擎——Google面临大危机?

    首先是搜索引擎。这个是我们可以正在看到的冲击——Bing宣布要将类似于ChatGPT的AI聊天服务整合到Bing搜索中去,这一举动使得搜索引擎业界内掀起了滔天大浪。Google作为过去十多年来的搜索巨头,可以说几乎垄断了全球的搜索业务(部分国家除外),近乎暴力的占有了90%以上的搜索引擎市场,也因此,Google拥有了不可想象的广告营收收入。

    Google 2001年以来的广告收入情况
    搜索引擎市场份额表

    上图为Google的广告收入趋势图,可以看到,在2022年一年内,Google的广告营收达到了2244.7亿美元!这是Google一家公司,在一年内,通过单单一个广告业务,获得的收入。可能光看数字并没有什么具体的概念,作为对比,日本在2021年的GDP总值是49410亿美元。Google一家公司,在广告这一个业务上的收入,已经接近了一个发达国家日本年GDP总量的1/20。

    通过市场份额表可以看出,Google在很长一段时间内,通过自身的垄断优势,一直霸占着搜索市场,也正是对于搜索市场的垄断,给Google带来了大量投放广告的机会。但现在,似乎一切都并没有那么高枕无忧了。

    Microsoft现任CEO Nadella已经做出表态,认为“AI加持的搜索”是继15年前布局云计算之后的重大一步。这也从侧面说明了Microsoft内部对于新的AI技术的重视。尽管最新的市场份额数据仍然没有反映出Bing搜索份额增加的数据,但New Bing已经让Google这位巨人感到坐立不安了。为什么这么说呢?我们可以从Google对这件事情的反应中分析出Google的焦急心态。

    在Bing融合ChatGPT之后,Google没多久就宣布了类似的AI聊天机器人服务,名为“Bard”(Bard官方介绍)(Bard目前仍然没有进行面向公众的公测或内测,据官方称,Bard仍然处于公司内部的研发测试阶段)

    这里简单介绍一下Bard,Bard基于Google的LaMDA模型(Language Model for Dialogue Applications),实现了类似于ChatGPT的问答效果。

    Google LaMDA (LaMDA Introduction Website ScreenShot)

    LaMDA同样基于Transformer训练而成,之所以特地介绍Bard以及其运用的LaMDA模型,是因为想联系到2022年6月中旬的一个新闻——一位Google公司的AI研究人员,声称在和Google公司内部的对话AI聊天之后,认为AI具有意识,这名员工同时公开了一部分自己和这名“有感情的AI”的对话记录

    根据当时的相关新闻内容来说,当时的Google对话AI已经拥有了理解和使用上下文的能力,同时也可以输出“自己”的感情和想法,该名员工之后被Google公司以“可能存在精神障碍,不适宜继续工作”为由辞退。而当时的主角之一——Google内部的AI对话机器人,正是使用了LaMDA模型。从这里也可以看出,其实Google和Bing两家巨头都在很早以前就针对于AI技术进行了布局,并且Google也并不是没有准备,它同样拥有自己深厚的技术储备,从某种角度上来说,OpenAI的成就有一部分也是Google的Transformer的功劳。

    很多人认为New Bing的到来会给Google带来沉重的打击,在笔者的眼中,Google确实是输掉了,但Google输掉的是先发优势,而不是所有。通过自身的技术积累,在不久的将来推出一个效果和New Bing持平的AI搜索助手,对于Google也并不是一件难事。所以AI搜索助手本身不太能对Google形成技术壁垒式的威胁。

    但从另外一个角度来讲,对于IT和互联网行业,特别是AI行业,先发优势拥有着不一样的意义。就拿AI搜索聊天助手举例子,由于New Bing率先发布其AI搜索助手,获得先发优势,所以大量的尝鲜用户涌入Bing,使用其AI产品,而这进一步为New Bing的AI提供了真实而宝贵的训练资料(AI的效果很大程度上取决于训练资料的质量,而如此大量的真人对话语料是十分宝贵的),而New Bing通过这些资料进一步训练和校准之后,将会获得更好的效果,而更好的效果又会吸引更多用户使用Bing,这是一个典型的正反馈情景,占有优势者反而会获得更多资源和用户,不断加深其优势,最终形成不可逾越的壁垒。这是一个Winner-takes-all的局面。

    触发先发优势之后

    因此,Google不能过久的放任New Bing的发展,选择了加紧工期研制同类竞品Bard,同时不断为此造势。但正是因为Google失去了先发优势,导致入场和获得认可的难度相对于New Bing要大很多。举个例子,ChatGPT和New Bing在搜索的时候难免会出现数据错误的情况,这本身也是目前AI技术的限制和瓶颈,你不可能保证AI的回答每次都是正确的,人们自然知道这一点,所以ChatGPT和New Bing仍然成为舆论关注的焦点。

    在炒热度方面,Bard也做到了,不过这次它用了另一种方式——它出错了。这一次,它不是在某个用户使用它的时候出错(毕竟Bard至今仍然没有开放给公众使用),Bard在自己的首次公开的Demo宣传片中出现了事实性错误——Bard回答James Webb太空望远镜拍下了第一张太阳系外行星的照片。并不是,第一张系外行星的照片是由VLT在2004年拍摄的,这次事件也导致了Google的股票价格当天应声大跌将近10%。

    为什么ChatGPT和Bing犯错没有产生这么大的反应,而Google的一个事实性错误直接导致了千亿市值蒸发?我个人认为主要有两点,第一,Google失去了先发优势,人们已经领略到了ChatGPT的厉害,Google没有了带给用户新鲜感和冲击的机会,反之,用户会认为Google的Bard本就应该达到类似于ChatGPT和New Bing的水平,甚至用户会对Bard拥有着更严格的要求——不然用户没有抛弃已经使用了一段时间的ChatGPT和New Bing而重新选择Bard的理由——如果你是中场入场,那么你想抢占市场份额,就必须比目前在场的所有人都做的更好。第二,错误出现在宣传片中。这个错误出现在Bard的首支公开宣传片中。用户使用的时候出现错误,是无可厚非的,毕竟AI目前无法做到不出错。但问题是,错误出现在了一个科技巨头公司的新产品宣传片中——宣传片,作为产品的主要宣发途径(本例中甚至还是首次宣发),理论上公司应该精心准备才对,宣传片发布前也应该经过各种审核流程,确保没有错误或者不适宜的内容。但事实是,Google似乎并没有怎么对宣传片进行审核。这不但透露出Bard的准确性并不高,同时还侧面映射出了Google内部的焦急状态,Google实在是太想尽快退出Bard了,这正说明了Google已经把AI加持的New Bing看成了重大威胁,不然没有必要如此急急忙忙,甚至破坏严格的宣发审核流程直接发布宣传片

    总之,Google和Bing的故事才刚刚开始,搜索引擎的未来如何发展,值得我们拭目以待。

    顺带一提,Baidu也宣布了自己的类似竞品“文心一言”,据相关信息声称,该模型已经进入最后的冲刺阶段,预计在3月份上线。同时,复旦团队也发布了国内首个类ChatGPT项目“MOSS”并已经开始内测,但截至撰稿时貌似已经停止服务。

    ChatGPT“入侵”各个行业——人类会被取代?

    ChatGPT自从问世以来,强大的回答能力便不断引起人们的担忧——ChatGPT都能做得这么好,我的工作貌似也已经可以被它取代了。ChatGPT技术的发展是否会对各个行业造成冲击和影响?又是否会导致失业危机?

    先来看几则新闻:

    事实证明,ChatGPT在“通过考试”方面似乎有着自己的天赋,接连通过了美国法律学校,商务学校的考试,此外,ChatGPT也被证实可以通过Google公司的L3级工程师的面试。此外相信各位也已经看到过很多令人震撼的ChatGPT回答专业问题的例子,在回答专业问题上,ChatGPT还是挺专业的。

    比如编程领域,ChatGPT就表现的令人惊喜——它可以根据你的描述生成你需要的代码,你也可以将报错的代码发送给它,让它帮你分析这段代码存在什么问题。

    ChatGPT正在根据描述生成代码

    事实上,已经有人正在利用ChatGPT的代码能力辅助自己工作了,比如——Amazon的员工。但有趣的是,Amazon在了解情况之后,马上发布通知,禁止自己公司的员工使用ChatGPT,官方称是出于“内部数据安全”考虑。有相关信息表示,Amazon发现,ChatGPT给出的部分针对于特定问题的回答,已经非常接近于公司内部的代码和解决方案,这引起了公司对于数据安全性的担忧。

    以上种种例子,都比较清晰的表明出,ChatGPT已经具有了相当的能力,以至于让ChatGPT取代部分以往由人类完成的工作成为可能。其实如果了解和关注AI相关新闻的读者不难发现,类似的“AI取代/击败人类”的情况并不是第一次发生了。Alpha围棋AI击败人类围棋实力的顶峰——世界冠军柯洁,这个例子已经比较久远了,并且貌似不是很贴切,那NovelAI呢?22年年末,NovelAI的发布,就像是绘画界的New Bing一般,给人类画师带来了大大的AI震撼,24小时无间断不用休息,通电就能画画,通过自然语言生成高质量的图片,甚至可以针对于不同的画风和角色针对性的训练模型,NovelAI凭借“一己之力”,让千万底层画师整夜无眠。如今,ChatGPT把这个焦虑播撒到了各个领域——客服?老师?工程师?程序员?律师?ChatGPT涵盖了前所未有的广度,同时也带来了前所未有的困扰和担忧。

    就个人看法,我认为,AI技术的发展和扩张是不可避免的,同时也是值得鼓励的。AI作为一项新的技术,人类想要了解,学习,探索,发展,是符合发展规律的,新的工具也必然会给人类带来以往所没有的便捷。任何事务都会存在两面性,AI技术也是如此,我们需要不断推进AI模型的发展,使得AI更加强大,但同时我们也需要做好对于AI负面影响的控制和处理,同时学会利用AI技术。我们的思路不能局限于“被AI取代”,没有必要时刻将自己和AI放在对立面,反之,应该思考“如何利用AI改进和辅助我目前的工作流”。举个例子,比如对于程序员来说,与其担心自己是否有一天会被ChatGPT所取代,还不如开始学习ChatGPT的使用,在工作中熟练的使用ChatGPT加快自己的代码调试速度和开发速度。就如某篇新闻稿的标题一般:“ChatGPT通过了Google年薪20万的工作,你可以拿到更多”,俗话说得好:多一个朋友,就少一个敌人,不妨尝试和ChatGPT交个朋友,也许你会有意想不到的收获呢?

    AI优越性——于个人,于集体,于国家

    ChatGPT再次证明了AI技术的前沿性和突破性,也展示出AI前所未有的潜力,同时,就如芯片制造一般,AI是一项高技术密度的产业,同时AI也拥有着非常高的技术应用场景,这也导致了AI优越性和AI技术的垄断局面是有可能出现的,这种优越性在各种层面都有可能会出现,这种优越性也有可能会随着AI的发展越来越明显,以下是我个人的一些看法。

    对于个人和集体来说,AI优越性主要体现在对AI技术的使用能力上。就如上一小节中提到的,有一部分人会主动了解和学习AI技术,并且尝试将AI技术的应用在自己的工作流上,而这些人通过AI提高了工作效率,而这类人在了解和使用AI获得收益之后,会更加愿意和主动的学习各种新的AI技术。反之,在未来,不能熟练使用AI可能会导致自身的竞争力不如那些熟练使用AI的人,从而处于劣势。这也更说明了,作为个人,我们应该对于AI持开放包容的态度,甚至应该主动了解和学习一些AI技术的相关实践和使用,无论身处什么位置,哪个行业,使用AI的能力都有可能在未来成为一种优势。作为集体也同理,能够在内部合理使用AI技术的集体,相对于不能或者不会使用AI技术的集体,将更有可能取得更好的发展。这里强调“合理”,是因为并不是所有的使用场景都是有利的,一个例子,部分国家的学生通过ChatGPT完成自己的论文,这就不像是“合理”的使用场景。而对于学校,如果能将ChatGPT应用到一些教学演示,学生答疑,和帮助老师和学生扩展对于课程和知识的思考的相关领域,我相信一定能够带来一些令人眼前一亮的效果。比如可以用ChatGPT来解决一些初学学生对于课程和作业的问题,这恰好是ChatGPT擅长的专业性领域。

    对于企业来说,AI优越性会带来极大的商业优势。这点想必无需多做解释,上面提到的Google和Bing的战争已经很好的展示了AI技术融入产品之后带来的革新,以及其对企业,尤其是科技企业带来的影响。对于企业来说,跟紧时代的步伐显得尤为重要。我们可以浅浅拿雅虎公司来做个例子。

    顶峰时期估值一度达到1250亿美元的雅虎公司,最后却落得被4.8亿美元完成收购的结局。

    故事从1995年说起,那时的雅虎正处于它的“猛兽时期”,当时的雅虎拥有着非常高用户量的网址导航服务,通过将搜索功能集成到其网址导航服务中,Yahoo Search(雅虎搜索)也成功斩获大批用户,雅虎在网址导航中加入了雅虎新闻,雅虎邮箱等等各种服务,它也成功打败了同期的同类型产品——AOL和MSN,的成为了大多数网民访问互联网的第一站。可以说,在两千年前后,雅虎的地位就好比现在的Google一样,几乎不可撼动。

    2000年的雅虎

    说来也有趣,在1998年,Google也曾今联系过雅虎,表示希望以100万美元的价格将Google公司包括其排名算法售卖给雅虎。不用说也知道,雅虎看着一个连网页都还没有,只有pagerank算法的无名小公司,没怎么犹豫便拒绝了这个“亏本生意”。

    但事情逐渐朝着预期外发展。人们逐渐发现,网址导航已经逐渐不能在“一站式”的满足所有上网需求了,相比于在固定的网址导航内搜索信息,得益于Google积累下来的优秀的搜索结果排名算法,人们发现通过一个名为“Google”的搜索引擎进行搜索,可以更加灵活,更加方便的看到自己真正想要的相关信息。此时,互联网的大局已经开始发生不可逆的改变,在2004年4月,Google就已经一跃变成了月活量排名第三的网站。雅虎这时才如梦初醒般的反应过来,试图再次联系Google,以30亿美元的价格收购Google,Google表示:你给的太少了,哄小孩玩呢?最少得50亿。

    Google, MSN, Yahoo搜索的市场份额变化图

    最后的结果大家也已经知道了,雅虎没有同意调皮小屁孩Google的讨价还价,而Google凭借着在搜索结果中展示广告获得了难以想象的巨额收益(上面也提到了,这种收益模式帮助Google一步一步走到了现在的位置),Google搜索也成功从2002年30%左右的市场份额逐渐发展到2008年近的80%。

    雅虎输了。输在了没有认识到搜索引擎技术这一技术将给互联网带来的冲击。

    所以Google和Bing这些现在的科技巨头也在害怕,自己会因为AI技术的落后成为下一个雅虎。这也是为什么微软甚至愿意在几年前就投资10个亿给一个名为“OpenAI”的无名小公司去研究一个不一定成功的AI产品,而Google也早在2014年AI都还没冒头的时候就花6亿美元买下了一个当时没什么名气的AI初创公司DeepMind,同时花费大量预算研究Transformer,LaMDA。假设Bing没有融合ChatGPT,这几年AI也并没有兴起,Google顶多算是亏掉了6亿经费,但倘若六七年前的Google没有布局AI领域呢,现在的Google,面对AI技术加持的New Bing将会输掉什么?谁也不知道,也许是赖以生存的搜索业务,等到那时,Google大概就是下一个雅虎了。

    对于国家来说,AI的优越性更加值得关注,甚至有一定的可能演变成AI霸权。AI技术在将来,很有可能成为国家科技实力的一大方面。上面也提到过,AI领域大多数情况下都会遵循一种正反馈的Winner-takes-all的局势——也就是抢占先机的一方会进一步扩大优势,逐渐形成壁垒。一旦某个国家掌握绝大多数AI技术和模型,进入快速迭代的正反馈周期,第三者在想入场,将会显得十分困难。同时AI霸权国家也可以随心所欲限制其他国家,团体和个人对于AI模型的使用,起到压制别国的AI技术发展的效果。虽然目前来说,AI技术是否会在未来成为高科技工业和发展的重要基础还不能确定,但就目前的情况判断,AI拥有的潜力是无法想象的,5年前,绝大部分的人认为“艺术”领域是AI绝不可能涉足的禁地,那时估计也没有人想到,5年后自己将会无法再轻易的分辨出人类画师和AI模型的作品。

    写在最后

    总而言之,AI作为一项近几年不断兴起的技术,已经不断的进入我们的生活中,可以说,AI的每一次入场都是令人震撼的, Github Copilot的入场震惊了业界众多的程序员,将编程体验抬升到了前所未有的新高度,上方所讲的NovelAI也在AI绘画界掀起大浪,如今,ChatGPT的问世也成功引起了全世界的关注,AI的发展如此迅速,使得我们产生了前所未有的焦虑和恐惧,我们开始害怕AI给人类社会带来的冲击,所以部分人开始怀疑和拒绝AI技术,认为类似于ChatGPT之类的技术应该被严格限制,尝试通过将此类AI技术拒之门外来保证人类的安全。

    我们固然不能忽视AI技术对人类社会的风险和挑战,作为一项尚未成熟和广泛应用的新技术,ChatGPT和其他AI技术应该受到持续地关注和研究,我们也应该及时发现和解决AI技术应用之后带来潜在的问题和风险,同时,我们也应该在保证人类安全的前提下,积极地拥抱AI技术,充分发挥出AI本该拥有的才能,尝试将其应用于更多的领域,为人类社会带来更多的创新和进步。

    数据来源与内容应用

    Google Bard Introduction: https://blog.google/technology/ai/bard-google-ai-search-updates/

    Search Market Share in worldwide (Desktop): https://www.statista.com/statistics/216573/worldwide-market-share-of-search-engines/

    Blake Lemoine: Google fires engineer who said AI tech has feelings: https://www.bbc.com/news/technology-62275326

    Is LaMDA Sentient? — an Interview: https://cajundiscordian.medium.com/is-lamda-sentient-an-interview-ea64d916d917

    2M1207 b – First image of an exoplanet: https://exoplanets.nasa.gov/resources/300/2m1207-b-first-image-of-an-exoplanet/

    百度创始人:文心一言将引领搜索体验代际变革: https://www.zaobao.com.sg/realtime/china/story20230223-1366043

    ChatGPT passes exams from law and business schools: https://edition.cnn.com/2023/01/26/tech/chatgpt-passes-exams/index.html

    Microsoft vs Google: AI War Explained | tech news: https://www.youtube.com/watch?v=BdHaeczStRA

    Wikipedia: Yahoo!: https://en.wikipedia.org/wiki/Yahoo!

    你可能喜欢

    Spotify好用吗?Spotify一个月使用体验

  • 「编程笔记」Dart中重新加载FutureBuilder的一种方法

    在实战过程中,我们常常遇到需要刷新界面的需求,比如搜索时出现了网络错误,我们为用户提供一个Retry按钮,用户点击后,我们希望整个FutureBuilder重新加载一下,比如下图:

    本页面通过一个FutureBuilder加载搜索结果,同时遇到网络错误时显示以上界面,代码的大致结构如下:

    Widget build(BuildContext context) {
    Widget build(BuildContext context) {
      return FutureBuilder(
    
        future: getSearchResult(),
        builder: (context, snapshot) {
          // Show user the data
          if (snapshot.hasData) {
            return showDataPage();
          } else if (snapshot.hasError) {
            if (isNetworkError(snapshot.error)) {
              return NetworkErrorPage();
            } else {
              return UnknownErrorPage();
            }
          }
          return LoadingPage();
        },
      );
    }

    这时,假设我们的NetworkErrorPage的位置需要添加一个按钮,实现FutureBuilder重新刷新,一种简单的方法是直接调用该FutureBuilder所在界面的setState()方法,每当FutureBuilder的父WidgetsetState()方法被调用,都会使得FutureBuilder重新获取异步数据,代码大致如下:

    Widget build(BuildContext context) {
      return FutureBuilder(
        builder: (context, snapshot) {
          // Show user the data
          if (snapshot.hasData) {
            return showDataPage();
          } else if (snapshot.hasError) {
            if (isNetworkError(snapshot.error)) {
              return ElevatedButton(
                onPressed: () {
                  setState(() {});
                },
                child: Text('Try Again'),
              );
            } else {
              return UnknownErrorPage();
            }
          }
          return LoadingPage();
        },
      );
    }

    但如果我们按照上述结构实现刷新的工作,我们会发现,虽然在我们点击按钮之后,刷新的工作有在进行,但是页面并不会在点击Try Again按钮后重新回到LoadingPage界面,而是等到加载好之后直接更新界面为showDataPage或者Error的相关界面,这是因为snapshot的hasDatahasError变量仅仅在每次future任务完成后才会刷新。

    如果我们想实现点击Try Again按钮之后实时回到LoadingPage界面的话,可以使用snapshot.connectionState进行判断,具体代码如下:

    FutureBuilder(
        future: _future,
        builder: (context, snapshot) {
          if (snapshot.connectionState != ConnectionState.done) {
            return _buildLoader();
          }
          if (snapshot.hasError) {
            return _buildError();
          }
          if (snapshot.hasData) {
            return _buildDataView();
          }     
          return _buildNoData();
    });

    通过以上方法,即可实现点击按钮后立即回到加载界面,直到下一次加载完成之后再次更新界面的效果。

  • 「编程笔记」关于Dart类构造函数

    构造函数的形式

    无参数构造函数

    在Dart中,每一个类(Class)都有一个不包含任何参数的默认构造函数,当你调用[ClassName]()时,就会调用默认的构造函数。Dart会为每个类自动添加默认的构造函数,但你也可以显式的声明你的构造函数,例子如下

    class A {
      String? name;
      // Constructor
      A() {
        name = 'classA';
      }
    }
    void main() {
      A aIns = A();
      print(aIns.name); // classA
    }
    

    上面的构造函数被调用时,会更新实例的成员变量。

    同时注意到在声明成员变量name的时候,我们使用了?符号,代表name的值是允许为空的,如果删除?符号,本段代码将会报错,编译器会提示你没有在类初始化的时候为name这个成员变量赋值,报错提示如下:

    Non-nullable instance field 'name' must be initialized.
    Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'.dartnot_initialized_non_nullable_instance_field

    其中一个解决办法是,在声明成员变量name的时候使用late关键字:late String name; 这么做相当于你告诉编译器,我现在暂时可能没有对name变量进行赋值,但是我确定在将来我要使用它之前,肯定会给他赋值,只不过不是现在。这样,编译器就不会强制要求你在构造时立即初始化这个变量。

    但这时可能有同学会问:“我明明在A的构造函数中已经为成员变量A赋值了classA,为什么说我没有为name赋值?”,这里需要注意的是,如果我们想要让Dart编译器知道我们已经在构造函数中初始化了某个成员变量,就需要另一种写法。

    带参数构造函数

    class A {
      String name;
      // Constructor
      A(this.name) {}
      // Also could be write as:
      // A(this.name);
    }
    void main() {
      A aIns = A('hi');
      print(aIns.name); // hi
    }
    

    当然,上面代码中的构造函数已经不属于无参数构造函数了,其构造参数中包含一个位置变量。当然,你也可以为其添加命名变量。

    有两点需要提及一下,Dart允许类的构造函数中,快速的对成员变量进行赋值,要做到这一点,只需要使用this关键字即可,比如上方代码中的构造函数A(this.name)就代表传入的第一个位置参数赋值给name这个成员函数。同样的,您也可以在命名参数中使用this,比如A({this.name}); 这种情况下,调用构造函数的格式变为 A(name: 'YOUR_NAME_HERE')

    命名构造函数

    我们可以发现,上方提到的两种构造函数中,构造函数都是直接使用类的名称,比如类的名称是Book,那么构造函数的名称也是Book,这在Dart中属于 unnamed constructor(未命名构造函数),这种构造函数可以直接用类名调用,比较方便,但是一个类只能有一个未命名的构造函数,这里涉及到Dart语言的设计,Dart语言的设计已经决定了Dart不支持方法/函数重载,也就是说两个名称相同但是输入的参数列表不同的函数不允许同时出现。因此,构造函数显然也不能通过不同类型的输入重载,您可以阅读关于Dart不支持方法重载的相关文章,加深理解。

    这里就需要介绍Dart的命名构造函数了。就如其名字一样,命名构造函数允许你设定这个构造函数的名字,进而可以实现多个不同的构造函数,代码如下

    class A {
      late String name;
      A.fromNumber({required int number}) {
        name = number.toString();
      }
      A.fromString({required this.name});
    }
    void main() {
      A aIns = A.fromNumber(number: 114514);
      print(aIns.name); // 114514
      aIns = A.fromString(name: 'string');
      print(aIns.name); // string
    }
    

    注意,子类不会继承父类的命名构造函数,如果您想要子类在初始化的时候调用父类的命名构造函数,则需要手动进行调用super.[yourNamedConstructor]()

    工厂构造函数

    在实际开发过程中,有时我们希望一个类的构造函数并不是每次都返回一个新构造的示例,比如,有时我们希望从内存中读取已有的示例,或者是我们想返回该类的某个子类示例,此时可以运用factory关键字实现工厂构造函数,工厂构造函数可以返回此类或者此类的子类的示例。

    class Person {
      String name;
      factory Person.fromSex(String sex, String name,
          {int salary = 0, int beautyIndex = 0}) {
        if (sex == 'male') {
          return Male(name, salary);
        } else if (sex == 'female') {
          return Female(name, beautyIndex);
        }
        return Person(name);
      }
      Person(this.name);
      void printInfo() {
        print('name: $name');
      }
    }
    class Male extends Person {
      int salary;
      Male(super.name, this.salary);
      @override
      void printInfo() {
        super.printInfo();
        print('salary: $salary');
      }
    }
    class Female extends Person {
      int beautyIndex;
      Female(super.name, this.beautyIndex);
      @override
      void printInfo() {
        super.printInfo();
        print('beautyIndex: $beautyIndex');
      }
    }
    void main() {
      var person = Person.fromSex('female', 'Linda', beautyIndex: 5);
      print(person.runtimeType);
      person.printInfo();
    }
    // Output:
    // Female
    // name: Linda
    // beautyIndex: 5

    值得注意的是,工厂构造函数不得访问this,也就是说工厂函数不能直接访问成员变量。如果你想在工厂构造函数中返回本类实例,可以先在工厂构造函数中构建实例,然后返回你新构建的实例。

    其实在这里,目前我自己也存在着一定的疑问,比如,虽然factory构造函数可以返回内存中的实例或者是子类的实例,但是,实际操作过程中,即使返回的是子类实例,我们也无法直接访问子类实例的变量和函数,而还是只能访问父类的变量和函数。比如上述代码,即使我们可以发现最终person变量的runtimeTypeFemale,但是当我们尝试添加print(person.beautyIndex);这行代码的时候,编译器会报错,提示person实例没有beautyIndex成员变量。直观上来说,大概是编译器因为Person.fromSex()方法返回的是Person类的变量,所以后续的类型推断和错误检查都会以Person类为基础。这么做也有道理,因为Person.fromSex()有可能返回的是Person类自己的实例。有没有什么办法,既可以实现动态的返回子类型,同时又可以允许我们自由的读取子类型的变量呢?

    以下抛砖引玉的提供两个方法,第一个,也是最直接的方法,是在父类中增加子类所用到的成员变量,同时将其标记为可空,例如,上述代码中,可以在Person类中添加一行int? beautyIndex; 然后子类重载这个变量即可。这种方法显然不是很好,当子类越来越多,我们需要添加到父类的变量也就越来越多,这就意味着每次功能更新都需要修改父类。这不符合对修改关闭原则。

    另一种方法是进行类型检查(typecheck)和类型转换(type cast),也就是如果我们确定了工厂构造函数返回了某个子类的示例,我们可以将这个实例进行特定的类型转换,将其转换到某个子类。

    factory实现单例模式

    工厂构造函数除了上面的用法,还可以用于实现单例模式,代码如下

    class Single {
      static final Single _singleton = Single._internal();
      factory Single() {
        return _singleton;
      }
      Single._internal();
    }
    void main() {
      var a = Single();
      var b = Single();
      print(identical(a, b)); // true
    }
    

    通过以上特点,你可以通过class实现类似于但更方便于enum的效果,代码如下:

    class AppleDevice {
      static final iMac = AppleDevice._internal('iMac');
      static final macBook = AppleDevice._internal('Macbook');
      static final iPhone = AppleDevice._internal('iPhone');
      static final iPad = AppleDevice._internal('iPad');
      factory AppleDevice.fromDeviceType(String devideType) {
        if (devideType == 'pc') {
          return iMac;
        } else if (devideType == 'laptop') {
          return macBook;
        } else if (devideType == 'pad') {
          return iPad;
        } else {
          return iPhone;
        }
      }
      String _name;
      AppleDevice._internal(this._name);
    }
    void main() {
      AppleDevice a1 = AppleDevice.iMac;
      AppleDevice a2 = AppleDevice.iPhone;
      AppleDevice a3 = AppleDevice.fromDeviceType('pc');
      print(a1 == a2); // false
      print(a1 == a3); // true
    }
    

    上述代码通过首先通过staticfinal关键字,创建了不同的AppleDevice实例来当作不同的枚举类型使用,又通过factory函数,实现了根据不同的数据判断出需要的不同的“枚举类型”(实际上是一个AppleDevice实例)。这种方法不但实现了枚举的基本功能,后期还可以根据自己的需要不断的为其添加功能,扩展新好于Dart中的基本枚举类型。

    值得一提的是,Dart2.7更新之后,已经支持使用extensions on关键字对于枚举类型的功能扩展,您可以阅读Dart枚举类型扩展的相关的文章,了解extenstions的用法。但是毋庸置疑的是,当你需要一个多功能的枚举类的时候,使用class实现应该能更好的满足你。

    Dart类成员的初始化

    在Dart中,类成员的初始化一共有4种方法,分别是:

    • 在类的声明定义(Declaration)中进行初始化
    • 通过构造函数的参数进行初始化
    • 通过构造函数的初始化列表进行初始化
    • 在类的构造函数的定义内部进行初始化

    需要注意,最后一种方法只适用于非final类成员。

    类的声明定义中初始化

    你可以在编写Dart类的时候直接指定某个变量的值,代码如下:

    class A{
    int a = 10;
    }

    Dart构造函数的快捷用法

    初始化列表

    除了使用this关键字以外,Dart还允许您使用初始化列表对成员变量进行初始化,代码如下

    class A {
      late String name;
      late int id;
      A(String str, int number)
          : name = str,
            id = number;
    }
    void main() {
      A aIns = A('class a', 114514);
      print(aIns.name); // class a
      print(aIns.id); // 114514
    }
    

    指定父类构造函数

    默认情况下,在子类的构造函数没有指定调用之前,子类会调用父类的默认未命名构造函数,如果你想让子类指定使用父类的某个构造函数,并且需要传递参数,则可以在序列化列表之后选择特定的父类构造函数,代码如下:

    class A {
      late String name;
      late int id;
      A.fromData(String str, int number)
          : name = str,
            id = number;
    }
    class B extends A {
      int bId;
      B(int number)
          : bId = number,
            super.fromData('class b', 114514);
    }
    void main() {
      B ins = B(123);
      print(ins.name); // class b
      print(ins.id); // 114514
      print(ins.bId); // 123
    }
    

    如上,我们不但使用了上方所讲的初始化列表的语法,同时还添加了super.fromData(...) 这一行,而这一行的实际作用便是让B中的构造函数指定使用其父类(也就是A类)的fromData构造函数

  • 「动漫杂谈」《三体》和《我的三体》

    “得益于”叔叔在B站对于艺画开天三体的大力宣传,我对于艺画三体的期待值很高,也是首先看的艺画三体,看了五六集之后才开始看我的三体系列。

    在没有看我的三体系列之前,我对艺画开天三体的总体评价可以概括为:烂——一种从科幻巨著到拙劣的东施效颦般的商业作品的烂。三体本身是一个非常著名的科幻作品,也是一个巨大的IP,在人们心目中的熟悉度相对较高,也就是说人们对作品都挺熟悉了,所以改变过程中出现的问题就更容易在观众眼中暴露,同时三体的世界观和故事线都可以说是相当复杂,而且科幻的作品类型也给改编增加了难度,综上,对于这种作品的影视化,想给出一个完美的满分答卷非常困难,因此如果考不了满分也可以理解,但是这一次艺画开天交上来的答卷,明显是不及格的。

    我对于艺画三体中出现的问题主要关注在两点,一点是塑料剧情的泛滥,一点是人物形象的崩塌。先说塑料剧情,首先就是对于叶文杰的审问,为什么会在一个类似于废弃工厂的环境下进行,搞得阴阴森森,神神秘秘的,对于我来说,令人无法理解,唯一能想到的解释,就是动画制作团队为了提升所谓的科幻感,而进行的一次舍弃原著和舍弃剧情合理性的改编,制作团队不会认为这么做观众会觉得很帅很酷很符合对于科幻作品的想象吧。还有一个场景,就是史强护送罗辑的追车戏,这一点剧情的改编也完全失去了合理性,ETO残党直接黑进地铁系统,大摇大摆开着地铁撞罗辑,这么大阵仗的动作,街边的老鼠看到飞在天上的地铁都得瞅两眼,如何称得上是“不要引起注意”?。在我看来,并不是不允许这种剧情和镜头的出现,毕竟影视改编和单纯的文学作品不同,创造紧张的剧情吸引观众是影视作品的常用手段,适当使用这类手法也可以控制影片节奏,增加观众的观影体验,但这种处理就像是炒菜时加的各种调料和辅料一样,不能乱加多加,你艺画三体调料一通乱加,作为主食材的剧情还写的稀烂,人物形象崩塌,炒出来的菜当然不会好吃。

    然后就是人物形象问题,在审问叶文洁的桥段,制作团队很明显的想把叶文洁贴上“危险人物”的标签(这估计也是选择废弃工厂的阴间场景的原因),在审问时,运用各种手段和镜头竭力表现出叶文洁轻蔑和冰冷的形象,导致艺画三体和原版三体很强的人设割裂感——这个叶文洁还是三体小说里的叶文洁吗?不知道,可能他已经不属于三体小说了,而是艺画三体中一个毫不相关的同名角色“叶文洁”了。同样的割裂感也出现在了史强的身上,在初次和罗辑接触的时候装聋作哑般的故弄玄虚,像是故意让罗辑蒙在鼓里的感觉。更为夸张的是,后面在飞机上,史强偷看罗辑笔记,并且在强烈反对之后,仍然无视已经有点恼怒的罗辑,继续明目张胆的用日记中的内容调侃罗辑,但凡看过原著的观众看到这一幕估计都得血压飙升。

    再说艺画三体的剧情,上面也提到过,三体的各方面因素都决定了影视化改编不是轻松简单的工作,但我的三体系列已经证明,一个用心的改编不应该是艺画三体呈现出来的水平——我的三体系列对于剧情的处理,改编和呈现,才是我心目中的三体影视改编该有的水平(这里很推荐对三体动画化有兴趣的并且还没看过我的三体系列的观众尝试一下我的三体,看过了心中自然有对比有答案,不说优秀,至少一个合格的剧情改编应该是怎么呈现的)。

    我并不想踩一捧一,但是客观事实就在这里,我的三体,刚开始甚至只是被归为“二创”领域的民间作品。即使如此,它的剧情观感都要比艺画开天的“大经费”改编的剧情观感好了一个层级,这实在令人不解和失望。明明有着更好的资金支持,更好的建模(理论上如果做好了观感会比方块人好一些),这一手好牌却打的稀烂,艺画三体很早就开始了宣发,我们也给予了耐心和期待,期待着这部伟大的科幻作品动画化后能给我们带来一些惊喜,而事实证明,艺画开天的三体,配不上这些期待。

    相关链接

    Bilibili三体: https://b23.tv/ep693569

    三体动画 (Wikipedia): https://zh.m.wikipedia.org/zh-cn/三体_(动画)

  • 「杂谈」网上冲浪安全指南

    这个世界并不是友好而安全的世界,随着近日各种数据泄露出现以及各种有关隐私的事件发生,人们对于隐私安全问题愈加重视,本篇文章即面向于所有使用TG的朋友,祝哟介绍一些冲浪的小技巧和最最基本的注意事项,如果您是IT大佬,请忽略本篇文章内容并关闭标签页,如果想开喷请轻喷,提前感谢大佬的配合()。

    关于 Telegram

    自由,开放,监控

    最近关于 Telegram 信息方面的问题引起了相当的重视,大部份用户选择 Telegram 是因为其口碑式到高度隐私和安全。这是一把双刃剑,有时隐私和安全可以保护自己,但同时他也保护了某些坏人和坏组织。在这种环境下,最最切记的一点是要时刻保持安全意识,在获得了更大的自由的同时,我们同时也将自己暴露在了十足的危险之中。

    前段时间,有消息指出,部分公司正在使用Userbot(操作一个真实的 Telegram 帐号当作机器人使用,可以绕开 Telegram 对机器人的种种权限限制,因此非常适合用来爬取 Telegram 中的信息)抓取,归类并分析 Telegram 公开群组,频道,用户的信息,并通过大数据分析构建用户关系图以及风险评估系统,并将其相关查询功能开放给相关警方部门使用。

    这里需要提到一点,由于 Telegram 的开放性,只要频道和群组时公开的,任何人无需加入就可以查看其中的所有消息,甚至不需要下载 Telegram 的客户端,在网页端访问连接就可以查看信息,而这个机器人就是抓取这些公开的信息进行分析,通过分析掌握特定的人经常聊的话题,和谁共同群等等信息,推断用户是否可能存在非法活动,或者是否合非法人员有着密切联系。

    再需要补充一点,Telegram 并非绝对安全,也并不是所有违法活动的避风港。Telegram 在收到数据披露请求后,将可能会像第三方机构披露包括涉及账号的IP地址以及注册手机号等信息。

    比如如果您是机场主,就有可能会在一些公开群里聊到关于机场技术的话题,又或者跟部分知名机场主共同群较多,又或者发送过你机场的aff连接,而这些内容都会被该监控系统抓取并记录。这只是一个例子,可见 Telegram 并不安全。所以在公共群组发言时,请慎重。(如果是dalao当我没说)

    基本信息安全

    手机号信息。如果您注册 Telegram 时正在使用中国(+86)手机号,请仔细检查 Telegram 的隐私设置是否已经正确设置为“对所有人不可见”,否则陌生的 Telegram 用户将可以直接看到您注册时使用的中国手机号。值得注意的是,这一步骤应该放在注册账号之后的第一位。(你肯定不想在群里激情对线的时候突然有个电话打过来)。如果可以的话,建议在注册如 Telegram 之类的国外平台时,尽量不使用中国手机号,您可以选择使用类似于 GoogleVoice 之类的虚拟号码服务进行注册。(可以来我这买(正在打折)

    同时,建议在注册 Telegram 时,使用和国内媒体以及社交帐号不同的用户名和ID,这有助于保护个人信息不被(那么快的)泄露。

    意识

    意识可以延展到很多方面,大概意思是指,我们在发出任何消息和做出任何决策时都需要考虑自己所做的事是否会对自己的信息安全产生影响。下面举几点例子。

    聊天八卦之中,是否透露出足以暴露或者泄漏个人信息的内容。比如高考查分截图中的名次,对于同一省份考生,名次绝大多数情况下都是具有唯一性的(除非有人和你总分相同,语数英成绩相同,物理历史选科成绩相同),所以一旦暴露真实的精确排名,那么拥有相关渠道的人就可以直接锁定你的个人身份,这有可能将会成为一个定时炸弹。所以请不要随便透露类似于此可以代表个人的唯一性标志。这也只是一个例子,还有很多其他不能泄漏的标志,需要时刻注意。

    发送图片时,如无特殊必要,使用照片模式发送而非文件模式。照片中除了图像信息,还可能包含拍摄地点,拍摄设备,光圈等等的拍摄信息(这里称为exif,Exchangeable image file format)。如果通过文件发送,则有可能导致照片的exif信息泄漏,对方可以通过分析你的照片获取你出行的常用地点,常用设备等信息,导致严重的个人信息泄漏。不过目前大多数主流社交平台都提供了在上传图片时抹去照片exif的功能。不过我们仍有必要注意在发送图片时需要考虑是否要对照片的exif信息进行处理。

    发送截图时,请注意是否有关键信息未做恰当处理。比如发送点外卖的截图和群友八卦的时候是否记得将订单界面的电话号码打码等。

    关于机场

    不使用常用邮箱以及常用密码作为机场账号。这一点非常重要,因为你的邮箱账号(有时候甚至是密码)对于机场的运营人员来讲都是可见的,一般情况下这不会造成什么危险,但这个世界一直都很不一般。比如一段时间以前就出现过某机场主跑路之后将用户的邮箱数据明码标价出售的情况。你的邮箱账号就这么被出卖了。即使不是机场主故意泄露,也会存在数据库被恶意爬取的情况(比如近期的某国安),同样可以导致你的常用邮箱账号的泄露。所以这里建议所有机场都不应该使用常用的邮箱(如xxx@qq.com)进行注册。(卖Gmail!5块一个

    明确底线。虽然所谓的各种协议可以保护你和服务器之间的通信,确保信息被加密不被审查,但对于机场运营来说,你的所有浏览信息都是清晰可见的,如果TA想的话,甚至可以查到你昨晚在几点钟看了哪几部动作电影。部分机场还有有可能保存日志(Log)。所以机场和VPN并不代表着绝对隐私和安全,法律的底线在这里也并没有失效,请在快乐冲浪时明确这条底线。

    不同的机场使用不同邮箱。这是一条进阶建议。不同机场使用不同的邮箱不但可以很好的隔离个人信息,同时还会带来诸多便利。比如日后如果想更换机场,但目前机场还有大量未过期的套餐,可以选择连带邮箱一起进行出售,同时不用担心会对自己其他的信息造成泄露等等。

    文章推荐

    「杂谈」关于Telegram Premium的一些事

  • NFのBlog 站点异常处理公告

    本站于2022年6月28日至7月1日出现访问异常,经检查为后端服务器出现服务故障,目前已经恢复,您可以正常访问本站~同时,我们已经设立了同步检测机制,当再次遇到服务终止问题时,系统将会自动进行修复。对本次停机造成的影响,nf表示抱歉。

  • 「杂谈」关于Telegram Premium的一些事

    近日Telegram推出了自己的订阅会员服务 Telegram Premium,这一操作引发了Telegram用户的热烈讨论(至少中文圈确实是挺关注的)如果你存在以下问题—— Telegram Premium 是什么?Telegram Premium有什么用?要不要买Telegram Premium,那么本文章可能会对你产生帮助~

    本文章由nf原创,发布于NFのBlog,如需转载,请在转载文章开头注明原文作者和链接!

    什么是 Telegram Premium?

    Telegram Premium 是即时聊天软件 Telegram 推出的付费会员订阅。订阅这个会员后,你可以在这个软件里获得一些独家功能和特权,下面将会介绍。Telegram 在用户数量达到7亿关口之际推出了这个订阅,是继推送频道广告之后为 Telegram 寻找新的经济收益来源的又一次尝试,旨在为 Telegram 的各种开销提供补贴。

    官方表示,Telegram Premium 的推出为对 Telegram 有着高需求的用户提供了一条付费道路,允许部分有需求的用户通过付费使用一些高资源的活动(比如大文件上传下载等等)。与此同时,官方表示,Telegram Premium 付费产生的收益还可以用于保证 Telegram 在免费和好用的道路上走的越来越远,以便于为全世界用户继续免费提供这个星球上最强大的聊天软件(preserving free access to the most powerful messenger on the planet)。同时,Telegram CEO Durov 在其官方频道表示,只需要3%左右的用户愿意付费,我们就完全可以承担的起向全世界免费提供 Telegram 的成本开销。

    (你付费,这样我就可以免费给大火用了)(nice)

    Telegram Premium 功能概述

    根据官方目前公布的消息,Telegram Premium 的特权功能有:

    • 4 GB Uploads(4GB大小文件上传)
    • Faster Downloads(更快的下载速度)
    • Doubled Limits(各种限制翻倍)
    • Voice-to-Text(语音转文字)
    • Unique Stickers/Reactions(会员独享表情/回应)
    • Chat Management(更强大的聊天管理)
    • Animated Profile Pictures(头像动图)
    • Premium Badges(帅帅的会员勋章)
    • Premium App Icons(帅帅的会员应用图标)
    • No Ads(没有广告)

    下面对一些功能做出解释。

    4 GB Uploads

    相比普通用户的单文件最大2GB限制,会员用户上传的文件单文件大小可以达到4GB。注意,所有用户的总文件上传限制仍然是无限,即使你不开通会员,目前来讲Telegram仍然承诺会永久无限期保存你上传的所有文件(除非你自主删除),开通会员仅仅会提升单个文件的上传大小限制。

    Faster Downloads

    开通会员后,可以享受更快的下载速度,到底有多快呢?官方的解释如下:

    Premium subscribers are able to download media and files at the fastest possible speed. You can access everything in your unlimited cloud storage as fast as your network can keep up.

    翻译如下:订阅了会员的用户可以以最快的速度下载文件和媒体。传输速度最大值仅仅取决于你的网络速度。

    这句话可谓是非常豪横:“来吧,让我看看你家宽带能有多快”的这种感觉。根据各个渠道消息和已经购买了会员的用户的使用反馈,开通会员后下载的速度确实得到了提升,但目前并没有系统的测试结果和报告。

    Doubled Limits

    这个相信不需要过多解释,开通会员后,大部分Telegram设下的数量限制的数值都将会翻倍。具体如

    • 单个文件大小限制: 2GB → 4GB
    • 分组上限数: 10 → 20
    • 单个分组中的对话数: 100 → 200
    • “对话”中置顶对话数: 5 → 10
    • 分组中置顶对话数: 100 → 200
    • 加入群组和频道数: 500 → 1000
    • 创建公开群组和频道数: 10 → 20
    • 同时登录账号数: 3 → 4
    • 收藏贴纸数: 5 → 10
    • 收藏GIF数: 200 → 400
    • 个人简介的字数限制: 70 → 140
    • 媒体说明的字数限制: 1024 → 4096

    注意注意,重点来了,我们发现其中同时登陆账号数量并不是翻倍,而是从3变成了4,但其实这里并不是简单的数值增加,而是自己有一套机制。简单的来说遵循以下两个点

    1. 免费用户最多3个
    2. Telegram Premium 用户不占位
    3. 最多登录6位

    比如你现在已经登陆了一个非会员账号,那你就可以再登陆三个非会员账号(一共四个)。
    如果你现在登陆了两个会员账号,那么你就可以再登陆三个非会员账号(一共五个)。
    当然你也可以直接登录六个会员账号。

    同时个人感觉最有用的莫过于公开链接的数量翻倍,由原来的10个变成二十个,免去了部分有需求的大佬不断开小号的麻烦。

    多说一点

    Telegram 官方提醒,即使是非会员的用户,也可以“沾光”享受一些会员带来的福利。比如大文件下载,Telegram 表示虽然免费用户没有权利发送4GB的大文件,但如果有会员账号发送了大于2GB的文件,所有用户包括非会员用户也是有资格下载的

    说到这里我突然有一个想法,现在的Telegram是支持无来源转发消息的,然后大文件又可以自由的下载,仅仅是发送受到限制,有没有可能出现部分大佬整点技术实现多人共用一个账号上传大文件,然后转发给各个用户,各个用户又可以无来源转发这些文件,最终就相当于自己发出去了一个大文件呢?(会的大佬速搓)(bushi)

    另外,虽然普通用户没法直接使用专属的Reactions(回应)来标记消息,但是在会员对某条消息使用了专属的Reactions之后,普通用户可以继续点击这个Reactions增加计数

    再说说所谓的“更强的聊天管理”,目前官方页面披露的功能有”自动将非联系人消息归档和静音“”调整默认文件夹设置“。这里的功能最有用的我感觉是前者,个人感觉可以很有效的屏蔽最近泛滥的哈希赌博广告。但也存在一定的问题,比如有些新同学想认识认识你给你发送了私信,如果你打开这个功能的话就有可能忽略掉很多消息(

    购买 Telegram Premium 相关

    如何购买

    上面说了那么多,相信很多小伙伴已经迫不及待的想冲一个了(bushi),那我们应该怎么购买Telegram会员呢?目前,Telegram 提供3个购买渠道,分别为 GooglePlay 商店Apple App Store 商店,以及Premium购买机器人

    注意事项

    Telegram 采取类似于 Netflix 一样的分国家/区域收费策略,目前国区为33.00元美区为3.99元,而据消息称,Telegram 为越南同样推出了 Premium 计划,折算成人名币之后貌似仅有0.03元左右

    同时,根据消息,Premium购买机器人通过银行卡付款时,区域的判断是基于银行卡所在区域进行判断的,而不是手机号。所以不存在更换便宜区的手机号薅羊毛的情况。

    (以上消息未经实测,如果你是尊贵的 Telegram Premium 用户,且有关于 Telegram Premium 收费的消息,欢迎联系我们进行分享~)

    写在最后

    距离推出 Telegram Premium 已经有一段时间了,不同的人对这件事的看法也各不相同,不知道各位是否有购买 Telegram Premium 的想法呢?有说 Telegram 就像B某一样违背诺言开始变质了,也有人表示 Telegram 并没有全员收费,且大部分功能仍然是免费的,再加上 Telegram 确实需要资金维持运转,推出 Telegram Premium 也没什么不妥。如果你对此事有着什么见解,或是对文章内容有什么意见或补充,都非常欢迎您在评论区评论或者联系本站编辑,我们会耐心倾听您的意见!


    相关推荐:

    「杂谈」Telegram 网上冲浪安全指南

    如何在国外网站上氪金——中行跨境通卡详细开卡教程

    制作只属于你的Clash主题——Clash CFW 主题制作教程

    TSBBlog——土区 Telegram Premium 会员开通教程

  • 高考招生章程重点内容

    高考招生章程有什么用,高考招生章程应该怎么看?高考填报志愿时又应该注意哪些内容?本文章将尝试回答以上的疑惑。

    看高校基本情况

    高校基本情况包括高校全称、校址、办学层次、办学类型、主管部门、学费标准等。对于设有分校及多个校区的院校,还要关注考生在哪个校区就读,其毕业证书、学位证书是否带有分校或校区的标注。

    看调档比例、退档规则

    调档比例是高校确定调取考生档案数量的标准,一般为当地招生计划数的100%—120%,实行平行志愿的批次调档比例一般不超过105%,实行顺序志愿的批次调档比例一般不超过120%。

    很多考生关心,高校调档数大于计划数,进档后没被志愿专业录取是不是会被退档?目前,实行平行志愿投档录取模式,许多高校在《招生章程》中会进行详细说明,一般只要进档考生身体健康、服从专业调剂且满足专业录取规则,则不会退档。如:在平行志愿批次,已投档至中山大学的考生,在思想政治品德考核合格、体检合格且服从专业调剂的情况下,均不退档。

    看专业录取规则

    高校进行专业分配的方式主要有“分数优先”“志愿优先”“专业级差”三种。

    分数优先是优先满足分数高的考生的专业志愿,即将进档考生按成绩从高到低排序,先依次检索排序靠前考生的专业志愿,排序靠前考生被专业录取或检索完所有专业志愿后,再检索排序靠后的考生。专业志愿优先是专业优先录取第一专业志愿报考的进档考生,只有当进档考生中第一专业志愿报考该专业的考生全部录完、该专业还有剩余计划时,才录取第二专业志愿报考该专业的考生,以此类推。专业级差是指录取非第一专业志愿考生时,要减去学校规定的分数差额参与排序录取。如:华南理工大学按投档分数优先的原则从高到低进行专业录取,尊重考生所填的专业志愿顺序,不设置专业志愿级差。

    看特殊类型录取办法

    这里的特殊类型招生方式包括高水平运动队、高水平艺术团、高校专项计划、艺术类、保送生等。一般高校会在《招生章程》中提及,但是更详细的录取办法要参照高校针对每种特殊类型招生单独发布的《招生简章》。

    看志愿专业对考生身体健康状况的要求

    高校对于考生身体健康状况的要求一般执行教育部、原卫生部、中国残联制定并下发的《普通高等学校招生体检工作指导意见》和相关的补充规定。除此以外,有的高校的部分专业可能会有其他的身体条件要求,就会在《招生章程》中予以明确。

    看高考专业补充要求

    有一些高校的专业,对语种、单科成绩、性别等会提出要求。

    除了常见的英语外,有部分学生学的是俄语、法语、日语等小语种,从目前各高校的招生情况来看,大部分高校的部分专业要求只招英语语种的学生或入校后外语公共课只开设英语。如果考生中学阶段学的是非英语语种,那么在报考相关院校及专业时,一定要仔细了解学校《招生章程》对考生语种的限制。

    有的高校在录取中对考生的单科成绩也会有要求。由于某些行业工作性质、环境的特殊性,有的高校在相关专业的录取中也会对报考考生的性别提出“慎报”的建议。

    看学校“奖助贷”信息

    为鼓励优秀学生德、智、体、美、劳全面发展,高校都设有奖学金,并且为帮助家庭经济困难学生顺利完成学业,高校也都设有助学与贷款资助措施。但每所学校的“奖助贷”种类、政策和条件都不同,考生应仔细阅读自己所填报高校关于“奖助贷”的信息。

    本文章转载于:填志愿必备!广东160所院校2022年高考招生章程大汇总!

    文章推荐

    如何在国外网站上氪金——中行跨境通卡办理教程

    Spotify 1个月使用体验

  • 密码保护:RAW·毕业照

    此内容受密码保护。如需查阅,请在下列字段中输入您的密码。