菜小胖

菜小胖 查看完整档案

北京编辑  |  填写毕业院校  |  填写所在公司/组织 test.com 编辑
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

个人动态

菜小胖 赞了文章 · 10月10日

走近Ts,用了爽,用后一直爽(一)

前言

vue3已经发布了,ts的脚步已经阻拦不住了,还只会es6?别想了,人家都已经在行动了,以下是ts的基本系列教程,ts的基本语法,高级语法等,以及在vue项目中如何应用ts,跟着我赶紧撸起来吧。

基本数据类型

数字

const a: number = 3;

字符串

const b: string = "1";

数组

const c: number[] = [1, 2, 3];
const d: Array<number> = [1, 3];
const arr: any[] = [1, "33", true];

元组

可以为数组中的每个参数定义相对应的类型

const e: [number, string] = [1, "ww"];

枚举

enum error {
  blue = 3,
  "orange",
}
const f: error = error.orange;
console.log(f); //输出4

tips

  1. 如果未赋值的上一个值是数字那么这个未赋值的值的是上一个值的值+1
  2. 如果未赋值上一个值未赋值那么输出的就是它的下标
  3. 如果未赋值的上一个值的值是非数字,那么必须赋值

布尔类型

const g: boolean = true;

对象


const i: object = {};

undefined

常用于组合类型

let j: number | undefined;

null

let k: null;

void

指定方法类型,表示没有返回值,方法体中不能return

function aa(): void {
  console.log(1);
}

//如果方法有返回值,可以加上返回值的类型
function bb(): number {
  return 1;
}

never

其他类型 (包括null和undefined)的子类型,代表从不会出现的值

let l: never;

//匿名函数并抛出异常
l = (() => {
  throw new Error("111");
})();

任意类型

让参数可以是任何一种类型


let h: any = 1;
h = true;
h = "st";

函数

函数申明

function cc(): void {}

方法传参

function getUserInfo(name: string, age?: number, school: string = "清华大学") {
  return `name:${name}--age:${age}--school:${school}`;
}
tips: ?代表这个参数可传可不传,不传就是undefined,也可定义个默认的值

剩余参数

传递多个时,如果用了剩余参数,就可以把未定义的形参转换为数组。

function sum (a: number, b: number, ...arr: number[]): number {
  let sum: number = a + b;
  arr.forEach((element) => {
    sum += element;
  });
  console.log(arr); [3,4,5]  
  return sum;
}
console.log(sum(1, 2, 3, 4, 5)); //15

函数重载

function reload(name: string): string;
function reload(age: number): string;
function reload(param: any): any {
  return typeof param === "string" ? `我是:${param}` : `我的年龄:${param}`;
}
console.log(reload(18)); //年龄
tips: 被重载的方法,是没有方法体,可以根据参数的类型走其中一个方法并判断参数,但如果传入的参数类型不是任何被重载方法的参数类型就不允许通过。
 第 1 个重载(共 2 个),“(name: string): string”,出现以下错误。
   类型“never[]”的参数不能赋给类型“string”的参数。
 第 2 个重载(共 2 个),“(age: number): string”,出现以下错误。
   类型“never[]”的参数不能赋给类型“number”的参数


class Person {
  // 私有变量
  private name: string;
  
  // 构造函数
  constructor(name: string) {
    this.name = name;
  }
  
  // 获取名字
  getName(): string {
    return this.name;
  }
  
  // 设置名字
  setName(name: string): void  {
    this.name = name;
  }
}

let p = new Person("张三");
p.setName("李四");
console.log(p);

继承

class Son extends Person {
 // 静态属性
  public static age: number = 18;
  // 学校
  public school: string;
  //构造方法
  constructor(name: string, school: string) {
    // 访问派生类的构造函数中的 "this" 前,必须调用 "super",初始化父类构造函数 --并把参数传给父类
    super(name); 
    //把传进来的school赋值给全局变量
    this.school = school;
  }
  //静态方法
  static run(name: string): string {
    return `${name}在跑步,他的年龄才${this.age}`;
  }
}

let son = new Son("王五", "清华大学");
son.setName("赵六"); // 私有类也不能在子类的外部访问,但可通过公开的方法中进行赋值和访问
console.log(son);
console.log(Son.run("方七"));
console.log(Son.age);

tips:

  1. public 在当前类里面,子类,类外面都可以访问
  2. protected 在当前类和子类内部可以访问,类外部无法访问
  3. private 在当前类内部可访问,子类,类外部都无法访问。
  4. 属性不加修饰符,默认就是公有的 (public)

多态

通过抽象方法/方法重载--实现多态--多态的作用是用来定义标准

// 抽象父类
abstract class Animal {
  private name: string;
  constructor(name: string) {
    this.name = name;
  }
  //抽象成员--方法
  abstract eat(): any;
  //抽象成员--属性
  protected abstract ages: Number;
  sleep(): void {
    console.log("睡觉");
  }
}

class cat extends Animal {
  ages: Number = 2;
  constructor(name: string) {
    super(name);
  }
  //非抽象类“cat”不会自动实现继承自“Animal”类的抽象成员“eat”,  必须手动定义父类中的抽象方法--多态
  eat(): string {
    return "猫吃鱼";
  }

  //多态
  sleep(): string {
    return "猫在睡觉";
  }
}

console.log(new cat("33").sleep());

tips:

  1. 抽象类无法实例化
  2. 非抽象类继承抽象父类时不会自动实现来自父类的抽象成员,必须手动定义父类中的抽象成员,否则报错。
  3. 抽象成员包括属性方法

接口

  在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,

  在程序设计里面,接口起到一种限制和规范的作用。

  接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可以满足实际需要。ts中的接口类似于java,同时还增加了更灵活的接口类型,包括属性、函数、可索引和类等。

属性接口

interface InterfaceName {
  first: string;
  second?: string; //加个问号,接口属性就可以变成可传可不传了,不传默认是undefined。
}
//打印变量
function logParam(name: InterfaceName): void {
  console.log(name.first, name.second, 11);
}
//定义参数
const obj = { first: "1", second: "fff", three: 1 };
//logParam({ first: "1", second: "1", three: 1 }); //报错,只能传接口定义的值
logParam(obj);
tips: 用个变量来存储传入的变量,这样可以传入定义的接口以外的值,否则如果直接传入对象中无接口定义的值会报错,所以建议接口定义了哪些值就传哪些值。

函数类型接口

对方法传入的参数类型,以及返回值类型进行约束,可批量进行约束。

interface keyMap {
  (key: string, value: string): string;
}
let logKeyMap: keyMap = function (key1: string, value: string): string {
  return key1 + value;
};
console.log(logKeyMap("key1", "value"));
tips: 接口只对传入的参数的类型和参数的个数进行约束,不对参数名称进行约束。

可索引接口

  • 约束数组
interface Arr {
  [index: number]: string;
}
let ss: Arr = ["2121"];
  • 约束对象
interface Obj {
  [index: string]: string;
}

let interfaceArr: Obj = { aa: "1" };

tips:

  1. 数组进行约束,index后必须跟着number类型。
  2. 对象进行约束,index后必须跟着string类型
  3. 索引签名参数类型必须为 "string" 或 "number"

类类型接口

  • 进行约束,类似抽象类的实现。
interface Animals {
  name: string;
  eat(): void;
}

class Dogs implements Animals {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  eat() {}
}
  • 接口继承--接口可以继承接口
interface Dog {
  eat(): void;
}

interface Persons extends Dog {
  work(): void;
}

class Cat {
  code() {
    console.log("猫在敲代码");
  }
}

//可继承类后再实现接口
class SuperMan extends Cat implements Persons {
  eat(): void {
    console.log(1);
  }
  work(): void {
    console.log(2);
  }
}
let superMan = new SuperMan();
superMan.code();
tips: 类接口会对类的属性方法进行约束,类似非抽象类继承抽象类时必须实现某些方法和属性,但对属性和方法的类型的约束更加严格,除了方法void类型可被重新定义外,其他属性或方法的类型定义需要和接口保持一致。

泛型

  软件工程中,我们不仅要创建一致的定义良好的api,同时也要考虑可重用性。
组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能

   泛型就是解决接口方法复用性,以及对不特定数据类型的支持。

  要求:传入的参数和返回的参数一致

函数的泛型

function getDate<T>(value: T): T {
  return value;
}
console.log(getDate<number>(123));
tips: 这里的T可改成其他任意值但定义的值,和传入的参数以及返回的参数是一样的,一般默认写法是T,也是业内规范的选择。

类的泛型

class MinClass<T> {
  public list: T[] = [];
  //添加
  add(value: T): void {
    this.list.push(value);
  }
  
  //求最小值
  min(): T {
    //假设这个值最小
    let minNum = this.list[0];
    for (let i = 0; i < this.list.length; i++) {
    //比较并获取最小值
    minNum = minNum < this.list[i] ? minNum : this.list[i];
    }
    return minNum;
  }
}
//实例化类 并且指定了类的T的类型是number
let minClass = new MinClass<number>(); 
minClass.add(23);
minClass.add(5);
minClass.add(2);
console.log(minClass.min());
 //实例化类 并且指定了类的T的类型是string,则其方法的传参和返回都是string类型
let minClass2 = new MinClass<string>();
minClass2.add("23");
minClass2.add("5");
minClass2.add("2");
console.log(minClass2.min());

接口的泛型

  • 第一种写法
interface ConfigFn {
  //规范参数类型,返回值类型
  <T>(value: T): T;
}

let getData: ConfigFn = function <T>(value: T): T {
  return value;
};

console.log(getData<string>("z11"));
  • 第二种写法

interface ConfigFn<T> {
  //参数类型 ,返回值类型
  (value: T): T;
}

//接口方法
function getData<T>(value: T): T {
  return value;
}

//使用接口
let myGetDate: ConfigFn<string> = getData;
console.log(myGetDate("3"));
tips:接口的泛型只针对函数类型的接口

类当做参数传入泛型类

//用户类--和数据库表字段进行映射
class User {
  username: string | undefined;
  password: string | undefined;
  //构造函数-初始化参数
  constructor(param: {
    username: string | undefined;
    password?: string | undefined;
  }) {
    this.username = param.username;
    this.password = param.password;
  }
}


//数据库类
class Db<T> {
  add(user: T): boolean {
    console.log(user);
    return true;
  }
  updated(user: T, id: number): boolean {
    console.log(user, id);
    return true;
  }
}

let u = new User({
  username: "张三",
});

//u.username = "李四";
u.password = "111111";
let db = new Db<User>();
db.add(u);
db.updated(u, 1);
tips: 类的参数名和类型都做了约束。

模块

  内部模块称为命名空间,外部模块简称为模块,模块在其自身的作用域里执行,而不是在全局作用域里;

  这意味着定义在一个模块里的变量、函数、类等等在模块外部是不可见的,除非你明确的使用export形式之一导出它们。

  相反,如果想使用其它模块导出的变量,函数,类,接口等的时候,你必须要导人它们,可以使用import形式之一。

  我们可以一些公共的功能单独抽离成一个文件作为一个模块。
模块里面的变量、函数、类等默认是私有的,如果我们要在外部访问模块里面的数据(变量、函数、类)
我们需要通过export暴露模块里面的数据(变量、函数、类...)。
暴露后我们通过import引入模块就可以使用模块里面暴露的数据(变量、函数、类...)

//modules/db.ts
function getDate(): any[] {
  console.log("获取数据");
  return [
    {
      userName: "张三",
    },

    {
      userName: "李四",
    },
  ];
}

//一个模块里面可以用多次
// export { getDate };
//一个模块里面只能用一次
export default getDate;
 import { getDate as getDbDate } from "./modules/db";
 import getDbDate from "./modules/db";
 getDbDate();
tips: 这个调试时浏览器中不能直接使用,可在nodeweakpack的环境中调试。

命名空间

  在代码量较大的情况下,为了避免各种变量命名相冲突,可将相似功能的函数、类、接口等放置到命名空间内
TypeScript的命名空间可以将代码包裹起来,只对外暴露需要在外部访问的对象。

   命名空间和模块的区别

  • 命名空间:内部模块,主要用于组织代码,避免命名冲突。
  • 模块:ts外部模块的简称,侧重代码的复用,一个模块里可能会有多个命名空间。
 // modules/Animal.ts
export namespace A {
  interface Animal {
    name: String;
    eat(): void;
  }

  export class Dog implements Animal {
    name: String;
    constructor(theName: string) {
      this.name = theName;
    }
    eat() {
      console.log("我是" + this.name);
    }
  }
}

export namespace B {
  interface Animal {
    name: String;
    eat(): void;
  }

  export class Dog implements Animal {
    name: String;
    constructor(theName: string) {
      this.name = theName;
    }
    eat() {}
  }
}
 import { A, B } from "./modules/Animal";
 let ee = new A.Dog("小贝");
 ee.eat();

装饰器

  • 类装饰器:类装饰器在类申明之前被申明(紧靠着类申明),类装饰器应用于类构造函数,可以用于监视,修改或者替换类定义。
function logClass(params: any) {
  console.log(params);
  //params 就是指代当前类--HttpClient
  params.prototype.apiUrl = "动态扩展属性";
  params.prototype.run = function () {
    console.log("动态扩展方法");
  };
  params.prototype.getDate = function () {
    console.log("动态扩展方法2");
  };
}

@logClass
class HttpClient {
  constructor() {}
  getDate() {
    console.log(1);
  }
}

let http: any = new HttpClient();
console.log(http.apiUrl);
http.run();
http.getDate();
tips: 装饰器会覆盖被装饰的类中的方法。
  • 装饰器工厂

可传参的装饰器


function logClassB(param: string) {
  return function (target: any) {
    console.log(target, "装饰器以下的类");
    console.log(param, "装饰器传进来的属性");
  };
}

@logClassB("小慧")
class HttpClients {
  constructor() {}
  getDate() {}
}

let https: any = new HttpClients();
console.log(https);
  • 构造函数装饰器
function logClassC(target: any) {
  console.log(target, 1111);
  //用在这里继承目标类并重载方法和属性
  return class extends target {
    a: any = "我是修改后的属性";
    getDate() {
      console.log(this.a + "--装饰器中的方法输出的");
    }
  };
}

@logClassC
class HttpClient2 {
  public a: string | undefined;
  constructor() {
    this.a = "我是构造函数里面的a";
  }
  getDate() {
    console.log(this.a);
  }
}
const https2 = new HttpClient2();
https2.getDate();

未完待续~

下期预告:在vue中使用ts。

查看原文

赞 23 收藏 17 评论 2

菜小胖 赞了文章 · 9月24日

免费领!500份大厂P7面试题免费送!!

金九银十,秋招,面试季

思否编程助你一臂之力

小编精心收集了大厂面试题 

#敲重点#

所有面试题免费送

#面试交流群#

关于面试那些事儿

不定期的岗位推荐

内部福利

等你一起来见证

本期面试题关于阿里P7

请持续关注我们

大厂面试题陆续与你相见

让你与大厂快人一步

# 活动时间 #

2020 年9 月 24 日 12:00

2020 年 9 月 30 日 24:00

# 活动规则 #

关注公众号,即刻领取

仅限500份

image

                     更多精彩内容请添加HR小姐姐

查看原文

赞 5 收藏 2 评论 9

菜小胖 赞了文章 · 9月23日

AWS 人工智能黑客马拉松决赛结果出炉!22 个队伍激烈角逐,谁才是最后赢家?

AWS 人工智能黑客马拉松决赛结果出炉!22 个队伍激烈角逐,谁才是最后赢家?

SegmentFault 特别支持的 Amazon Web Services (AWS) Hackathon Online 2020 已经圆满落幕。

7 月 27 日起,AWS Hackathon Online 2020 正式启动,来自全球各大企业和高校的编程爱好者参加本次黑客马拉松,他们围绕遗失宠物的智能寻找、老年人的远程智能诊疗、环境污染的预测、餐厅及后厨卫生安全的自动监测、登山爱好者的智能追踪与安全保障五大赛题,结合 Amazon SageMaker 模型和 AWS SDK 提交了众多优秀作品。

经过层层筛选后,突出重围的 22 组选手,在历时近两个月的比赛后,终于在 9月20日 的决赛场上决出胜负。

8 位 AWS 专家评委从赛题完成度、创意度、实用性、用户体验、商业前景、技术难度 6 个维度对选手的作品进行综合考量,最终评选出了 3 组优胜选手。

image.png

22 个队伍激烈角逐,冠军花落谁家?

参赛队伍结合 Amazon SageMaker,训练并部署了自己的机器学习模型,通过 AWS SDK 本地调用线上模型,为自己的作品带来独特的优势。

WechatIMG4158.png

这 22 组选手中,有 10 组选择了遗失宠物的智能寻找赛题,有 5 组选择了老年人的远程智能诊疗赛题,有 4 组选择了环境污染的预测赛题,有 2 组选择了餐厅及后厨卫生安全的自动监测赛题,有 1 组选择了登山爱好者的智能追踪与安全保障赛题。

每组选手分别展示了自己的作品后,专家评委从作品的技术原理、项目独创性和商业价值等角度进行了提问,经过评委们专业的分析和讨论,最终选出了 3 组获胜队伍。

第一名 【SW】 团队:他们的“遗失宠物的智能寻找”作品摘得了冠军,获得了 AWS 提供的 5000 元云服务抵扣券和 AWS DeepRacer 自动驾驶电动车。

第二名【Excelsior】团队:他们的“智能老年医疗”作品获得第二名,赢得了 3000 元 AWS 云服务抵扣券和支持深度学习的摄像机 AWS DeepLens。

第三名【对不对】团队:该团队作品“狗不离”,获得了 3000 元 AWS 云服务抵扣券和树莓派开发套件。

此外,所有参与比赛提交了作品的队伍,都获得了 AWS 限量版定制T恤。

WechatIMG4159.png

专家点评,为选手提出项目落地建议

比赛结束后,评委代表 AWS Senior Developer Advocate 王宇博老师根据选手的表现,从以下四个方面做了总结:

一、AWS 设计的 5 个赛题都关注了在不同场景中 AI 是如何落地的,未来建议选手们应该从更宏观的维度上看待每个赛题。

二、一场 Hackathon 不仅是个比赛,也在为更好的 AI 项目落地打基础,为选手们提供实践经验,项目的完成度越高越有利于作品的展示。

三、现在我们看到的很多 AI 落地项目和云计算的推动是分不开的,AWS 等云计算厂商在云端推出产品是为了方便开发者在云端开发出机器模型构建产品,希望大家在具体的实践中了解 AWS 产品的特点,未来更好的应用到 AI 项目落地中。

四、AWS Hackathon Online 2020 并没有规定比赛中选手必须使用哪些数据集,希望大家能更多关注数据集的特点,做到举一反三,在 AI 项目中做出更好的表现。

image.png

AWS 专家评委费良宏老师也对本次大赛各组选手的表现进行了点评,费老师认为各组选手对机器学习、对人工智能的兴趣和能力都在这次比赛中得到了很好的体现。对获奖的前 3 组选手,费老师也逐一点评,具体如下:

第三名的获奖作品“狗不离”凭借这个独特的作品名更好的体现了自己的作品,在整个项目的讲解中,无论是前端、后端还是算法部分都实施的非常完整。

获得第二名的“智能老年医疗”作品给费老师留下了很深的印象,他认为这个团队对医疗影像的引用能帮助老年人医疗健康工作取得更好的结果,他还坦言,“希望这样的作品越来越多,让我们的生活变得越来越好。”

对于获得第一名的作品“遗失宠物的智能寻找”,费老师更是给出了很高的评价,他说,这个项目完整的涵盖了前端、后台,以及 AWS 服务的调用,它的代码完整度非常高,可用性也很高,只要简单优化后就可以应用到现实当中。费老师还补充道:“Amazon SageMaker 帮助参赛团队在短时间内建立了比较完善的模型,这也是第一名团队能在这次比赛中获得胜利的一个重要原因。”

最后,费老师说:“除了获奖的三个作品,其他很多团队的作品都给我们留下了很深的印象,希望未来大家可以把更多更好的想法注入到自己的项目中去,也希望人工智能可以让我们的生活变得更好。”

用实力演绎科技向善

随着物联网、云计算、大数据等技术的飞速发展,人工智能已不仅仅是个概念,有了越来越多的落地项目。以 AWS Hackathon Online 2020 为例,老年人远程医疗、户外运动智能追踪、遗失宠物智能寻找、环境污染监测和食品安全监测等涉及社会生活方方面面的场景都成为了 AI 落地的重要战地。

AWS 举办本次大赛的初衷也是“科技向善”,希望未来有越来越多的科技开发者参与到这类赛事中,共同为创造更好的社会环境、更健全的社会体系贡献一份力量。

福利来啦!!!AWS 为机器学习应用提供专属福利,1000 元人民币/200 美元服务抵扣券直充到 AWS 账户,让你轻松体验 Amazon SageMaker 服务,赶紧扫描下方二维码领取吧!

image.png


SegmentFault 作为最早把黑客马拉松引入中国、中国最大的 Hackathon 组织者,在大陆、香港、台北、新加坡、美国硅谷等地参与或举办了上千场 Hackathon,覆盖了数万名 Hackers。如今我们将成熟的 Hackathon 组织经验提炼和升华,面向企业定制以推动技术创新为目的的企业内/外部技术竞赛 / Hackathon,希望更多企业和开发者可以参与进这场创新的革命,一起 Make Things Happen!

技术内训/技术活动合作:marketing@sifou.com

segmentfault 公众号

查看原文

赞 7 收藏 0 评论 0

菜小胖 赞了文章 · 9月22日

100+队伍逐鹿大奖,创新编程挑战赛秋季赛圆满落幕

就在上周末,SegmentFault 思否策划承办的RTE 2020 编程挑战赛秋季赛的决赛在线上圆满落幕了。本次秋季赛的赛题只有一个,参赛者可以根据自己的创意,基于声网Agora SDK、 声网Agora 实时消息 RTM SDK、云录制 SDK 等 SDK 实现实时互动应用,或在已有的项目中实现实时互动场景。

相对春季赛,尽管赛题减半,但参赛选手热情不减,仅一个赛道便有近 260 名开发者报名参赛,组成了 100+队伍,最终 20 个作品进入决赛答辩。

与春季赛一样,这次的决赛和颁奖都是通过 Agora Video Call App 在线上进行的,同时通过 B 站全程对外直播。

最终,决赛一共产生了一、二、三等奖各一支团队,还有两支团队分别获得了最佳创意奖和最佳实用奖。

获奖名单:


一等奖:Storyteller

二等奖:AR Assistance

三等奖:Codesync

最佳创意奖:Touch Fish Artifact

最佳实用奖:Post-it Notes

下面让我们一睹获奖作品的风采!

一等奖:Storyteller


这是一个交互式 Demo 的编辑器,借助了声网Agora SDK 的能力,实现了多人实时协同编辑以及云端录制音视频。

       

在传统的教学视频中,都会演示很多交互的步骤,比如完成某一步后点击哪个按钮,接着输入代码等。相对于其他演示 Demo 的方式的优缺点,参赛者也做了对比:       

Storytell 无需编写代码,任何人员可以使用,支持多人协同,而且可为交互式 Demo 添加多种特效。另外,基于声网 Agora 录制 SDK,还可以在为演示 Demo 录制以视频旁白。 

二等奖:AR Assistance


获得第二名的团队中有一位开发者有多年的 AR 互动软件开发经验,并有多款 AR 应用和 Kinect 交互应用上线。所以这次他们的作品就是将 AR 与 RTC 结合到了一起,做了一个 AR Assistance。

AR Assistance 主要是为了进行实时远程协作而开发的。例如,当一些硬件设备出现故障的时候,往往需要有工程师或专家亲自跑过去现场进行指导或技术支持。

而通过 AR + RTC,则可以进行远程的辅助作业。除了可以进行视频交流,还可以通过 AR 在视频中实时标注出问题所在。

所以在这个作品中,他们不仅应用了声网 Agora SDK,还通过图像识别技术,定位并截取指定区域,对该区域进行点对点标注。 

三等奖:Codesync


在教学过程中,我们经常会看到投影。但当要演示代码,讲解其中一些关键点的时候,投影的问题就变得很明显了。分辨率低、字号小,只要学生做得考后,就很难看清。所以他开发了 Codesync 。

        

Codesync 是一个 VS Code 插件,单击右键菜单内的一个“开始代码同步”按钮,就可以利用声网Agora RTM SDK 的能力,实时将老师在 IDE 中修改的内容同步展示到 Web 浏览器端。同时,该插件会生成一个房间号和二维码,学生扫码或用房间号就可以加入房间,看到老师的操作。而且,学生在房间内还可以发送弹幕,实时交流。

最佳创意奖:Touch Fish Artifact


这个作品创意,源自于很多人日常都在做,却又不会公开承认的一件事——摸鱼。应用的首页为一个简单的lottie鱼游动的动画,点击任意位置进入主页面。然后,你就会进入一个视频会议,在这里正式进入“摸鱼”状态。

因为在这个九宫格显示的视频窗口里,除了你以外,其它的视频图像都是提前录好的。当你在这个状态下输入 B站或腾讯视频的网址后,你可以在右上角的视频窗口中浏览网页。(温馨提示,如果输入“Agora”,还会有彩蛋)

最佳实用奖:Post-it Notes


这个创意是源于在线上课记笔记而产生的。参赛团队基于声网 Agora SDK 开发了一个支持截图记笔记、点击查单词的在线课堂+笔记应用。这个应用分为学生端和教师端。教师可以在上课的时候分享屏幕。学生可以在上课时随时截图,并在图上标注笔记。

下课后,观看课程回放的时候,屏幕右侧会显示之前记下的笔记截图,点击截图,就会自动跳转到当时的课程画面。

以上就是本届 RTE 2020 编程挑战赛秋季赛的获奖作品及团队。

SegmentFault 思否 CTO 祁宁表示:这是我第二次作为评委参与到声网的编程挑战赛,这一次选手们的切入点都非常广泛,而且大多数作品的完成度都非常高。大家都利用了声网提供的强大的实时通讯能力,有些作品还结合了时下社会热点,是真真正正奔着解决问题而去的。祝贺那些取得好成绩的队伍,也期待他们能继续打磨产品。

获奖团队除了会得到本季度大赛奖金,还可以申请进入声网应聘快速通道。参与大赛的创业团队,还可通过声网Agora官网“400-6326626”咨询电话申请加入“Agora创业支持计划”(需保证使用声网产品的分钟数用量高于10000分钟/月)。

本次挑战赛的作品将开源在 Github:

https://github.com/AgoraIO-Co...

9 月 26 日,RTE 2020 算法挑战赛的决赛也将在线上举行,声网将在本周预告直播。关注深度学习、计算机视觉的小伙伴不要错过哦。


作为大赛的策划和承办方,SegmentFault 连续组织了声网春秋两季的编程挑战赛,即 RTC 2020 Innovation Challenge 编程挑战赛秋季赛,RTE 2020 Innovation Challenge 编程挑战赛秋季赛。

从开发者的角度,技术竞赛能够很大程度让开发者从日常任务中脱离出来,回归初心,通过动手打破现实系统的束缚,将创新想法变成现实。

SegmentFault 作为最早把黑客马拉松引入中国、中国最大的 Hackathon 组织者,在大陆、香港、台北、新加坡、美国硅谷等地参与或举办了上千场 Hackathon,覆盖了数万名 Hackers。如今我们将成熟的 Hackathon 组织经验提炼和升华,面向企业定制以推动技术创新为目的的企业内/外部技术竞赛 / Hackathon,希望更多企业和开发者可以参与进这场创新的革命,一起 Make Things Happen!

技术内训/技术活动合作:marketing@sifou.com

segmentfault公众号

查看原文

赞 17 收藏 2 评论 2

菜小胖 赞了文章 · 9月11日

鸿蒙智能硬件生态的“场景化超级终端”,到底是什么?

harmonyOS

物联网(IoT)的概念我们其实已经非常熟悉了,近些年物联网设备的飞速增长说明整个行业正在呈现一个爆发性发展的趋势。但 IoT 产业的快速发展即带来了巨大的机会,也迎来了巨大的商业和技术挑战。

为了解决这个挑战,华为提出要与生态伙伴一起共建“场景化的超级终端”。单从名字我们可能看不出来什么信息,但在本次的 HDC 大会的一场分论坛中,华为消费者 BG 软件部副总裁杨海松为我们给出了他的答案。

一、万物互联时代: 有机会、有空间、有挑战

在 5G 技术真的有实质性进展之前,一个不得不直面的现实是 —— 几乎所有的传统物联网或者智能硬件产业,发展都已不断接近天花板。

无论是硬件还是软件,无论是市场还是技术,人口红利的消耗勉强靠着全球市场扩张和新型应用功能的不断迭代来维持。但客观上已经不可避免的放缓了发展的脚步。

随着 5G 技术的逐渐成熟与落地,IoT 产业才迎来了又一次的快速发展。

“有机会、有空间,同时有挑战。”

这是杨海松对这件事情的理解,在分享中他也和我们分享了一组数据:根据 Statista 的资料显示,从 2015 年到 2025 年,人均智能设备的数量预期将从 2.09 台飙升到 9.27 台,也就是说除了手机、电脑、Pad 这新三大件之外,其他的智能设备也将逐步进入我们的生活。

这对 IoT 产业来说当然是个乐观的发展前景,未来十年也将是硬件创新非常好的机遇与发展空间。但杨海松也提出 —— 这个数字背后,其实是不断增加的硬件种类与系统下,有限的开发投入、复杂割裂的多设备使用体验,以及缺乏成熟商业模式所带来的巨大挑战。之前这个行业之所以没发展起来,还有一个很重要原因就是生态、体验、以及商业的割裂。

相对于单一的手机场景,在万物互联的时代,无论终端、业务、用户、还是其他的各种产业要素,都将呈现高度的碎片化与个性化。在各种不同的垂直业务场景下,用户对产品和服务的需求都将存在巨大差异,将这个差异放大到产业链来看则更为复杂。

以手机为例。传统的功能机搭配的软件功能和硬件能力都是固定的,发展到智能机后,软件功能得以进行丰富的扩展。那么在未来,我们手中的“手机”有没有可能变成一种“智能终端”,让软硬件都能具备扩展能力,从而满足不同用户的个性化需求?

“消费者的需求是开发产品的源动力。”很多人都认为是 5G 的发展催生了物联网的发展,但其实不然。杨海松认为改变行业的永远都不是技术,而是需求。为了解决 IoT 领域面临的挑战、满足更多用户的需求,华为提出要围绕 7 大场景,与生态伙伴一起共建“场景化的超级终端”。

二、超级终端的定义“公式”

杨海松在会上对这个超级终端提出了一个公式定义:场景化超级终端 = 核心硬件 + HarmonyOS + 核心应用

从这个公式中我们不难看出,华为的超级终端其实就是一条相对完整的生态链,从硬件到系统到应用,只有覆盖了这些完整的能力才能称之为“超级终端”。

终端对应的七大场景,分别是:智能家居、智慧出行、社交购物、智慧教育、影音娱乐、移动办公和运动健康。

现阶段,这些场景分别对应着不同的硬件设施,比如在 9 月 10 日 HDC 大会中提到的由智能手表承载的智慧出行能力,由不同的大屏间联动赋能的智慧教育等。这些硬件设备承载着不同使用场景的核心应用,在不同的方向和领域优化用户的使用体验。

但目前各种应用和硬件之间有一个很大的问题,就是生态的割裂。

早在 1995 年,比尔·盖茨在《未来之路》一书中,便提出了物联网的概念。当时他做出的一个设想基本命中了 25 年后的物联网发展:未来的住宅应该具备智能家居系统。

但他当时只想到了产品的形态,可能并没有想到物联网时代的超级终端之所以称之为超级终端,还需要有一个完整的生态来支持。不断推进自身能力迭代的 HarmonyOS,可能正是这中间承上启下最为关键的一环。

杨海松在会议中分享到,目前智能设备领域有三个最主要的痛点,“连不上、用不了、留不住”。展开来讲就是设备入网率低、平均 App 安装率低、智能特性用户使用率低,这些问题很大程度上都是生态割裂导致的。

HarmonyOS 有一项能力叫无感配网,通过降低用户联网的繁复操作,解决智能硬件入网率低的问题;FA+ 手机系统的入口,则可以解决设备 App 安装率低导致的设备或者应用沉寂。我们刚才提到的等等问题,看起来都在 HarmonyOS 所预定的能力范围之内。

本次 HDC 2020 上余承东正式宣布 HarmonyOS 将于今年 12 月推出面向手机的 beta 版本,2021 年将发布第一款搭载 HarmonyOS 手机。根据杨海松所说,第一款鸿蒙手机在各位用户手中的硬件形态将会是不一样的,而这个不一样,可能就体现在和其他智能硬件通过 HarmonyOS的生态融合当中了。

三、鸿蒙智能硬件生态发展规划:一横一纵&双赋能

IoT 领域中各种发展因素的迭加,注定了万物互联不但将激发出一个前所未有的庞大市场,也注定不是一家或几家企业便能解决的问题。未来的万物互联,将更加立体全面,既没有人能全盘通吃,也没有人能置身于事外。

华为深谙这个道理,早在去年就提出了 1+8+N 的战略。这当中的 1 指的便是我们手里的智能手机。

手机是未来智慧生活的入口,从目前来看,多数智能家居的生态链,一般都会以手机为核心。为什么会这样?因为手机是最为普及的智能硬件,基本已经达到了人手一部。

在万物互联的世界中,每一台手机其实都可以看做是一个活生生的人,承载的是发于人的需求。我们发展物联网的原因,其实也是希望以人为核心,让人与万物互联,从而为人赋予更强大的能力。

但杨海松在会议中提出了一个思考题:“手机可以替代相机、替代mp3、录音机,但是能灭掉跑步机、可穿戴设备么?”

答案他也给出来了,不能。

实现真正的万物互联,需要从手机延伸出去,扩展到智能家具、扩展到全场景当中。因此,鸿蒙智能硬件生态发展规划「一横一纵」中「一横」,便是横向的从智能家居扩展到全场景。杨海松表示鸿蒙生态将覆盖 7 大场景核心智能设备,建立全场景鸿蒙精品设备圈,并提出了 1 年内让华为鸿蒙设备规模达到 2 亿的目标。

而「一纵」则是纵向的从品牌厂家扩展到全产业链,鸿蒙硬件智能生态将联合芯片、模组、IDH、品牌厂家、服务商,快速打造鸿蒙生态产业链,1 年内让鸿蒙生态设备规模超过 1 亿。

这加起来就是 3 亿台设备,听起来有些难以实现,但结合 5G 和物联网的发展速度与规模来看,也不是没有可能。但如果想要实现这个目标,一定离不开智能硬件伙伴的帮助。

为了发展鸿蒙生态,华为在芯片、模组、开发板、解决方案等领域已经找到了很多合作企业,并为致力于加入鸿蒙生态、发展鸿蒙生态的朋友提供了技术和商业的“双赋能”,解决商业变现的“最后一公里”。

结语

物联网的发展其实仍处于战国的蛮荒发展时代,眼前的局势其实并不是十分的明朗。从简单的单一场景入网,到形成产业规模效应、形成一个完整、完善的生态,仍需要一个长远的产业协同过程。华为已经开始眺望远方的可能,付出实际行动,并见到了一些成效。

但前路唯艰,道阻且长。

“有机会、有空间、有挑战”,随着技术的发展,20 年前比尔盖茨的技术幻想已经成为了现实。我们今天对于物联网的期待、对于鸿蒙生态的期待,要等多久呢?

这个问题可能华为自身都给不出一个确切的答案。

但正如今年 HDC 大会的后缀「together」所传递的信息,携手、并肩前行,才是面对未来挑战的正确方式。

这里的「together」,既包括鸿蒙生态链条中上下游的合作伙伴,应该也包含期待未来的每一个人吧。

clipboard.png

查看原文

赞 10 收藏 0 评论 0

菜小胖 赞了文章 · 9月11日

开放与拥抱丨HMS 要打破垄断,让开发者与平台平等对话 !

HDC2020

华为在本次 HDC 大会上提到 HMS 时,使用频率很高的两个词是“开放”、“拥抱”,这两个词显示出了华为希望通过与全球合作伙伴和开发者携手,通过 HMS 生态提供能力和服务的决心。

根据华为公开的数据,截至目前,HMS 的全球注册开发者数量已经超过了 180 万,有 9.6 万以上的应用集成 HMS Core。提到这些数据时,华为消费者业务全球生态发展部总裁汪严旻说:“全球第三大移动应用生态正在破土而出。”

让开发者与平台平等对话

想要 HMS 短时间内进入大众,与苹果和安卓两大巨头三分市场是很难做到的,对于这一点,汪严旻也很坦诚的说到:

“过去的十几年里面,整个移动应用生态已经被垄断了很多年了,这一点我们在物理世界很敏感,大家没有选择,只能选择一个供应商,可能也会觉得很不爽,其实数字世界里面应用和内容也是一种垄断,这种垄断大家都希望被打破,所以我们在今天生态发展里面,我们强调我们的目标就是能够给广大的应用开发者、内容开发者、合作伙伴以及消费者提供更加公平的、多元化的、可信赖的生态选择。”

为了打破现有的格局,华为贯彻的准则是把更多利益分享给开发者,这也是华为打破苹果和安卓两大巨头垄断的一种策略。汪严旻提到了苹果、谷歌对平台内应用抽成高达 30% 的例子,他认为在这样的情况下,中国的开发者永远不可能与他们有平等的对话机会。HMS 要做的就是建立一个新的生态,可以更加公平、开放,也能让消费者更加信赖。

HDC2020g

HMS 的目标是能三分天下有其一

在消费者已经习惯了使用一种移动应用生态的时候,后入局者想要在短时间与之形成分立是很难的。华为也意识到了这个难题,汪严旻从三个方面总结了 HMS 目前面临的主要挑战。

一是如何让消费者在短时间内接受一个新的东西,这需要让头部应用尽可能的商家,和 HMS 平台进行集成开发。

二是低频刚需应用这个硬骨头,很多应用并不是头部应用,使用频率也很低,比如购买车票、机票的应用,一年可能只用几次,但却是刚需,这在 HMS 的全球生态建设中也是必不可少的。

第三,也是最重要的一点,就是在一些平台级的应用上,华为还在进行探索,积极追赶,比如搜索、地图、广告这些根应用的服务能力的提升。

从长期来看,HMS 的目标是能三分天下有其一,做到跟其他两个应用生态相当的水平。这需要整个生态能做到自我循环,从获客、增长、运营到面向,产品的设计能有一个系统自我运作完成。

汪严旻说,华为下一步的计划是首先把基础服务工作做好,把 Open line、digital line,还有包括线下全球开发者服务中心这些基础能力做好。同时构建围绕开发者的界面,包括论坛、线上线下活动等等。

与中国开发者共同进军海外

HDC2020

汪严旻提到了一个数字“38%”,这是中国开发者目前在 Google Play 和 iOS 上贡献的占比,其实从这个角度来讲,中国开发者早就三分天下有其一了,中国开发者是未来移动生态最重要的开发的力量。所以,汪严旻提出,即使做海外生态,也要更多的和中国开发者一起,把应用内容发布到海外。

现阶段 HMS 要做的,是把“基本可用”变成“好用”,这个变化涉及到两个关键点,分别是低频刚需应用要全和内容必须足够丰富。对于目前缺失的 20% 的头部应用,汪严旻说,会尽快找到替代应用,也鼓励中国应用到海外当地发展。


随着中国移动应用出海走入深水区,语言转化、法律合规、本土推广等本土化壁垒,逐渐成为挑战。而华为自身的全球化实践和经验能够帮助开发者和合作伙伴克服种种挑战。

汪严旻表示“我们坚信,每一位开发者,都是重要的合作伙伴。点点星光汇聚,便是璀璨银河。只有与开发者共同成长,才能最终打造可信赖的开放生态,为用户提供多元化创新体验。”

期待在未来,华为与全球合作伙伴和开发者携手,共建一个全场景的智慧生态。

segmentfault 思否

查看原文

赞 10 收藏 0 评论 0

菜小胖 赞了文章 · 9月10日

连接无限可能,华为 HarmonyOS 2.0 正式发布

今天(2020年9月10日),华为消费者业务 CEO 余承东又一次站在了松山湖华为开发者大会的主舞台上。今年,他带来了万众瞩目的华为鸿蒙 HarmonyOS 2.0。此次 HarmonyOS 的升级,不仅仅包括了分布式能力的全面提升,还为开发者提供了完整的分布式设备与应用开发生态,使能全场景智慧生态,引领移动产业的下一个 10 年。

开发者

三大核心能力升级,HarmonyOS 2.0为开发者掌灯

去年推出的 HarmonyOS 1.0 版本,验证了终端分布式技术的可行性,这一技术也被应用到 EMUI 中,创新出多屏协同、畅连视频通话、华为 HiCar 等跨终端体验。HarmonyOS 2.0 则在分布式软总线、分布式数据管理和分布式安全三方面进行了全面提升。

分布式软总线让多设备融合为“一个设备“,带来设备内和设备间高吞吐、低时延、高可靠的流畅连接体验。分布式数据管理让跨设备数据访问如同访问本地,大大提升跨设备数据远程读写和检索等性能。

分布式安全确保正确的人、用正确的设备、正确的使用数据。当用户进行解锁、付款、登陆等行为时系统会主动拉出认证请求,并通过分布式技术可信互联能力,协同身份认证确保正确的人;HarmonyOS 能够把手机的内核级安全能力扩展到其他终端,提升全场景设备安全性,通过设备能力互助,共同抵御攻击,保障智能家居网络安全;HarmonyOS 通过定义数据和设备的安全级别,对数据和设备都进行了分类分级保护,确保数据流通安全可信。

赋能设备厂商,HarmonyOS 用软件定义新设备

当前,智能家居设备大多数面临联网率低、APP 安装率低、服务触达率低三座大山的困境。但在发布会中我们看到,华为已经与美的、九阳、老板等设备厂商达成了合作,搭载 HarmonyOS 2.0 的智能家居设备为我们带来了不一样的体验。当走进厨房,用手机碰一碰蒸烤一体机,极速设备联网,再也不担心设备不在线;手机碰一下料理机,分分钟实现无屏变有屏,还能结合智能手表,根据运动健康信息智能推荐最佳菜谱;碰一下抽油烟机,服务直达手机,清洗维修一站式服务更无忧……这样的体验,还会担心“智能设备不智能”吗?

面对广大的设备厂商,HarmonyOS 通过 SDK、源代码、开发板/模组和HUAWEI DevEco 等装备共同构成了完备的开发平台与工具链,让HarmonyOS 设备开发易如反掌。设备厂商可以选择不同的方式加入全场景智慧生态:通过使用分布式 SDK,已经有 1200 万+设备,获得畅连、HiCar等7大能力快速接入;此次发布会后,30+ 品类的 128MB 以下 IoT 设备整机也可以使用开源代码接入;对于 128MB 以上、4GB 以下的智能设备整机,HarmonyOS 已经通过申请定向代码开始招募伙伴加入。

为了让 HarmonyOS 智能设备开发者快速上手,HarmonyOS 为其提供了丰富的模组、开发板和解决方案。同时,HUAWEI DevEco 将为 HarmonyOS 设备带来一站式开发环境,支持家电、安防、运动健康等品类的组件定制、驱动开发和分布式能力集成。在用户开发过程中,不论设备是有屏还是无屏,HUAWEI DevEco 都可以为其提供一站式开发、编译、调试和烧录,组件可以按需定制,减少资源占用,开发环境内置安全检查能力,用户在开发过程中也可以进行可视化调试。

为了共建万物互联的全场景智慧生态,HarmonyOS 将源代码捐赠给开放原子开源基金会进行孵化,这一项目就是 OpenHarmony。目前,面向 RAM 在 128KB~128MB 的 IoT 智能硬件源代码已经开放;在明年 4 月前,RAM 在 128MB 到 4GB 间的终端设备,包括平板、低内存手机等在内的设备均可以获得相关的开源代码;到明年 10 月,HarmonyOS 源代码将会面向更多全场景终端设备开放。

应用创新升级,HarmonyOS 打造全新开发体验

应用创新是一款操作系统发展的关键,应用开发体验更是如此。在发布会中我们看到,搭载 HarmonyOS 2.0 之后,许多传统应用在开发者的手中被赋予新生。在办公室开会时,只需打开智慧屏上的 WPS 应用一扫,手机上 PPT 的材料便可快速分享到大屏,还能实时批注和文件分享;想要体验大屏多人体感游戏却苦于没设备?通过 Cocos,只需拿起华为手机便可接入智慧屏游戏,手机秒变手柄,家人同享大屏游戏;上网课屏幕太小?通过智慧屏和平板协同,VIPKid 能够让你大屏上课小屏互动,线上课堂一如现场教学。

image

完整的应用开发生态中,应用框架、编译器、IDE、API/SDK 都是必不可少的。为了赋能开发者,HarmonyOS 提供了一系列构建全场景应用的完整平台工具链与生态体系,助力开发者,轻松构筑全场景创新体验。

分布式应用框架能够将复杂的设备间协同封装成简单接口,可分可合可流转,轻松实现跨设备应用协同。开发者只需要关注业务逻辑,不必关心跨端调度与通信细节,减少代码和复杂度,大幅提升全场景体验开发效率。分布式应用框架 SDK/API 开发者 Beta 版已经同步上线,分步骤提供 13000 多个 API,支持开发大屏、手表、车机等应用。

编译器方面,HarmonyOS 采用了支持高性能多语言编译的方舟编译器。其能够消除跨语言交互开销,统一运行时;统一多语言前端,让开发者能够自由选择 Java、JavaScript 及其他语言;通过组件解耦实现多设备弹性部署;操作系统、运行时和开发框架协同设计,能够完成联合优化,提高代码执行效率。

IDE 方面,HarmonyOS 2.0 打造了全场景跨设备集成开发工具 Huawei DevEco Studio。其具有三大特色能力,在编程时开发者可以实时预览UI,实现编程所⻅即所得;提供 API 智能补全,实现高效编码;面对多设备测试难题,DevEco Studio 提供了高性能模拟仿真和实时调测。

华为面向广大开发者提供了 HarmonyOS 应用开发者官网、设备开发者官网、设备合作伙伴门户、开发者论坛 @华为开发者联盟等四大平台,持续对外发布相关技术,也让开发者们互通有无,共同陪伴 HarmonyOS 一路前行。

《孙子·谋攻篇》有云:“上下同欲者胜,以虞待不虞者胜”。 华为发布 HarmonyOS 并非仓促的决定,而是一次上下同心、准备充足的征程。 当前,已经有大批设备合作伙伴、应用合作伙伴和开发者社区合作伙伴加入了 HarmonyOS 全场景智慧生态,成为先行者。HarmonyOS 抓住了 IoT 产业崛起的历史机遇,共享先进平台,共建开源平台,同合作伙伴及开发者共同发力,共赢全场景智慧时代。

segmentfault 公众号

查看原文

赞 28 收藏 2 评论 8

菜小胖 赞了文章 · 9月9日

活动推介 | 用 Serverless 写下你的第一行 Hello World

Serverless 作为云原生时代下最火热的名词之一,其架构所提供服务的便捷性,在日常、预发、线上等多套环境中即可部署、调试、运行应用,实现真正的按需付费和免运维,相信关注先进技术的你一定有所耳闻吧。

而在当下,Serverless 虽提出了一个先进的概念,但对于如何利用Serverless 应用于实际开发,服务于生产效率,切实感受到 Serverless 的便利性,相信大多数开发者还没有体感。

为了快速帮助国内开发者触手可及地感受到 Serverless,面向社会上对 Serverless 和云原生感兴趣的开发者,阿里云发起了一个“脑洞实验”:想邀请 10000 名工程师,花 5 分钟时间,体验 Serverless 架构在云上部署的便利性,在云上写下你的第一行基于 Serverless 的 Hello World。

为了更好得完成这项挑战,阿里云与国内技术社区联合发起这个活动。如果你也感兴趣,不如让我们从一行 Hello World 开始理解 Serverless?

三步云上 Hello World

· 第一步:花 1min 签到,让你的身影出现在 DataV 的实时大屏上

· 第二步:花 3mins 提交代码,把你的 Hello World 留在云上

· 第三部:花 1min 查看结果,10000 人目标成功后,你将收到全球唯一序列号的私人定制证书

image

该实验仅支持在PC端完成,链接:https://developer.aliyun.com/topic/yiqi/hol

另外,这次云栖大会有一个全部都是福利的开发者斜杠栏目: Hands-on Labs,没啥特别的,为了承包你一周的T恤,我们付出了全部努力,推荐看看。

image

查看原文

赞 14 收藏 1 评论 0

菜小胖 关注了标签 · 9月4日

关注 19

认证与成就

  • 获得 0 次点赞
  • 获得 0 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 0 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 4月2日
个人主页被 77 人浏览