鸡汤文案生成器,鸡汤文案高级 ***

牵着乌龟去散步 百科 19
Android基础系列篇(一):注解的那些事儿

前言

本系列文章主要是汇总了一下大佬们的技术文章,属于Android基础部分,作为一名合格的安卓开发工程师,咱们肯定要熟练掌握j *** a和android,本期就来说说这些~

<非商业用途,如有侵权,请告知我,我会删除>

DD一下: 开发文档跟之前仍旧一样,需要的跟作者直接要。

注解

Annotation 中文译过来就是注解、标释的意思,在 J *** a 中注解是一个很重要的知识点,但经常还是有点让新手不容易理解。

我个人认为,比较糟糕的技术文档主要特征之一就是:用专业名词来介绍专业名词。 比如:

J *** a 注解用于为 J *** a 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。J *** a 注解是从 J *** a5 开始添加到 J *** a 的。 这是大多数网站上对于 J *** a 注解,解释确实正确,但是说实在话,我之一次学习的时候,头脑一片空白。这什么跟什么啊?听了像没有听一样。因为概念太过于抽象,所以初学者实在是比较吃力才能够理解,然后随着自己开发过程中不断地强化练习,才会慢慢对它形成正确的认识。

我在写这篇文章的时候,我就在思考。如何让自己或者让读者能够比较直观地认识注解这个概念?是要去官方文档上翻译说明吗?我马上否定了这个 *** 。

后来,我想到了一样东西————墨水,墨水可以挥发、可以有不同的颜色,用来解释注解正好。

不过,我继续发散思维后,想到了一样东西能够更好地代替墨水,那就是印章。印章可以沾上不同的墨水或者印泥,可以定制印章的文字或者图案,如果愿意它也可以被戳到你任何想戳的物体表面。

但是,我再继续发散思维后,又想到一样东西能够更好地代替印章,那就是标签。标签是一张便利纸,标签上的内容可以 *** 定义。常见的如货架上的商品 *** 标签、图书馆中的书本编码标签、实验室中化学材料的名称类别标签等等。

并且,往抽象地说,标签并不一定是一张纸,它可以是对人和事物的属 *** 评价。也就是说,标签具备对于抽象事物的解释。



所以,基于如此,我完成了自我的知识认知升级,我决定用标签来解释注解。

1.注解的定义

注解通过 @interface 关键字进行定义。

public @interface TestAnnotation {}

它的形式跟接口很类似,不过前面多了一个 @ 符号。上面的代码就创建了一个名字为 TestAnnotaion 的注解。

你可以简单理解为创建了一张名字为 TestAnnotation 的标签。

1.1注解的属 ***

注解的属 *** 也叫做成员变量。注解只有成员变量,没有 *** 。注解的成员变量在注解的定义中以“无形参的 *** ”形式来声明,其 *** 名定义了该成员变量的名字,其返回值定义了该成员变量的类型。

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface TestAnnotation {    int id();    String msg();}

上面代码定义了 TestAnnotation 这个注解中拥有 id 和 msg 两个属 *** 。在使用的时候,我们应该给它们进行赋值。

赋值的方式是在注解的括号内以 value=”” 形式,多个属 *** 之前用 ,隔开。

@TestAnnotation(id=3,msg="hello annotation")public class Test {}

需要注意的是,在注解中定义属 *** 时它的类型必须是 8 种基本数据类型外加 类、接口、注解及它们的数组。

注解中属 *** 可以有默认值,默认值需要用 default 关键值指定。比如:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface TestAnnotation {    public int id() default -1;    public String msg() default "Hi";}

TestAnnotation 中 id 属 *** 默认值为 -1,msg 属 *** 默认值为 Hi。 它可以这样应用。

@TestAnnotation()public class Test {}

因为有默认值,所以无需要再在 @TestAnnotation 后面的括号里面进行赋值了,这一步可以省略。

另外,还有一种情况。如果一个注解内仅仅只有一个名字为 value 的属 *** 时,应用这个注解时可以直接接属 *** 值填写到括号内。

鸡汤文案生成器,鸡汤文案高级图片-第1张图片-

public @interface Check {    String value();}

上面代码中,Check 这个注解只有 value 这个属 *** 。所以可以这样应用。

@Check("hi")int a;

这和下面的效果是一样的

@Check(value="hi")int a;

最后,还需要注意的一种情况是一个注解没有任何属 *** 。比如

public @interface Perform {}

那么在应用这个注解的时候,括号都可以省略。

@Performpublic void testMethod(){}

2.自定义注解

2.1注解如同标签

之前某新闻客户端的评论有盖楼的习惯,于是 “乔布斯重新定义了 *** 、罗永浩重新定义了傻 X” 就经常极为工整地出现在了评论楼层中,并且广大网友在相当长的一段时间内对于这种行为乐此不疲。这其实就是等同于贴标签的行为。 在某些网友眼中,罗永浩就成了傻 X的代名词。

广大网友给罗永浩贴了一个名为“傻x”的标签,他们并不真正了解罗永浩,不知道他当教师、砸冰箱、办博客的壮举,但是因为“傻 x”这样的标签存在,这有助于他们直接快速地对罗永浩这个人做出评价,然后基于此,罗永浩就可以成为 *** 的谈资,这就是标签的力量。

而在 *** 的另一边,老罗靠他的人格魅力自然收获一大批忠实的拥泵,他们对于老罗贴的又是另一种标签。



老罗还是老罗,但是由于人们对于它贴上的标签不同,所以造成对于他的看法大相径庭,不喜欢他的人整天在 *** 上评论抨击嘲讽,而崇拜欣赏他的人则会愿意挣钱购买锤子 *** 的发布会门票。

我无意于评价这两种行为,我再引个例子。

《奇葩说》是近年 *** 上非常火热的辩论节目,其中辩手陈铭被另外一个辩手马薇薇攻击说是————“站在宇宙中心呼唤爱”,然后贴上了一个大大的标签————“鸡汤男”,自此以后,观众再看到陈铭的时候,首先映入脑海中便是“鸡汤男”三个大字,其实本身而言陈铭非常优秀,为人师表、作风正派、谈吐举止得体,但是在 *** 中,因为娱乐至上的环境所致,人们更愿意以娱乐的心态来认知一切,于是“鸡汤男”就如陈铭自己所说成了一个撕不了的标签。

我们可以抽象概括一下,标签是对事物行为的某些角度的评价与解释。

到这里,终于可以引出本文的主角注解了。

初学者可以这样理解注解:想像代码具有生命,注解就是对于代码中某些鲜活个体的贴上去的一张标签。简化来讲,注解如同一张标签。

在未开始学习任何注解具体语法而言,你可以把注解看成一张标签。这有助于你快速地理解它的大致作用。如果初学者在学习过程有大脑放空的时候,请不要慌张,对自己说:

注解,标签。注解,标签。

2.2注解语法

因为平常开发少见,相信有不少的人员会认为注解的地位不高。其实同 classs 和 interface 一样,注解也属于一种类型。它是在 J *** a SE 5.0 版本中开始引入的概念。

2.3元注解

元注解是什么意思呢?

元注解是可以注解到注解上的注解,或者说元注解是一种基本注解,但是它能够应用到其它的注解上面。

如果难于理解的话,你可以这样理解。元注解也是一张标签,但是它是一张特殊的标签,它的作用和目的就是给其他普通的标签进行解释说明的。

元标签有 @Retention、@Documented、@Target、@Inherited、@Repeatable 5 种。

@Retention

Retention 的英文意为保留期的意思。当 @Retention 应用到一个注解上的时候,它解释说明了这个注解的的存活时间。

它的取值如下:

  • RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
  • RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
  • RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。

我们可以这样的方式来加深理解,@Retention 去给一张标签解释的时候,它指定了这张标签张贴的时间。@Retention 相当于给一张标签上面盖了一张时间戳,时间戳指明了标签张贴的时间周期。

@Retention(RetentionPolicy.RUNTIME)public @interface TestAnnotation {}

上面的代码中,我们指定 TestAnnotation 可以在程序运行周期被获取到,因此它的生命周期非常的长。

@Documented

顾名思义,这个元注解肯定是和文档有关。它的作用是能够将注解中的元素包含到 J *** adoc 中去。

@Target

Target 是目标的意思,@Target 指定了注解运用的地方。

你可以这样理解,当一个注解被 @Target 注解时,这个注解就被限定了运用的场景。

类比到标签,原本标签是你想张贴到哪个地方就到哪个地方,但是因为 @Target 的存在,它张贴的地方就非常具体了,比如只能张贴到 *** 上、类上、 *** 参数上等等。@Target 有下面的取值

  • ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
  • ElementType.CONSTRUCTOR 可以给构造 *** 进行注解
  • ElementType.FIELD 可以给属 *** 进行注解
  • ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
  • ElementType.METHOD 可以给 *** 进行注解
  • ElementType.PACKAGE 可以给一个包进行注解
  • ElementType.PARAMETER 可以给一个 *** 内的参数进行注解
  • ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举

@Inherited

Inherited 是继承的意思,但是它并不是说注解本身可以继承,而是说如果一个超类被 @Inherited 注解过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解。 说的比较抽象。代码来解释。

@Inherited@Retention(RetentionPolicy.RUNTIME)@interface Test {}@Testpublic class A {}public class B extends A {}

注解 Test 被 @Inherited 修饰,之后类 A 被 Test 注解,类 B 继承 A,类 B 也拥有 Test 这个注解。

可以这样理解:

老子非常有钱,所以人们给他贴了一张标签叫做富豪。

老子的儿子长大后,只要没有和老子断绝父子关系,虽然别人没有给他贴标签,但是他自然也是富豪。

老子的孙子长大了,自然也是富豪。

这就是人们口中戏称的富一代,富二代,富三代。虽然叫法不同,好像好多个标签,但其实事情的本质也就是他们有一张共同的标签,也就是老子身上的那张富豪的标签。

@Repeatable

Repeatable 自然是可重复的意思。@Repeatable 是 J *** a 1.8 才加进来的,所以算是一个新的特 *** 。

什么样的注解会多次应用呢?通常是注解的值可以同时取多个。

举个例子,一个人他既是程序员又是产品经理,同时他还是个画家。

@interface Persons {    Person<>  value();}@Repeatable(Persons.class)@interface Person{    String role default "";}@Person(role="artist")@Person(role="coder")@Person(role="PM")public class SuperMan{}

注意上面的代码,@Repeatable 注解了 Person。而 @Repeatable 后面括号中的类相当于一个容器注解。

什么是容器注解呢?就是用来存放其它注解的地方。它本身也是一个注解。

我们再看看代码中的相关容器注解。

@interface Persons {    Person<>  value();}

按照规定,它里面必须要有一个 value 的属 *** ,属 *** 类型是一个被 @Repeatable 注解过的注解数组,注意它是数组。

如果不好理解的话,可以这样理解。Persons 是一张总的标签,上面贴满了 Person 这种同类型但内容不一样的标签。把 Persons 给一个 SuperMan 贴上,相当于同时给他贴了程序员、产品经理、画家的标签。

我们可能对于 @Person(role=”PM”) 括号里面的内容感兴趣,它其实就是给 Person 这个注解的 role 属 *** 赋值为 PM ,大家不明白正常,马上就讲到注解的属 *** 这一块。

2.4J *** a 预置的注解

J *** a 语言本身已经提供了几个现成的注解。

@Deprecated

这个元素是用来标记过时的元素,想必大家在日常开发中经常碰到。编译器在编译阶段遇到这个注解时会发出提醒警告,告诉开发者正在调用一个过时的元素比如过时的 *** 、过时的类、过时的成员变量。

public class Hero {    @Deprecated    public void say(){        System.out.println("Noting has to say!");    }    public void speak(){        System.out.println("I h *** e a dream!");    }}

定义了一个 Hero 类,它有两个 *** say() 和 speak() ,其中 say() 被 @Deprecated 注解。然后我们在 IDE 中分别调用它们。



可以看到,say() *** 上面被一条直线划了一条,这其实就是编译器识别后的提醒效果。

@Override

这个大家应该很熟悉了,提示子类要复写父类中被 @Override 修饰的 ***

@SuppressWarnings

阻止警告的意思。之前说过调用被 @Deprecated 注解的 *** 后,编译器会警告提醒,而有时候开发者会忽略这种警告,他们可以在调用的地方通过 @SuppressWarnings 达到目的。

@SuppressWarnings("deprecation")public void test1(){    Hero  ***  = new Hero();     *** .say();     *** .speak();}

@SafeVarargs

参数安全类型注解。它的目的是提醒开发者不要用参数做一些不安全的 *** 作,它的存在会阻止编译器产生 unchecked 这样的警告。它是在 J *** a 1.7 的版本中加入的。

@SafeVarargs // Not actually safe!    static void m(List<String>... stringLists) {    Object<> array = stringLists;    List<Integer> tmpList = Arrays.asList(42);    array<0> = tmpList; // Se *** ntically invalid, but compiles without warnings    String s = stringLists<0>.get(0); // Oh no, ClassCastException at runtime!}

上面的代码中,编译阶段不会报错,但是运行时会抛出 ClassCastException 这个异常,所以它虽然告诉开发者要妥善处理,但是开发者自己还是搞砸了。

J *** a 官方文档说,未来的版本会授权编译器对这种不安全的 *** 作产生错误警告。

@FunctionalInterface

函数式接口注解,这个是 J *** a 1.8 版本引入的新特 *** 。函数式编程很火,所以 J *** a 8 也及时添加了这个特 *** 。

函数式接口 (Functional Interface) 就是一个具有一个 *** 的普通接口。 比如

@FunctionalInterfacepublic interface Runnable {    /**     * When an object implementing interface <code>Runnable</code> is used     * to create a thread, starting the thread causes the object's     * <code>run</code> method to be called in that separately executing     * thread.     * <p>     * The general contract of the method <code>run</code> is that it  *** y     * take any action whatso *** r.     *     * @see     j *** a.lang.Thread#run()     */    public abstract void run();}

我们进行线程开发中常用的 Runnable 就是一个典型的函数式接口,上面源码可以看到它就被 @FunctionalInterface 注解。

可能有人会疑惑,函数式接口标记有什么用,这个原因是函数式接口可以很容易转换为 Lambda 表达式。这是另外的主题了,有兴趣的同学请自己搜索相关知识点学习。

3.注解的使用

3.1注解的应用

上面创建了一个注解,那么注解的的使用 *** 是什么呢。

@TestAnnotationpublic class Test {}

创建一个类 Test,然后在类定义的地方加上 @TestAnnotation 就可以用 TestAnnotation 注解这个类了。

你可以简单理解为将 TestAnnotation 这张标签贴到 Test 这个类上面。

3.2注解的提取

前面的部分讲了注解的基本语法,现在是时候检测我们所学的内容了。

我通过用标签来比作注解,前面的内容是讲怎么写注解,然后贴到哪个地方去,而现在我们要做的工作就是检阅这些标签内容。 形象的比喻就是你把这些注解标签在合适的时候撕下来,然后检阅上面的内容信息。

要想正确检阅注解,离不开一个手段,那就是反射。

3.3注解与反射

注解通过反射获取。首先可以通过 Class 对象的 isAnnotationPresent() *** 判断它是否应用了某个注解

public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}

然后通过 getAnnotation() *** 来获取 Annotation 对象。

 public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {}

或者是 getAnnotations() *** 。

public Annotation<> getAnnotations() {}

前一种 *** 返回指定类型的注解,后一种 *** 返回注解到这个元素上的所有注解。

如果获取到的 Annotation 如果不为 null,则就可以调用它们的属 *** *** 了。比如

@TestAnnotation()public class Test {    public static void  *** in(String<> args) {        boolean hasAnnotation = Test.class.isAnnotationPresent(TestAnnotation.class);        if ( hasAnnotation ) {            TestAnnotation testAnnotation = Test.class.getAnnotation(TestAnnotation.class);            System.out.println("id:"+testAnnotation.id());            System.out.println("msg:"+testAnnotation.msg());        }    }}

程序的运行结果是:

id:-1msg:

这个正是 TestAnnotation 中 id 和 msg 的默认值。

上面的例子中,只是检阅出了注解在类上的注解,其实属 *** 、 *** 上的注解照样是可以的。同样还是要假手于反射。

@TestAnnotation(msg="hello")public class Test {    @Check(value="hi")    int a;    @Perform    public void testMethod(){}    @SuppressWarnings("deprecation")    public void test1(){        Hero  ***  = new Hero();         *** .say();         *** .speak();    }    public static void  *** in(String<> args) {        boolean hasAnnotation = Test.class.isAnnotationPresent(TestAnnotation.class);        if ( hasAnnotation ) {            TestAnnotation testAnnotation = Test.class.getAnnotation(TestAnnotation.class);            //获取类的注解            System.out.println("id:"+testAnnotation.id());            System.out.println("msg:"+testAnnotation.msg());        }        try {            Field a = Test.class.getDeclaredField("a");            a.setAccessible(true);            //获取一个成员变量上的注解            Check check = a.getAnnotation(Check.class);            if ( check != null ) {                System.out.println("check value:"+check.value());            }            Method testMethod = Test.class.getDeclaredMethod("testMethod");            if ( testMethod != null ) {                // 获取 *** 中的注解                Annotation<> ans = testMethod.getAnnotations();                for( int i = 0;i < ans.length;i++) {                    System.out.println("method testMethod annotation:"+ans.annotationType().getSimpleName());                }            }        } catch (NoSuchFieldException e) {            // TODO Auto-generated catch block            e.printStackTrace();            System.out.println(e.getMessage());        } catch (Sec *** ityException e) {            // TODO Auto-generated catch block            e.printStackTrace();            System.out.println(e.getMessage());        } catch (NoSuchMethodException e) {            // TODO Auto-generated catch block            e.printStackTrace();            System.out.println(e.getMessage());        }    }}

它们的结果如下:

id:-1msg:hellocheck value:himethod testMethod annotation:Perform

需要注意的是,如果一个注解要在运行时被成功提取,那么 @Retention(RetentionPolicy.RUNTIME) 是必须的。

3.4注解的使用场景

我相信博文讲到这里大家都很熟悉了注解,但是有不少同学肯定会问,注解到底有什么用呢?

对啊注解到底有什么用?

我们不妨将目光放到 J *** a 官方文档上来。

文章开始的时候,我用标签来类比注解。但标签比喻只是我的手段,而不是目的。为的是让大家在初次学习注解时能够不被那些抽象的新概念搞懵。既然现在,我们已经对注解有所了解,我们不妨再仔细阅读官方最严谨的文档。

注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释的代码本身的一部分。注解对于代码的运行效果没有直接影响。 注解有许多用处,主要如下:

  • 提供信息给编译器: 编译器可以利用注解来探测错误和警告信息
  • 编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。
  • 运行时的处理: 某些注解可以在程序运行的时候接受代码的提取 值得注意的是,注解不是代码本身的一部分。

如果难于理解,可以这样看。罗永浩还是罗永浩,不会因为某些人对于他“傻x”的评价而改变,标签只是某些人对于其他事物的评价,但是标签不会改变事物本身,标签只是特定人群的手段。所以,注解同样无法改变代码本身,注解只是某些工具的的工具。

还是回到官方文档的解释上,注解主要针对的是编译器和其它工具软件(SoftWare tool)。

当开发者使用了Annotation 修饰了类、 *** 、Field 等成员之后,这些 Annotation 不会自己生效,必须由开发者提供相应的代码来提取并处理 Annotation 信息。这些处理提取和处理 Annotation 的代码统称为 APT(Annotation Processing Tool)。

现在,我们可以给自己 *** 了,注解有什么用?给谁用?给 编译器或者 APT 用的。

如果,你还是没有搞清楚的话,我亲自写一个好了。

3.5亲手自定义注解完成项目

我要写一个测试框架,测试程序员的代码有无明显的异常。

—— 程序员 A : 我写了一个类,它的名字叫做 NoBug,因为它所有的 *** 都没有错误。 —— 我:自信是好事,不过为了防止意外,让我测试一下如何? —— 程序员 A: 怎么测试? —— 我:把你写的代码的 *** 都加上 @Jiecha 这个注解就好了。 —— 程序员 A: 好的。

package ceshi;import ceshi.Jiecha;public class NoBug {    @Jiecha    public void suanShu(){        System.out.println("1234567 *** 0");    }    @Jiecha    public void jiafa(){        System.out.println("1+1="+1+1);    }    @Jiecha    public void jiefa(){        System.out.println("1-1="+(1-1));    }    @Jiecha    public void chengfa(){        System.out.println("3 x 5="+ 3*5);    }    @Jiecha    public void chufa(){        System.out.println("6 / 0="+ 6 / 0);    }    public void ziwojieshao(){        System.out.println("我写的程序没有 bug!");    }}

上面的代码,有些 *** 上面运用了 @Jiecha 注解。

这个注解是我写的测试软件框架中定义的注解。

package ceshi;import j *** a.lang.annotation.Retention;import j *** a.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)public @interface Jiecha {}

然后,我再编写一个测试类 TestTool 就可以测试 NoBug 相应的 *** 了。

package ceshi;import j *** a.lang.reflect.InvocationTargetException;import j *** a.lang.reflect.Method;public class TestTool {    public static void  *** in(String<> args) {        // TODO Auto-generated method stub        NoBug testobj = new NoBug();        Class clazz = testobj.getClass();        Method<> method = clazz.getDeclaredMethods();        //用来记录测试产生的 log 信息        StringBuilder log = new StringBuilder();        // 记录异常的次数        int errornum = 0;        for ( Method m: method ) {            // 只有被 @Jiecha 标注过的 *** 才进行测试            if ( m.isAnnotationPresent( Jiecha.class )) {                try {                    m.setAccessible(true);                    m.invoke(testobj, null);                } catch (Exception e) {                    // TODO Auto-generated catch block                    //e.printStackTrace();                    errornum++;                    log.append(m.getName());                    log.append(" ");                    log.append("has error:");                    log.append("\n\r  caused by ");                    //记录测试过程中,发生的异常的名称                    log.append(e.getCause().getClass().getSimpleName());                    log.append("\n\r");                    //记录测试过程中,发生的异常的具体信息                    log.append(e.getCause().getMessage());                    log.append("\n\r");                }             }        }        log.append(clazz.getSimpleName());        log.append(" has  ");        log.append(errornum);        log.append(" error.");        // 生成测试报告        System.out.println(log.toString());    }}

测试的结果是:

1234567 *** 01+1=111-1=03 x 5=15chufa has error:  caused by ArithmeticException/ by zeroNoBug has  1 error.

提示 NoBug 类中的 chufa() 这个 *** 有异常,这个异常名称叫做 ArithmeticException,原因是运算过程中进行了除 0 的 *** 作。

所以,NoBug 这个类有 Bug。

这样,通过注解我完成了我自己的目的,那就是对别人的代码进行测试。

所以,再问我注解什么时候用?我只能告诉你,这取决于你想利用它干什么用。

3.6注解应用实例

注解运用的地方太多了,如: JUnit 这个是一个测试框架,典型使用 *** 如下:

public class ExampleUnitTest {    @Test    public void addition_isCorrect() throws Exception {        assertEquals(4, 2 + 2);    }}

@Test 标记了要进行测试的 *** addition_isCorrect().

还有例如s *** 框架等运用了大量的注解。

注解部分总结

  • 如果注解难于理解,你就把它类同于标签,标签为了解释事物,注解为了解释代码。
  • 注解的基本语法,创建如同接口,但是多了个 @ 符号。
  • 注解的元注解。
  • 注解的属 *** 。
  • 注解主要给编译器及工具类型的软件用的。
  • 注解的提取需要借助于 J *** a 的反射技术,反射比较慢,所以注解使用时也需要谨慎计较时间成本。

4.APT实现原理

4.1 SPI机制

SPI是jdk内置的服务发现机制, 全称叫Service Provider Interface.

SPI的工作原理, 就是ClassPath路径下的META-INF/services文件夹中, 以接口的全限定名来命名文件名, 文件里面写该接口的实现。 然后再资源加载的方式,读取文件的内容(接口实现的全限定名), 然后再去加载类。

SPI可以很灵活的让接口和实现分离, 让api提供者只提供接口, 第三方来实现。

这一机制为很多框架的扩展提供了可能,比如在 Dubbo、JDBC、SpringBoot 中都使用到了SPI机制。虽然他们之间的实现方式不同,但原理都差不多。今天我们就来看看,SPI到底是何方神圣,在众多开源框架中又扮演了什么角色。

4.1.1 JDK中的SPI

我们先从JDK开始,通过一个很简单的例子来看下它是怎么用的。

4.1.1.1、小栗子

首先,我们需要定义一个接口,SpiService

package com.dxz.jdk.spi;public interface SpiService {    void println();}

然后,定义一个实现类,没别的意思,只做打印。

package com.dxz.jdk.spi;?public class SpiServiceImpl implements SpiService {    @Override    public void println() {        System.out.println("------SPI DEMO-------");    }}

最后呢,要在reso *** ces路径下配置添加一个文件。文件名字是接口的全限定类名,内容是实现类的全限定类名,多个实现类用换行符分隔。

文件内容就是实现类的全限定类名:

4.1.1.2、测试

然后我们就可以通过 ServiceLoader.load *** 拿到实现类的实例,并调用它的 *** 。

public static void  *** in(String<> args){    ServiceLoader<SpiService> load = ServiceLoader.load(SpiService.class);    Iterator<SpiService> iterator = load.iterator();    while (iterator.hasNext()){        SpiService service = iterator.next();        service.println();    }}

4.1.1.3、源码分析

首先,我们先来了解下 ServiceLoader,看看它的类结构。

public final class ServiceLoader<S> implements Iterable<S>{    //配置文件的路径    private static final String PREFIX = "META-INF/services/";    //加载的服务类或接口    private final Class<S> service;    //已加载的服务类 ***     private LinkedHashMap<String,S> providers = new LinkedHashMap<>();    //类加载器    private final ClassLoader loader;    //内部类,真正加载服务类    private LazyIterator lookupIterator;}

当我们调用 load *** 时,并没有真正的去加载和查找服务类。而是调用了 ServiceLoader 的构造 *** ,在这里最重要的是实例化了内部类 LazyIterator ,它才是接下来的主角。

private ServiceLoader(Class<S> svc, ClassLoader cl) {    //要加载的接口    service = Objects.requireNonNull(svc, "Service interface cannot be null");    //类加载器    loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;    //访问 ***     acc = (System.getSec *** ityMa *** r() != null) ? AccessController.getContext() : null;    //先清空    providers.clear();    //实例化内部类     LazyIterator lookupIterator = new LazyIterator(service, loader);}

查找实现类和创建实现类的过程,都在 LazyIterator 完成。当我们调用 iterator.hasNext和iterator.next *** 的时候,实际上调用的都是 LazyIterator 的相应 *** 。

public Iterator<S> iterator() {?    ret *** n new Iterator<S>() {            public boolean hasNext() {            ret *** n lookupIterator.hasNext();        }        public S next() {            ret *** n lookupIterator.next();        }        .......    };}

所以,我们重点关注 lookupIterator.hasNext() *** ,它最终会调用到 hasNextServicez ,在这里返回实现类名称。

private class LazyIterator implements Iterator<S>{    Class<S> service;    ClassLoader loader;    Enumeration<URL> configs = null;    Iterator<String> pending = null;    String nextName = null;        private boolean hasNextService() {        //第二次调用的时候,已经解析完成了,直接返回        if (nextName != null) {            ret *** n true;        }        if (configs == null) {            //META-INF/services/ 加上接口的全限定类名,就是文件服务类的文件            //META-INF/services/com.viewscenes.netsupervisor.spi.SP *** ervice            String fullName = PREFIX + service.getName();            //将文件路径转成URL对象            configs = loader.getReso *** ces(fullName);        }        while ((pending == null) || !pending.hasNext()) {            //解析URL文件对象,读取内容,最后返回            pending = parse(service, configs.nextElement());        }        //拿到之一个实现类的类名        nextName = pending.next();        ret *** n true;    }}

然后当我们调用 next() *** 的时候,调用到 lookupIterator.nextService 。它通过反射的方式,创建实现类的实例并返回。

private S nextService() {    //全限定类名    String cn = nextName;    nextName = null;    //创建类的Class对象    Class<?> c = Class.forName(cn, false, loader);    //通过newInstance实例化    S p = service.cast(c.newInstance());    //放入 *** ,返回实例    providers.put(cn, p);    ret *** n p; }

到这为止,已经获取到了类的实例。

4.1.2 JDBC中的应用

我们开头说,SPI机制为很多框架的扩展提供了可能,其实JDBC就应用到了这一机制。

在以前,需要先设置数据库驱动的连接,再通过 DriverMa *** r.getConnection 获取一个 Connection 。

String  *** l = "jdbc:mysql:///consult?serverTimezone=UTC";String user = "root";String passwor d = "r oot";?Class.forName("com.mysql.jdbc.Driver");Connection connection = DriverMa *** r.getConnection( *** l, user, password);

而现在,设置数据库驱动连接,这一步骤就不再需要,那么它是怎么分辨是哪种数据库的呢? *** 就在SPI。

4.1.2.1 加载

下图mysql Driver的实例。 com.mysql.cj.jdbc.Driver就是Driver的实现。



mysql驱动为例



mysql Driver实现类


Driver接口上的一段注释。

DriverMa *** r将尝试加载尽可能多的驱动程序。

我们把目光回到 DriverMa *** r 类,它在静态代码块里面做了一件比较重要的事。很明显,它已经通过SPI机制, 把数据库驱动连接初始化了。

public class DriverMa *** r {    static {        loadInitialDrivers();        println("JDBC DriverMa *** r initialized");    }}

接下来我们去DriverManger上看看是如何加载Driver接口的实现类的。

public class DriverMa *** r {?    /**     * Load the initial JDBC drivers by checking the System property     * jdbc.properties and then use the {@code ServiceLoader} mechani ***      */    static {        loadInitialDrivers();        println("JDBC DriverMa *** r initialized");    }?    private static void loadInitialDrivers() {        AccessController.doPrivileged(new PrivilegedAction<Void>() {            public Void run() {                ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);                Iterator<Driver> driversIterator = loadedDrivers.iterator();                try{                    while(driversIterator.hasNext()) {                        driversIterator.next();                    }                } catch(Throwable t) {                               }                ret *** n null;            }        });}

在DriverManger类初始化的时候, 调用loadInitialDrivers *** 。

具体过程还得看 loadInitialDrivers ,它在里面查找的是Driver接口的服务类,所以它的文件路径就是:

META-INF/services/j *** a.sql.Driver

在loadInitialDrivers *** 中,

private static void loadInitialDrivers() {    AccessController.doPrivileged(new PrivilegedAction<Void>() {        public Void run() {            //很明显,它要加载Driver接口的服务类,Driver接口的包为:j *** a.sql.Driver            //所以它要找的就是META-INF/services/j *** a.sql.Driver文件            ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);            Iterator<Driver> driversIterator = loadedDrivers.iterator();            try{                //查到之后创建对象                while(driversIterator.hasNext()) {                    driversIterator.next();//当调用next *** 时,就会创建这个类的实例。它就完成了一件事,向 DriverMa *** r 注册自身的实例。                }            } catch(Throwable t) {                // Do nothing            }            ret *** n null;        }    });}

这段代码是实现SPI的关键, 真是这个ServiceLoader类去实现SPI的。 那么下面就分析分析ServiceLoader的代码, 看看是如何实现SPI的。

package j *** a.util;?public final class ServiceLoader<S> implements Iterable<S> {   public static <S> ServiceLoader<S> load(Class<S> service) {        ClassLoader cl = Thread.c *** rentThread().getContextClassLoader();        ret *** n ServiceLoader.load(service, cl);    }?   //其中service就是要加载实现类对应的接口, loader就是用该加载器去加载对应的实现类   public static <S> ServiceLoader<S> load(Class<S> service, ClassLoader loader){        ret *** n new ServiceLoader<>(service, loader);    }}

先调用ServiceLoader类的静态 *** load, 然后根据当前线程的上下文类加载器,创建一个ServiceLoader实例。

private static final String PREFIX = "META-INF/services/";?public void reload() {        providers.clear();        lookupIterator = new LazyIterator(service, loader);    }private ServiceLoader(Class<S> svc, ClassLoader cl) {        service = Objects.requireNonNull(svc, "Service interface cannot be null");        loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;        acc = (System.getSec *** ityMa *** r() != null) ? AccessController.getContext() : null;        reload();    }

创建ServiceLoader实例的时候,接着创建一个Iterator实现类。 接下来这个Iterator分析的重点。基本所有的加载类的实现逻辑都在里面。

其中ServiceLoader类中一个常量的定义是关键的。 前面说过,我们service的实现类在放在哪, 就是这里写死的常量路径。

//这里先介绍Iterator的变量,先大概有个印象。private class LazyIterator        implements Iterator<S>    {        //service, loader前面介绍过了。        Class<S> service;        ClassLoader loader;        Enumeration<URL> configs = null;        Iterator<String> pending = null;        String nextName = null;?      public boolean hasNext() {        //省略权限相关代码        ret *** n hasNextService();         }?       private boolean hasNextService() {            //一开始nextName肯定为空            if (nextName != null) {                ret *** n true;            }            //一开始configs也肯定为空            if (configs == null) {                try {                    //PREFIX = META-INF/services/                    //以mysql为例,就是 META-INF/services/j *** a.sql.Driver                    String fullName = PREFIX + service.getName();                    if (loader == null) configs = ClassLoader.getSystemReso *** ces(fullName);                    //loader去加载这个classpath下文件。                    //这里很有可能返回的是多个文件的资源,                    //例如一个项目下既有mysql驱动, 也有sql server驱动等                    //所以返回的是一个枚举类型。                    else configs = loader.getReso *** ces(fullName);                } catch (IOException x) {                    fail(service, "Error locating config *** ation files", x);                }            }            while ((pending == null) || !pending.hasNext()) {                if (!configs.hasMoreElements()) {                    ret *** n false;                }                //然后根据加载出来的资源,解析一个文件中的内容。放到Iterator实现类中                pending = parse(service, configs.nextElement());            }            //这里next返回的就是文件一行的内容,一般一行对应一个接口的实现类。            //一个接口放多行,就可以有多个接口实现类中。            nextName = pending.next();            ret *** n true;        }}

configs变量,就对应service文件。 是个枚举, 就是说可以定义多个service文件。

pending 变量: 就对应configs中, service文件解析出来的一行有效内容,即一个实现类的全限定类名称。

parse *** 就是简单,不是重点。这里就略过了。就是读取service文件中读取,一行就是一个nextName,然后遇到“#“就跳过“#”后面的内容。所以service文件可以用“#”作为注释。 直到遇到空行,解析结束。

LazyIterator类中的hasNext *** 就分析完了。 使用classLoader.getReso *** ces *** 加载service文件。我看了下getReso *** ces *** ,并一定是加载classpath下的资源,得根据classLoader来解决。不过绝大多数情况下,都是classpath的资源。这里为了好理解,就理解成classpath下的资源。

接着分析LazyIterator#next *** 。

public S next() {       //删除权限相关代码       ret *** n nextService(); }private S nextService() {            if (!hasNextService())                throw new NoSuchElementException();            //这个nextName前面分析过了            String cn = nextName;            nextName = null;            Class<?> c = null;            try {                //加载类,且不初始化                c = Class.forName(cn, false, loader);            } catch (ClassNotFoundException x) {                fail(service,                     "Provider " + cn + " not found");            }            if (!service.isAssi *** ableFrom(c)) {                fail(service,                     "Provider " + cn  + " not a subtype");            }            try {                //类型判断                S p = service.cast(c.newInstance());               //最后放到ServiceLoader实例变量Map中,缓存起来,下次直接使用                providers.put(cn, p);                ret *** n p;            } catch (Throwable x) {                fail(service,                     "Provider " + cn + " could not be instantiated",                     x);            }            throw new Error();          // This cannot happen        }

next *** 就比较简单了,根据前面解析出来的nextName(接口实现类的全限定名称),用Class.forName创建对应的Class对象。

4.1.2.2 创建Connection

DriverMa *** r.getConnection() *** 就是创建连接的地方,它通过循环已注册的数据库驱动程序,调用其connect *** ,获取连接并返回。

private static Connection getConnection(String  *** l, Properties  *** , Class<?> caller) throws SQLException {        //registeredDrivers中就包含com.mysql.cj.jdbc.Driver实例    for(DriverInfo aDriver : registeredDrivers) {        if(isDriverAllowed(aDriver.driver, callerCL)) {            try {                //调用connect *** 创建连接                Connection con = aDriver.driver.connect( *** l,  *** );                if (con != null) {                    ret *** n (con);                }            }catch (SQLException ex) {                if (reason == null) {                    reason = ex;                }            }        } else {            println("skipping: " + aDriver.getClass().getName());        }    }}

4.1.2.3 扩展

既然我们知道JDBC是这样创建数据库连接的,我们能不能再扩展一下呢?如果我们自己也创建一个 j *** a.sql.Driver 文件,自定义实现类MySQLDriver,那么,在获取连接的前后就可以动态修改一些信息。

还是先在项目reso *** ces下创建文件,文件内容为自定义驱动类 com.jcc.j *** a.spi.domyself.MySQLDriver



我们的 MySQLDriver 实现类,继承自MySQL中的 NonRegisteringDriver ,还要实现 j *** a.sql.Driver 接口。这样,在调用connect *** 的时候,就会调用到此类,但实际创建的过程还靠MySQL完成。

public class MySQLDriver extends NonRegisteringDriver implements Driver{    static {        try {            DriverMa *** r.registerDriver(new MySQLDriver());        } catch (SQLException e) {            e.printStackTrace();        }    }    public MySQLDriver() throws SQLException {}?    @Override    public Connection connect(String  *** l, Properties  *** ) throws SQLException {        System.out.println("准备创建数据库连接. *** l:"+ *** l);        System.out.println("JDBC配置信息:"+ *** );        //重置配置         *** .setProperty("user", "root");        Connection connection =  super.connect( *** l,  *** );        System.out.println("数据库连接创建完成!"+connection.toString());        ret *** n connection;    }}

这样的话,当我们获取数据库连接的时候,就会调用到这里。

--------------------输出结果---------------------准备创建数据库连接. *** l:jdbc:mysql:///consult?serverTimezone=UTCJDBC配置信息:{user=root, password=root}数据库连接创建完成!com.mysql.cj.jdbc.ConnectionImpl@7cf10a6f

4.1.3 SpringBoot中的应用

Spring Boot提供了一种快速的方式来创建可用于生产环境的基于Spring的应用程序。它基于Spring框架,更倾向于约定而不是配置,并且旨在使您尽快启动并运行。

即便没有任何配置文件,SpringBoot的Web应用都能正常运行。这种神奇的事情,SpringBoot正是依靠自动配置来完成。

说到这,我们必须关注一个东西: SpringFactoriesLoader,自动配置就是依靠它来加载的。

4.1.3.1 配置文件

SpringFactoriesLoader 来负责加载配置。我们打开这个类,看到它加载文件的路径是: META-INF/spring.factories



笔者在项目中搜索这个文件,发现有4个Jar包都包含它:

  • List *** spring-boot-2.1.9.RELEASE.jar
  • spring-beans-5.1.10.RELEASE.jar
  • spring-boot-autoconfig *** e-2.1.9.RELEASE.jar
  • mybatis-spring-boot-autoconfig *** e-2.1.0.jar

那么它们里面都是些啥内容呢?其实就是一个个接口和类的映射。在这里笔者就不贴了,有兴趣的小伙伴自己去看看。

比如在SpringBoot启动的时候,要加载所有的 ApplicationContextInitializer ,那么就可以这样做:

SpringFactoriesLoader.loadFactoryNames(ApplicationContextInitializer.class, classLoader)

4.1.3.2 加载文件

loadSpringFactories 就负责读取所有的 spring.factories 文件内容。

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {?    MultiValueMap<String, String> result = cache.get(classLoader);    if (result != null) {        ret *** n result;    }    try {        //获取所有spring.factories文件的路径        Enumeration<URL>  *** ls = lassLoader.getReso *** ces("META-INF/spring.factories");        result = new LinkedMultiValueMap<>();        while ( *** ls.hasMoreElements()) {            URL  *** l =  *** ls.nextElement();            //加载文件并解析文件内容            UrlReso *** ce reso *** ce = new UrlReso *** ce( *** l);            Properties properties = PropertiesLoaderUtils.loadProperties(reso *** ce);            for (Map.Entry<?, ?> entry : properties.entrySet()) {                String factoryClassName = ((String) entry.getKey()).trim();                for (String factoryName : StringUtils ***  *** DelimitedListToStringArray((String) entry.getValue())) {                    result.add(factoryClassName, factoryName.trim());                }            }        }        cache.put(classLoader, result);        ret *** n result;    }    catch (IOException ex) {        throw new IllegalArgumentException("Unable to load factories from location <" +            FACTORIES_RESOURCE_LOCATION + ">", ex);    }}

可以看到,它并没有采用JDK中的SPI机制来加载这些类,不过原理差不多。都是通过一个配置文件,加载并解析文件内容,然后通过反射创建实例。

4.1.3.3 参与其中

假如你希望参与到 SpringBoot 初始化的过程中,现在我们又多了一种方式。

我们也创建一个 spring.factories 文件,自定义一个初始化器。

org.springframework.context.ApplicationContextInitializer=com.youyouxunyin.config.context.MyContextInitializer



然后定义一个MyContextInitializer类

public class MyContextInitializer implements ApplicationContextInitializer {    @Override    public void initialize(Config *** ableApplicationContext config *** ableApplicationContext) {        System.out.println(config *** ableApplicationContext);    }}

4.1.4 Dubbo中的应用

我们熟悉的Dubbo也不例外,它也是通过 SPI 机制加载所有的组件。同样的,Dubbo 并未使用 J *** a 原生的 SPI 机制,而是对其进行了增强,使其能够更好的满足需求。在 Dubbo 中,SPI 是一个非常重要的模块。基于 SPI,我们可以很容易的对 Dubbo 进行拓展。

它的使用方式同样是在 META-INF/services 创建文件并写入相关类名。

4.1.5 sentinel中的应用

通过SPI机制将META-INFO/servcie下配置好的默认责任链构造这加载出来,然后调用其builder() *** 进行构建调用链。

public final class SlotChainProvider {?    private static volatile SlotChainBuilder slotChainBuilder = null;?    /**     * The load and pick process is not thread-safe, but it's okay since the method should be only invoked     * via {@code lookProcessChain} in {@link com.alibaba. *** p.sentinel.CtSph} under lock.     *     * @ret *** n new created slot chain     */    public static ProcessorSlotChain newSlotChain() {        if (slotChainBuilder != null) {            ret *** n slotChainBuilder.build();        }?        // Resolve the slot chain builder SPI.        slotChainBuilder = SpiLoader.of(SlotChainBuilder.class).loadFirstInstanceOrDefault();?        if (slotChainBuilder == null) {            // Should not go through here.            RecordLog.warn(" Wrong state when resolving slot chain builder, using default");            slotChainBuilder = new DefaultSlotChainBuilder();        } else {            RecordLog. *** (" Global slot chain builder resolved: {}",                slotChainBuilder.getClass().getCanonicalName());        }        ret *** n slotChainBuilder.build();    }?    private SlotChainProvider() {}}

SpiLoader.of()

    public static <T> SpiLoader<T> of(Class<T> service) {        AssertUtil.notNull(service, "SPI class cannot be null");        AssertUtil.isTrue(service.isInterface() || Modifier.isAbstract(service.getModifiers()),                "SPI class<" + service.getName() + "> must be interface or abstract class");?        String className = service.getName();        SpiLoader<T> spiLoader = SPI_LOADER_MAP.get(className);        if (spiLoader == null) {            synchronized (SpiLoader.class) {                spiLoader = SPI_LOADER_MAP.get(className);                if (spiLoader == null) {                    SPI_LOADER_MAP.putIfAbsent(className, new SpiLoader<>(service));                    spiLoader = SPI_LOADER_MAP.get(className);                }            }        }?        ret *** n spiLoader;    }
@Spi(isDefault = true)public class DefaultSlotChainBuilder implements SlotChainBuilder {?    @Override    public ProcessorSlotChain build() {        ProcessorSlotChain chain = new DefaultProcessorSlotChain();?        List<ProcessorSlot> sortedSlotList = SpiLoader.of(ProcessorSlot.class).loadInstanceListSorted();        for (ProcessorSlot slot : sortedSlotList) {            if (!(slot instanceof AbstractLinkedProcessorSlot)) {                RecordLog.warn("The ProcessorSlot(" + slot.getClass().getCanonicalName() + ") is not an instance of AbstractLinkedProcessorSlot, can't be added into ProcessorSlotChain");                continue;            }?            chain.addLast((AbstractLinkedProcessorSlot<?>) slot);        }?        ret *** n chain;    }}

责任链同样是由spi机制加载出来的,上面的加载只会在之一次使用的时候加载,然后缓存到内从后,以后直接取即可。

至此,SPI机制的实现原理就分析完了。 虽然SPI我们日常开发中用的很少,但是至少了解了解还是有必要的。 例如: 一些框架实现中一般都会用到SPI机制。



vert.x内部也是大量使用SPI

4.2 APT注解处理器

4.2.1 基础知识

注解的保留时间分为三种:

  • SOURCE——只在源代码中保留,编译器将代码编译成字节码文件后就会丢掉
  • CLASS——保留到字节码文件中,但J *** a虚拟机将class文件加载到内存是不一定在内存中保留
  • RUNTIME——一直保留到运行时

通常我们使用后两种,因为SOURCE主要起到标记方便理解的作用,无法对代码逻辑提供有效的信息。


时间

解析

*** 能影响

RUNTIME

运行时

反射

CLASS

编译期

APT+J *** aPoet

如上图,对比两种解析方式:

  • 运行时注解比较简单易懂,可以运用反射技术在程序运行时获取指定的注解信息,因为用到反射,所以 *** 能会收到一定影响。
  • 编译期注解可以使用APT(Annotation Processing Tool)技术,在编译期扫描和解析注解,并结合J *** aPoet技术生成新的j *** a文件,是一种更优雅的解析注解的方式,不会对程序 *** 能产生太大影响。

下面以BindView为例,介绍两种方式的不同使用 *** 。

4.2.2 运行时注解

运行时注解主要通过反 *** 行解析,代码运行过程中,通过反射我们可以知道哪些属 *** 、 *** 使用了该注解,并且可以获取注解中的参数,做一些我们想做的事情。

首先,新建一个注解

@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)public @interface BindViewTo {    int value() default -1; //需要绑定的view id}

然后,新建一个注解解析工具类AnnotationTools,和一般的反射用法并无不同:

public class AnnotationTools {?    public static void bindAllAnnotationView(Activity activity) {        //获得成员变量        Field<> fields = activity.getClass().getDeclaredFields();?        for (Field field : fields) {            try {                if (field.getAnnotations() != null) {                    //判断BindViewTo注解是否存在                    if (field.isAnnotationPresent(BindViewTo.class)) {                        //获取访问权限                        field.setAccessible(true);                        BindViewTo getViewTo = field.getAnnotation(BindViewTo.class);                        //获取View id                        int id = getViewTo.value();                        //通过id获取View,并赋值该成员变量                        field.set(activity, activity.findViewById(id));                    }                }            } catch (Exception e) {            }        }    }}

在Activity中调用

public class MainActivity extends AppCompatActivity {?    @BindViewTo(R.id.text)    private TextView mText;?    @Override    protected void onCreate(Bundle s *** edInstanceState) {        super.onCreate(s *** edInstanceState);        setContentView(R.layout.activity_ *** in);?        //调用注解绑定,当前Activity中所有使用@BindViewTo注解的控件将自动绑定        AnnotationTools.bindAllAnnotationView(this);?        //测试绑定是否成功        mText.setTextColor(Color.RED);    }?}

测试结果毫无意外,字体变成了红色,说明绑定成功。

4.2.3 编译期注解(APT+J *** aPoet)

编译期注解解析需要用到APT(Annotation Processing Tool)技术,APT是j *** ac中提供的一种编译时扫描和处理注解的工具,它会对源代码文件进行检查,并找出其中的注解,然后根据用户自定义的注解处理 *** 进行额外的处理。APT工具不仅能解析注解,还能结合J *** aPoet技术根据注解生成新的的J *** a源文件,最终将生成的新文件与原来的J *** a文件共同编译。

APT实现流程如下:

  1. 创建一个j *** a lib作为注解解析库——如apt_processor
  2. 在创建一个j *** a lib作为注解声明库——如apt_annotation
  3. 搭建两个lib和主项目的依赖关系
  4. 实现AbstractProcessor
  5. 编译和调用

整个流程是固定的,我们的主要工作是继承AbstractProcessor,并且实现其中四个 *** 。下面一步一步详细介绍:

4.2.3.1创建解析库apt_processor

apply plugin: 'j *** a-library'?dependencies {    implementation fileTree(dir: 'libs', include: <'*.jar'>)    compile 'com.squareup:j *** apoet:1.9.0' // square开源的 J *** a 代码生成框架    compile 'com.google.auto.service:auto-service:1.0-rc2' //Google开源的用于注册自定义注解处理器的工具    implementation project(':apt_annotation') //依赖自定义注解声明库}so *** ceCompatibility = "7"targetCompatibility = "7"

4.2.3.2 创建注解库apt_annotation

声明一个注解BindViewTo,注意@Retention不再是RUNTIME,而是CLASS。

@Target({ElementType.FIELD})@Retention(RetentionPolicy.CLASS)public @interface BindViewTo {    int value() default -1;}

4.2.3.3 搭建主项目依赖关系

dependencies {    implementation fileTree(dir: 'libs', include: <'*.jar'>)    implementation project(':apt_annotation')  //依赖自定义注解声明库    annotationProcessor project(':apt_processor')  //依赖自定义注解解析库(仅编译期)}

这里需要解释一下,因为注解解析库只在程序编译期有用,没必要打包进APK。所以依赖解析库使用的关键字是annotationProcessor,这是google为gradle *** 件添加的特 *** ,表示只在编译期依赖,不会打包进最终APK。这也是为什么前面要把注解声明和注解解析拆分成两个库的原因。因为注解声明是一定要编译到最终APK的,而注解解析不需要。

4.2.3.4 实现AbstractProcessor

这是最复杂的一步,也是完成我们期望工作的重点。首先,我们在apt_processor中创建一个继承自AbstractProcessor的子类,重载其中四个 *** :

  • init()——此处初始化一个工具类
  • getSupportedSo *** ceVersion()——声明支持的J *** a版本,一般为最新版本
  • getSupportedAnnotationTypes()——声明支持的注解列表
  • process()——编译器回调 *** ,apt核心实现 ***
具体代码如下:
//@SupportedSo *** ceVersion(So *** ceVersion.RELEASE_7)//@SupportedAnnotationTypes("com.xibeixue.apt_annotation.BindViewTo")@AutoService(Processor.class)public class BindViewProcessor extends AbstractProcessor {?    private Elements mElementUtils;    private HashMap<String, BinderClassCreator> mCreatorMap = new HashMap<>();?    /**     * init *** 一般用于初始化一些用到的工具类,主要有     * processingEnvironment.getElementUtils(); 处理Element的工具类,用于获取程序的元素,例如包、类、 *** 。     * processingEnvironment.getTypeUtils(); 处理TypeMirror的工具类,用于取类信息     * processingEnvironment.getFiler(); 文件工具     * processingEnvironment.getMessager(); 错误处理工具     */    @Override    public synchronized void init(ProcessingEnvironment processingEnvironment) {        super.init(processingEnvironment);        mElementUtils = processingEnv.getElementUtils();    }?    /**     * 获取J *** a版本,一般用最新版本     * 也可以使用注解方式:@SupportedSo *** ceVersion(So *** ceVersion.RELEASE_7)     */    @Override    public So *** ceVersion getSupportedSo *** ceVersion() {        ret *** n So *** ceVersion.latestSupported();    }?    /**     * 获取目标注解列表     * 也可以使用注解方式:@SupportedAnnotationTypes("com.xibeixue.apt_annotation.BindViewTo")     */    @Override    public Set<String> getSupportedAnnotationTypes() {        HashSet<String> supportTypes = new LinkedHashSet<>();        supportTypes.add(BindViewTo.class.getCanonicalName());        ret *** n supportTypes;    }?    /**     * 编译期回调 *** ,apt核心实现 ***      * 包含所有使用目标注解的元素(Element)     */    @Override    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {        //扫描整个工程, 找出所有使用BindViewTo注解的元素        Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(BindViewTo.class);        //遍历元素, 为每一个类元素创建一个Creator        for (Element element : elements) {            //BindViewTo限定了只能属 *** 使用, 这里强转为变量元素VariableElement            VariableElement variableElement = (VariableElement) element;            //获取封装属 *** 元素的类元素TypeElement            TypeElement classElement = (TypeElement) variableElement.getEnclosingElement();            //获取简单类名            String fullClassName = classElement.getQualifiedName().toString();            BinderClassCreator creator = mCreatorMap.get(fullClassName);            //如果不存在, 则创建一个对应的Creator            if (creator == null) {                creator = new BinderClassCreator(mElementUtils.getPackageOf(classElement), classElement);                mCreatorMap.put(fullClassName, creator);?            }            //将需要绑定的变量和对应的view id存储到对应的Creator中            BindViewTo bindAnnotation = variableElement.getAnnotation(BindViewTo.class);            int id = bindAnnotation.value();            creator.putElement(id, variableElement);        }?        //每一个类将生成一个新的j *** a文件,其中包含绑定代码        for (String key : mCreatorMap.keySet()) {            BinderClassCreator binderClassCreator = mCreatorMap.get(key);            //通过j *** apoet构建生成J *** a类文件            J *** aFile j *** aFile = J *** aFile.builder(binderClassCreator.getPackageName(),                    binderClassCreator.generateJ *** aCode()).build();            try {                j *** aFile.writeTo(processingEnv.getFiler());            } catch (IOException e) {                e.printStackTrace();            }?        }        ret *** n false;    }}

其中,BinderClassCreator是代码生成相关 *** ,具体代码如下:

public class BinderClassCreator {?    public static final String ParamName = "rootView";?    private TypeElement mTypeElement;    private String mPackageName;    private String mBinderClassName;    private Map<Integer, VariableElement> mVariableElements = new HashMap<>();?    /**     * @param packageElement 包元素     * @param classElement   类元素     */    public BinderClassCreator(PackageElement packageElement, TypeElement classElement) {        this.mTypeElement = classElement;        mPackageName = packageElement.getQualifiedName().toString();        mBinderClassName = classElement.getSimpleName().toString() + "_ViewBinding";    }?    public void putElement(int id, VariableElement variableElement) {        mVariableElements.put(id, variableElement);    }?    public TypeSpec generateJ *** aCode() {        ret *** n TypeSpec.classBuilder(mBinderClassName)                //public 修饰类                .addModifiers(Modifier.PUBLIC)                //添加类的 ***                 .addMethod(generateMethod())                //构建J *** a类                .build();?    }?    private MethodSpec generateMethod() {        //获取全类名        ClassName className = ClassName.bestGuess(mTypeElement.getQualifiedName().toString());        //构建 *** -- *** 名        ret *** n MethodSpec.methodBuilder("bindView")                //public ***                 .addModifiers(Modifier.PUBLIC)                //返回void                .ret *** ns(void.class)                // *** 传参(参数全类名,参数名)                .addParameter(className, ParamName)                // *** 代码                .addCode(generateMethodCode())                .build();    }?    private String generateMethodCode() {        StringBuilder code = new StringBuilder();        for (int id : mVariableElements.keySet()) {            VariableElement variableElement = mVariableElements.get(id);            //变量名称            String name = variableElement.getSimpleName().toString();            //变量类型            String type = variableElement.asType().toString();            //rootView.name = (type)view.findViewById(id), 注意原类中变量声明不能为private,否则这里是获取不到的            String findViewCode = ParamName + "." + name + "=(" + type + ")" + ParamName + ".findViewById(" + id + ");\n";            code.append(findViewCode);?        }        ret *** n code.toString();    }?    public String getPackageName() {        ret *** n mPackageName;    }}

4.2.3.5 编译和调用

在MainActivity中调用,这里需要强调的是待绑定变量不能声明为private,原因在上面代码注释中已经解释了。

public class MainActivity extends AppCompatActivity {?    @BindViewTo(R.id.text)    public TextView mText;?    @Override    protected void onCreate(Bundle s *** edInstanceState) {        super.onCreate(s *** edInstanceState);        setContentView(R.layout.activity_ *** in);//这里的MainActivity需要先编译生成后才能调用        new MainActivity_ViewBinding().bindView(this);        //测试绑定是否成功        mText.setTextColor(Color.RED);    }}

此时,build或rebuild工程(需要先注掉MainActivity的调用),会看到在generatedJ *** a文件夹下生成了新的J *** a文件。



上面的调用方式需要先编译一次才能使用,当有多个Activity时比较繁琐,而且无法做到统一。

我们也可以选择另一种更简便的 *** ,即反射调用。新建工具类如下:

public class MyButterKnife {?        public static void bind(Activity activity) {            Class clazz = activity.getClass();            try {                Class bindViewClass = Class.forName(clazz.getName() + "_ViewBinding");                Method method = bindViewClass.getMethod("bindView", activity.getClass());                method.invoke(bindViewClass.newInstance(), activity);            } catch (Exception e) {                e.printStackTrace();            }        }?}

调用方式改为:

    @Override    protected void onCreate(Bundle s *** edInstanceState) {        super.onCreate(s *** edInstanceState);        setContentView(R.layout.activity_ *** in);?        //通过反射调用        MyButterKnife.bind(this);?        //测试绑定是否成功        mText.setTextColor(Color.RED);    }

此方式虽然也会稍微影响 *** 能,但依然比直接使用运行时注解高效得多。

4.2.4 APT注解处理器总结

说到底,APT是一个编译器工具,是一个非常好的从源码到编译期的过渡解析工具。虽然结合J *** aPoet技术被各大框架使用,但是依然存在固有的 *** ,比如变量不能私有,依然要采用反射调用等,普通开发者可斟酌使用。

个人认为APT有如下优点:

  1. 配置方式,替换文件配置方式,改为代码内配置,提高程序内聚 ***
  2. 代码精简,一劳永逸,省去繁琐复杂的格式化代码,适合团队内推广

以上优点同时也是缺点,因为很多代码都在后台生成,会对新同学造成理解困难,影响其对整体架构的理解,增加学习成本。

近期研究热修复和APT,发现从我们写完成代码,到代码真正执行,期间还真是有大把的“空子”可以钻啊,借图 *** rk一下。


4.3 j *** ac源码分析

4.3.1 j *** ac概述

我们都知道 *.j *** a 文件要首先被编译成 *.class 文件才能被 JVM 认识,这部分的工作主要由 J *** ac 来完成,类似于 J *** ac 这样的我们称之为前端编译器;

但是 *.class 文件也不是机器语言,怎么才能让机器识别呢?就需要 JVM 将 *.class 文件编译成机器码,这部分工作由JIT 编译器完成;

除了这两种编译器,还有一种直接把 *.j *** a 文件编译成本地机器码的编译器,我们称之AOT 编译器。


4.3.2 j *** ac 的编译过程

首先,我们先导一份 j *** ac 的源码(基于 openjdk8)出来,下载 *** :https://hg.openjdk.j *** a.net/jdk8/jdk8/langtools/archive/tip.tar.gz,然后将 JDK_SRC_HOME/langtools/src/share/classes/com/sun 目录下的源文件全部 *** 到工程的源码目录中,生成的 目录如下:

我们执行 com.sun.tools.j *** ac.Main 的 *** in *** ,就和我们在命令窗口中使用 j *** ac 命令一样:



从 Sun J *** ac 的代码来看,编译过程大致可以分为三个步骤:

  • 解析和填充符号表过程
  • *** 式注解处理器的注解处理过程
  • 分析和字节码生成过程

这三个步骤所做的工作内容大致如下:



这三个步骤之间的关系和交互顺序如下图所示,可以看到如果注解处理器在处理注解期间对语法树进行了修改,编译器将回到解析和填充符号表的过程进行重新处理,直到注解处理器没有再对语法树进行修改为止。



J *** ac 编译的入口是 com.sun.tools.j *** ac. *** in.J *** aCompiler 类,上述三个步骤的代码都集中在这个类的 compile() 和 compile2() 中:


4.3.3 j *** ac编译器编译程序的步骤

词法分析  首先是读取源代码,找出这些字节中哪些是我们定义的语法关键词,如J *** a中的if、else、for等关键词   语法分析的结果:从源代码中找出一些规范化的token流    注:token是一种认证机制?语法分析   检查关键词组合在一起是不是J *** a语言规范,如if后面是不是紧跟着一个布尔表达式。   语法分析的结果:形成一个符合J *** a语言规范的抽象语法树?语义分析   把一些难懂的、复杂的语法转化为更加简单的语法   语义分析的结果:完成复杂语法到简单语法的简化,如将foreach语句转化成for循环结果,还有注解等。最后形成一个注解过后的抽象语法树,这颗语法树更接近目标语言的语法规则?生成字节码  通过字节码生成器生成字节码,根据经过注解的抽象语法树生成字节码,也就是将一个数据结构转化成另一个数据结构  代码生成器的结果:生成符合J *** a虚拟机规范的字节码?注:抽象语法树   在计算机科学中,抽象语法树是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构

2022-2023设计趋势 *** UX报告· NFT虚拟形象篇(上)

编辑导语:2017年,两个开发者机缘巧合下带着一万多个像素头像来到了以太坊生态中,由此开发出了世界上之一个NFT项目——CryptoPunks。到现在,都有哪些极具影响力的虚拟形象诞生呢?本文介绍了比较有特色的十二款NFT形象作品,一起来看一下吧。

01 虚拟形象

1. 虚拟形象的诞生-CryptoPunks

2017 年,正值以太坊生态开始发力之时,原本两个不在加密货币圈子的开发者机缘巧合之下带着一万多个像素头像来到了这个生态当中,并由此开发出了世界上之一个NFT项目——CryptoPunks。

原本是做移动 App 开发的两人 John 和Matt,致力于从 *** 和实用程式到 *** 基础设施再到数位设计和艺术的各种项目。

在 2017 年初团队从伦敦Punks场景和cyberpunk *** 和小说中汲取灵感, *** 开发了一个多元化像素角色生成器,并创造了许多充满朋克精神的像素角色头像,当他们在想围绕着这些头像还能进一步做一点什么事的时候,他们关注到了区块链和当时逐渐火热的以太坊。

于是他们便决定将这些像素头像放到区块链上,让这些本身也十分具有个 *** 的像素头像通过区块链的特 *** 可以得到验证,并让它们可以被他人拥有或者允许被他人转给其他人。

由此,世界上真正意义上之一个 NFT 形象项目 CryptoPunks 诞生了。

CryptoPunks一经发布,就遭到了全球的关注与疯抢。虽然CryptoPunks初期是免费获得,但是数位肖像的稀有 *** 和艺术 *** ,让NFT玩家的需求量增加,从而导致 *** 一路飞涨不下。

它开创 *** 地将图像作为加密资产带入到了加密货币领域里,在当时各类 Token 满天飞的时候,作为一股清流给了众多从业者新的启发。同时又将不同的形象作为特色,让收藏家不再是单一维度进行 *** 上售卖,而是从更多艺术或生活的维度进行欣赏。

2. 虚拟形象的价值

至此NFT形象开始起飞,艺术家与创作者们纷纷将目光投向了NFT进行创作。

投身于NFT的艺术家或者创作者则可以向以太坊区块链上传并认证任何数字资产进行铸币,建立一份包含 *** 、所有权和 *** 记录的NFT代码化 *** 证档案。这一 *** 让艺术家或创作者既能够通过NFT向全世界展示自己的想法与创意,扩充自身影响力,又能通过NFT整个销售模式给自己带来可观的销售收入。

NFT形象由于为多个单独元素随机组合生成具有唯一 *** 的形象,故此它的独特 *** 与稀有 *** 让某一款形象比其他形象更有价值。

同一个项目中具有更多稀有属 *** 的形象 *** 更会一路攀升。同时对于藏家来说,稀有 *** 并不是唯一能决定NFT价值的因素,有的形象可能会因为收藏家喜欢这样的外观,或者是曾拥有藏家的知名度而 *** 飙升。

NFT形象也从相对边缘的收藏品慢慢向主流艺术进行转变,其中一部分藏品已经在佳士得和苏富比会场进行拍卖。这一行为无疑是能给NFT带来更高的 *** 与商业价值。

NFT市场经过2021年的洗礼,在不断起伏之下变得越来越成熟。

细心的藏家不难发现,越来越多的专业的艺术家、创作团队开始参与其中,他们带来好莱坞级别的NFT作品,同时给藏家们也带来丰富的艺术享受。

举例而言,由RTFKT Studios与艺术家村上隆所创作的CLONE X 系列给人于无尽幻想与延展空间,还有新崛起的HAPE Prime成为时下年轻族群追逐的焦点,还有由combrisi X flatizy 手工 *** 的非生成的S *** *** 系列,以世界各地的神话人物为原型的Godpod系列等等,接下来我们将一一介绍比较有特色的十二款NFT形象作品。

02 极具影响力的虚拟形象

1. CLONE X-RTFKT Studios&村上隆

由虚拟时尚品牌 RTFKT Studios 和村上隆联合创作的CLONE X,于2021年11月开始发售。

CLONE X 是一款拥有1 *** 11个 3D 角色的 Avatar 项目,同时是对 CryptoPunks 明确的致敬项目,不同的是 CLONE X 是带有 3D 骨架 *** 的模型。这意味着拥有者可以将他们使用在 AR 滤镜、Zoom *** 会议或游戏等,也可作为往后进入「元宇宙」的形象。

该款设计每个角色都有随机分配特征组合而成的外观,同时村上隆将角色的眼睛、嘴巴、头部装饰等部分进行拥有其专属风格的 *** 美学的的特殊设计, *** 出「特色装扮」。拥有CLONE X盲盒的藏家,可以通过官网的铸造页面进行随机生成NFT形象。目前已经有 *** 00+用户拥有该产品,更便宜的头像为18.5ETH。

Clone X的故事背景是在未来,有三名来自德拉科星座轨道星的外星人来到地球,这些星际游客来加速我们向非物质存在的进化。他们计划将所有人类意识转化为高级 *** 形式,以创造终极元宇宙。故而他们将人们的意识从原本的身体中抽出,再将抽出的意识放入到数码 Clone X 替身(digital CloneX *** atars),让人类进化到下一个阶段,这样人们就有更多的时间和体力能够探索更远的星球或是星系,不用担心生老病死。

拥有该NFT形象的持有者,会拥有一个 *** 的太空舱NFT。根据资讯信息,Clone X将在不久之后可以打造一个属于自己的社区平台,玩家所拥有的Clone X形象成为他们入场的 *** 。同时在平台里可能拥有各大联名潮流内容产品,或者可提供玩家在元宇宙中自创或者使用3D档案,个 *** 化的Clone时尚配件,穿着特色形象参与时装周等各色活动……

在这个故事背景下,不同的CLONE X拥有不同的DNA特质,也 *** 了不同的种族。

其中人类占流通量约50%,但是其中有少部分人会有有特殊皮肤特质,还有10%的人类能得到「村上特质」。机器人占有25%,恶魔、天使各占有8.5%,爬虫类种族约占1%,不死族占有0.5%流通量。最为稀少的外星人占有0.13%,其中会有15%会得到「村上特质」。

除此以外还会有16款艺术家版本,会在铸造中随机出现。

这些形象中,如果没有「村上特质」的NFT则可以进行100万美元的商业用途。如果拥有「村上特质」则不允许作为商业用途使用。这不难让人想象,在现实场景下,拥有Clone X形象的人可以在原有形象上再进行二次创作或者商业发布。在元宇宙中,持有Clone XNFT的持有者能够提升自身价值与知名度,也会有相应的商机。

最贵价的十款 *** X形象:

其中4542号形象,他涵盖了恶魔种族以及多款村上隆特质,整体稀少程度较高,故而整体交易 *** 为更高。售价为 ETH 100,000,000,000,000,折合为 人民币 ¥1 *** 4,769,769,700,000,000.00,达到了需要不停核算0来确认总价的地步。

趋势启发:

  • NFT形象的 *** 公司与创作艺术家知名度的高低,能够极大地带动该款形象是否受到大家的关注,作家自身的流量能够为项目带来庞大的粉丝量, *** 公司往期优质作品也能很提升玩家对新项目的期待值。
  • 有趣的项目故事能拓展NFT形象的运营,在原有知名度上,通过故事将每个形象的特质属 *** 进行合理化与趣味化。从预告到拥有的仪式感,更让玩家能够更细致的体验到NFT的精细打磨与强化关注。
  • 在原有艺术家或设计师十分著名的情况下,在NFT形象中加入或者强化创作者的个人标签或者特色,能让NFT的辨识度与知名度更上一个台阶,也能够提升拥有者的价值感与同理 *** ,满足拥有者的优越感与归属 *** 。拉动观望者对项目的关注度与敏感度。

2. HAPE PRIME-Digimental

HAPE PRIME是由知名3D艺术工作室Digimental设计的,共有81 *** 个,这些3D猿猴NFT的设计非常巧妙,融合了很多常见的街头元素。HAPE NFT设计初稿在网上公开后,就马上受到了社会各界的喜爱并引起了热烈的讨论。正如同它自己的介绍:高清,潮流视觉,将猿宇宙更进一步风靡世界。

通过穿着不同质感的服装,给猿猴增加独一无二的个 *** 与特色。由于HAPE PRIME的大热故而带动了NFT的形象逐渐由2D转向3D设计。8200+用户拥有该产品,更便宜的头像为0.74ETH。

HAPE PRIME以街头时尚和运动休闲装为特色的时尚运动。它是 90 年代嘻哈和非常流行的时尚文化的化身,不同的猿猴会随机分配颜色和各种质感特色。纵然每个形象都不曾明显的表露出男女的特色,但是随机分配的服装与发型,让角色展示出明显的男女或 *** 格的趋向 *** 。

这是一组黑白造型的海报,整体洒脱又纯粹。给人一种霸气又沉稳内敛的感受。

接下来是一组炫彩造型,形象元素传神地展示了每个形象的不同 *** 格。

千人千面,不过是如此。虽然大家都是同一基础角色进行叠加变化,但是随机元素赋予角色更多的可能 *** 与独特的 *** 格。背景上也有与角色强关联的香蕉背景。整体打光与材质的渲染,让香蕉背景并不突兀,反而充满趣味。

贵价的十款潮流猿形象:

其中戴着帽子穿着白色棒球服的4269是众多玩家最为关注的HAPE PRIME NFT形象。

趋势启发:

  • 在HAPE PRIME中着重显示了不同潮流服装对于NFT的影响,人们会根据服饰的潮流与形象的统一或个 *** 程度进行购买,并由此引领购买趋势。将实际服装与形象相结合,通过NFT形象表达一种形象态度,由此强化NFT形象记忆点与商业价值。
  • 多风格样式,受众面更广。虽然设计者更钟情于街头风格,但是从多款形象中也可以看到有照顾到东方文化。在前期的雏形项目中,设计者就有多风格样式进行试水,故而HAPE PRIME的设计方向则会更加精准,更受大众所喜爱。

3. *** IRICS-Combrisi & Flatizy

S *** *** 是由combrisi X flatizy 手工 *** 的非生成系列,将不同领域的icon缩影成太空人,极具未来感,简洁统一的造型也使得一系列的S *** *** 辨识度高,可拓展 *** 非常强。而不同新颖写实渲染质感和设计概念,让每款S *** *** 都是独一无二的。

每款S *** c背后都有非常酷、非常独特的设计背景,可以在官方的insgram上详细了解。通过讲述它们不同的故事,可以感受到每个角色的独特且生动的 *** 格。

下面介绍几类比较有特色的 *** ir *** ,例如去年冬季推出的Hyggel S *** *** 系列,是一群有着毛茸茸质感的S *** *** ,丰富蓬松的绒毛给人以舒适感。

复古风格的 *** ir *** :

将 *** ir *** 形象与大众熟知的艺术风格进行结合,例如 *** *** ir *** 和波普 *** ir *** :

Nat *** a S *** c则是全身铺满小花小草,就像与大自然融为一体,与自然世界密切共生。

趋势启发:

  • 让故事场景化,让场景形象化。一个有故事的NFT形象,让持有者在拥有的同时会更加深入了解形象背后的故事,从而加深NFT的记忆点与品牌 *** 。
  • 使用统一的形象结构,配合不同质感的服装,让形象不仅仅是一张 *** ,更是一个 *** 度质感与故事的丰富,从而成为一个活泼生动的案例,赋予持有者深度与内涵,提升形象厚度。

4. GODPOD-muzixiiistudio

来自 *** 工作室muzixiii studio的nft作品,提供最新的 *** *** 服务以响应元宇宙。以世界各地的神话人物为原型,创作出一个个造型简约可爱的形象。

Muzixiii studio是专业的3D影像工作团队,曾经与漫威、迪士尼等企业合作过,并为华硕、宏碁、微星科技等知名资讯品牌 *** 过影片。

会使用神明的形象 *** NFT,是因为Amber观察到,现代的人因为压力大,所以更重视疗愈、 *** 跟心灵健康,而GodPod便是一个新的 *** *** ,大家不用再依附于 *** 体系之下寻求安慰,而是可以在去中心化的世界中找到精神的寄托。

小神明的形象,不仅包含 *** 众所皆知的神明,还有更多来自世界各地,大家不一定熟悉的 *** ,甚至邀请大家自行创造,让心中的 *** 能具象化,期许小神明能为大家带来心灵的平衡及健康。

除了可爱的神明NFT,Discord社群上也会搭配多元疗愈的题材,例如塔罗牌、人类图、星座…等等。大家每天也都可以在社群上抽卡牌、测运势,卡牌内有许多建议与鼓励, 带给Goody们满满的心灵鸡汤、正能量,让疲惫的心灵能获得小小的救赎感 。

这些动态emoji也让这些可爱的神明变得生动起来,被应用Discord社群成员之间的聊天中。

所以尽管Godpod在没正式发行前,Discord社群上已经有近一万人在关注。

趋势启发:

  • 趣味素材的前期预热,以及动图的细节展现与搞笑故事 *** ,都能给尚未发行的NFT带来极大的吸引里,带动用户持续的关注。
  • 形象NFT不仅仅局限于在外头像或穿着的热潮,也可以在NTF形象中体现更多可能 *** 。元宇宙的形象可以在内心或者压力上进行发力,或者是引导用户了解自己的内在,让 *** 褪去原有老牌的风格,以一种全新更符合年轻人预期的感受去体现。
  • 运营时充分展示NFT形象独有的优势,针对 *** 进行游戏玩法拓展品牌影响力。延展品牌衍生品应用在实际生活中,让形象传播更为广泛。

5. AZUKI-TeamAzuki

Azuki 是现在市场中成交量很大的蓝筹 NFT 项目,其中的角色和元素受到日本动漫影响深刻。他的世界背景是基于“The Garden”建立,希望用户通过持有其NFT参与到这个世界的建设以及运营。

角色早期是由《守望先锋》的角色设计师Arnold Tsang业余时间积累创作的,Azuki的角色大部分都是滑板少年,风格特立,其中不乏叛逆、追求自我价值的精神。

Azuki的画风也是在现在市场不可多得,运用日系漫画中干净、干练的笔触,和其他三维、Meme 的 NFT 画风拉开差距,让人印象深刻。角色风格分为四类 —— 人类、蓝、红、灵魂,其交易 *** 和稀缺呈成正相关。

下图为其中两款人物形象:

虽然整体NFT是以2D画风为主,但是还是有部分服装进行了 *** 度的创作,以带给持有者三维立体的感受,同时进行实体服装实体的生产,让NFT形象的同理 *** 带入到实际生活中。

上图为实际生活中穿着Azuki 夹克的受访照片。

BeanZ 同是 Azuki 团队根据 The Garden 世界创作的 NFT 项目,寓意花园中的 *** ,造型可爱。

Azuki与Mek *** ers一致,也是有缩小版的NFT造型,但是整体风格也是延续了2D效果,在3D当道的NFT形象中独树一帜。

趋势启发:

每个人都曾有过当动漫人物的梦想,而这款NFT的形象让用户更好的融入到The Garden的世界观中让每个人都实现动漫梦,同时 *** 度的 *** 素材和实体服装也让持有者更有带入感。

而用户也自发进行虚拟形象实体化的cos行为。

6. The Sheep Fellas-Met *** erse

The Sheep Fellas是Met *** erse的一种新型品牌,由 BSC 区块链 (pentas.io) 中的部族和帮派整理出来的毛茸茸的 3d Sheep NFT *** 。每个氏族都有自己的故事和目的,这是为了将整个元宇宙中多品种的所有绵羊联合起来。这不仅是一种NFT,它是一种文化。

稀有度:在每个氏族中,他们由 1 个 Alpha 领导,由 Genesis 和 Superiors 支持。每个氏族的所有士兵都不是来自 Korleno 家族。他们被引入氏族。每只羊都是独一无二的,因为它是非生成的 3d 和纯 1 对 1 手动 *** 和渲染的(Alpha/Genesis/Superiors/Sol *** rs四个等级)。

稀有度1【Alpha】:Alpha 是每个氏族的领袖。每个氏族只有 1 个 alpha。它有自己的故事和个 *** 。它具有 *** 其角色的 3d 背景。

稀有度2【Genesis】:每个氏族有 5 – 8 个Genesis。他们是其他人中最强大的角色。他们与他们的 Alpha 密切合作。每个角色都有自己的特色,他们的主要目的是服务和保护他们的Alpha。他们也有自己的 3d 背景,根据他们的个 *** 进行单独设计与渲染。

稀有度3【Superiors】:上等羊是Genesis的助手。他们将根据他们的起源顺序行事。他们的主要目的是保护Alpha 和氏族。他们的背景是二维图形。

稀有度4【Sol *** rs】:士兵是羊群中最常见的角色。他们的主要目的是服务和保护他们的氏族,只是为了在氏族中生存。它有一个通用和干净的背景。

趋势启发:

The Sheep Fellas开拓了一种新的玩法,不再是单一不同形象的NFT,他们是以家族式作为形象结构。每一款NFT的形象都有自己的使命,由这个使命而延展为不同的形象展示侧重,让整个项目拥有一致 *** 与结构 *** 。这也拓展了大家创作NFT的结构思维,不再是因为世界而创造不同的形象,而是根据帮派或家族而进行设计上的细化和归属感的创作。

7. INTO THE MET *** ERSE-Adidas Originals

Adidas 与《Bored Ape Yacht Club》、Gmoney 以及 Punks Comic 背后团队共同打造了一款 NFT。名为《Into the Met *** erse》的 adidas NFT,拥有者将获得对各种 adidas Originals 体验与产品的独家访问权,随着 NFT 作为虚拟土地与免费联乘单品的 *** ,拥有者能够在基于区块链的游戏《The Sandbox》穿戴相关虚拟设备。

这是adidas的之一个NFT或不可代替币系列—本质上是经过验证的数字收藏品。NFT充当基于区块链的所有权证书,允许对作品进行身份验证、购买和收集。该品牌与NFT中一些最知名的任务合作创建了该系列:Bored Ape Yacht Club、gmoney和朋克漫画创作者。

adidas在Into the Met *** erse上的合作者包括 *** 猿人头像的Bored Ape Yacht Club, adidas将此次发布 *** 为与粉丝互动并加入“创意前沿”的一种方式。

作为此次发布的一部分,阿迪达斯还购买了其首个 NFT – 猿 #8774。该俱乐部为所有者提供了一些特权,阿迪达斯现在可以使用这些特权。阿迪达斯还在 The Sandbox 内获得了一块虚拟土地,计划在其中填充“独家内容和体验”。

带有实体元素的NFT漫画Punks Comic背后的艺术家们也参与了adidas的收藏,数字产品将用于The Sandbox的基于区块链的游戏世界以及其他平台,而实物产品将包括连帽衫、运动服和gmoney标志 *** 的橙色无檐 *** 帽。虽然阿迪达斯已经接受了 NFT,但该技术存在争议因为它所需的大量的内容与相关前沿的技术的支持。

趋势启发:

将2D三维化,将用户购买的商品与NFT进行结合,在购买商品的同时可以获取到NFT的虚拟形象,将商业化推广进行破壁元尝试。不仅仅是商业的联合,还拓展了商品与虚拟人物的互动 *** ,满足了拥有者与品牌的联动感。

03 未来启示

随着NFT角色的热度增加,不同的画风维度与视觉展示方式都让用户在浏览拥有的同时,延展扩张了无数的遐想。或许你在这个世界中只是平平无奇的普通人,而在元宇宙中你则是拥有超能力,惊艳全球的著名人士。也许不久的某一天,每个人都能进入不同的元宇宙,在不同的元宇宙中又拥有不一样的形象,来满足实现自身的无限可能 *** 与创造力。

注:文章部分内容来源于 *** ,如有侵权请及时联系我们,感谢。

来源公众号: *** *** UX(ID:tencent_isux), *** 社交用户体验设计,简称 *** UX (Internet Social User Experience),是 *** 核心设计团队, 负责 *** 社交 *** 相关产品的用户体验设计与研究。

本文由人人都是产品经理合作媒体@ *** *** UX 授权发布于人人都是产品经理,未经许可,禁止转载。

题图来自 Unsplash,基于CC0协议。

七个自动写文案的神器

文案这道坎,谁走谁知道。很多时候写文案苦于没有选题、没有素材、没写思路......找了7种自动写文案的工具,保证一定对你有用:

1.Get智能写作

主页是一个搜索框,下边默认有热点发现、标题推荐、智能改写和质量检测四个选项,非常适合不知道写什么、起标题的小伙伴。搜索框输入你想写的内容,比如我找了【新媒体运营】,素材里会找到别人写的相关文章。付费内容的版块,还能看到模板、文集、知识、段落和金句。

2.秘塔写作猫

比较常用的功能是全文改写,用AI找到更好的表达方式。比如你不太擅长写正式的、官方的话,可以先用自己的话口述,用AI改写一两遍就特别正式了。古文改写挺好玩的,AI会整出一些新活,让你想都没想到。

3.彩虹屁生成器

不会哄对象的福音,自动生成各种彩虹屁,撩到对象心痒痒。

再也不担心,自己不会说甜甜的情话了。

4.毒鸡汤生成器

每天生活不清醒怎么办?

来碗毒鸡汤,立马人间清醒。

特别是不想做事的时候,看一两条,立马泪目。

5.kalvin文章生成器

懒人福音,只需要给它关键词,就能还给你一篇文章。

但无奈官方吐槽,它是 *** 不通文章生成器。

写出来的效果也的确如此,丝毫没有虚假宣传。

奔着找乐子的心态,让AI写作文去。

6.Aii文章生成器

同样是一个,你给它关键词,它还给你文章的AI。基本原理是根据关键词,结合搜索引擎SEO的优化技巧,快速生产被搜索引擎收录高的热门文章。写出来的东西还算靠谱,逻辑也比较清晰。AI整理出的一些思路还可以作为参考。

7.Essaybot

免费的英文写作参考软件。输入简单的关键词,它会显示出不同的文章片段。比如搜索“new media”,会显示出许多含有关键词的英文文章。

有了这些神器,无论你是工作、哄对象还是写英文 *** ,都可以更便捷地进行啦。当然啦,能原创的时候,更好还是做原创!


当你不想写稿了,这几款「智能写作工具」能帮上忙吗?

从上小学开始,我们就和「写作」这件事打交道了:小时候写周记、写思想汇报,长大了写 *** 、写文案、写工作总结……写东西时才思泉涌时也就罢了,要在灵感枯竭时硬生生地「憋」出字来,才真是让人痛不欲生。

写作之苦,并非今日之人才有,大文豪苏轼就说「人生识字忧患始,姓名粗记可以休。」有时候想想如果有一天能讲句话就有人帮你把心中所想完美地写出来,甚至输入几个词就能表达心中所想该多好。

当再一次对着字数为零的 Word 文档发呆,而稿件截止日期又迫在眉睫时, A 君带着「让 AI 帮我写吧」这样淳朴又美好愿望,开始了对 *** 上传说中的智能写作工具的测试,本次测试的工具均为网页版,使用特别方便。

智能之一步:起标题

万事开头难,写文章的之一步常常是想标题,打开之一款测试的工具——《易撰》,让我们饱含期待地看看它能给出什么让人眼前一亮的标题。

《易撰》是一款综合 *** 较强的自媒体人写稿工具,有电商榜单、数据检测、话题库查询等功能,但是大部分的功能都需要购买会员才能用,好在「起名」是免费的。

「爆文标题助手」这样简单粗暴的名字不免让人内心涌现出不妙的感觉,输入「苹果 *** 」「降价」两个关键词后果然生出了不少引诱力极强的标题:

选取了其中几个,列举如下:

  • 国产 *** 的狼来了,5 小时成交额 5 亿,苹果 *** ,降价背后的焦虑
  • 6 月最不值得入手的苹果 *** 一降价,国产 *** 还怎么玩?
  • 库克又赢了!苹果 *** 又降价至 3499 元,网友:终于等到你
  • 制裁苹果是幻想?库克先「认怂」,苹果 *** 大降价吗? *** 二值得购买的苹果 *** 有哪些?

观察这几个标题,从挑起国产 *** 和苹果 *** 的斗争到薛定谔的库克输赢论,的的确确是拉爆了话题度,然而里面一些数据的真假和时效就不得而知了。

为了让测试更加好玩,又尝试了以前段时间频频被 *** 畜的「鸡汤」为主题,输入「喝鸡汤」和「长生不老」,让《易撰》来命题,这次结果就更有趣了,有扯上人生哲理的,如:

你这么爱喝鸡汤,是因为肉被别人吃了

有骇人听闻,使你忍不住一探究竟的:

喝鸡汤出事,因为姐姐在鸡汤里面放了这东西

甚至还能整出集穿越、玄幻、狗血家庭伦理于一身的小说楔子:

《空间 *** 奋斗记》她魂穿六零身带空间超市,天天喝鸡汤,大姑姐吃鸡肉,到底是你坐月子还是我?

看罢才知道原来一碗鸡汤还能玩出那么多的花样,相信连有十多年鸡汤烹调经验的炊事员老冯也要自愧不如。

除了起名,《易撰》还有一个免费的功能——检查文章质量,主要是检查有无违规内容和原创程度。

随便从网上找了一篇名为《彭祖活了 800 岁竟然是因为一碗鸡汤?》的真正论证喝喝鸡汤长生不老的文章丢进去检查。从反馈结果看,文章尚算规范,就是原创度较低。

智能第二步:文章生成

有了名字和检查工具后,下一步就是写文章了。按照由简单到复杂的规律,首先找来了三款网上热门的文章生成器。它们使用起来简单粗暴,在写文章方面,哪怕没有效果,至少拥有「笑果」。

之一款名叫《营销号文案生成器》的工具,从输入到产出,只需使用者给出一个标题,比如:喝鸡汤能长生不老。

敢叫营销号文章生成器,自然不负盛名,这个工具产出的文章不论是标题还是内容都不叫人失望,同一个内容给你变着法子翻来覆去换表达,没有一点建设 *** 的新内容。

第二款工具名为《 *** 不通文章生成器》,用起来同样只需输入一个标题,产出的文章和前面这一款更大的区别就是它不仅文章的长度可观,而且擅长引经据典。

然而这样的文章粗看你会觉得它字字扣题,反复重申,细看则会发现反反复复说的都是废话,除了表达标题内容对作者意义重大,并无任何实质内容。

名字稍微严肃的《AII 文章生成器》效果也不见得很好。

输入了文章的关键词后,出来的文章终于稍微有点知识科普的意味了,但是却只关注了前面的「鸡汤」,没有注意后面的「长生不老」。

看来太简单的东西只能用来娱乐,生成的文章上不了台面,接下来唯有尝试使用更加复杂一点的智能写作工具了。当发现《GI *** O 写作机器人》的时候,它干净简洁、指向明确的卡片式主页立刻引起了我的兴趣。

当选择太过丰富时,反而让人不知所措,毕竟这款工具大部分功能的使用都要消耗积分(一般为生成文章为 5 分,每分约等于一元人民币),不谨慎挑选正确的模板,试错成本很高。

好在用户前期能通过注册和分享好友获得少量的免费积分,完成试用是勉强足够的。

首先来到「热点写作」版面,根据当日的热搜选择了「 *** 放榜」这个话题,点击「智能写作」,若干篇由 AI 书写的文章就自动生成了,左右滑动挑选最满意的文章进入后即可 *** 编辑。

在编辑界面中,我们可以利用素材智能联想功能随意调换或扩写段落,调换段落免费,但每次扩写段落消耗 2 个积分。

利用网页自带的查重功能还可以与数据库中的其他文本进行比对,得出相似度。刚才生成的这篇文章网页显示相似度为 0。

但是当我们用之前《易撰》的原创 *** 检测工具再检测时,却只有 47% 的原创度,看来 AI 写作也免不了是东拼西凑,并且仔细看这篇文章的段与段之间也缺乏衔接。

把念念不忘的老题目「喝鸡汤能长生不老」丢进网页中进行测试,效果又如何呢?

文章确实是流畅的了,甚至还教给了我们公鸡肉和母鸡肉是要加以区分的,然而还是老问题,「长生不老」这个点不见了,也有可能是这个词中能和鸡汤关联到的只有「生」这个字,所以不断给我们寻找和女子生产有关的话题吧。

除了「热点写作」,《易撰》还提供听起来十分人 *** 化的「提纲写作」服务。

「提纲写作」允许用户创建自己的私人提纲,「主题」和「关键词」是文章大致的覆盖范围(决定程序该从哪些方面为你找资料),下方蓝色框框内的「提纲」为文章内的小标题,「提纲关键词」是该小标题下的主要内容。

要求纯良的 AI 去论证一个错误的话题(喝鸡汤长生不老)也许太苛刻了,但写一篇《宝可梦传说:阿尔宙斯》的介绍 *** 文章应该就不难了吧?

初稿的小标题和下面的段落对应上还是有点「答非所问」的感觉,但是花了 5 分钟用「素材智能联想功能」进行调换和扩写段落后,第二版的文章应付 5 秒钟阅读型的读者来说已经绰绰有余。

▲ 初版

▲ 第二版

最后,《易撰》的「思想学习」报告智能撰写的功能应该也能帮到不少的 *** *** 朋友,然而此时用户积分已经耗尽,实在不想花 5 块钱去写一篇思想汇报,有兴趣的读者请自行尝试。

除了生成正儿八经的说理 *** 散文的文章生成器们,A 君还找到了能写出剧本和小 *** 的「智能」工具。

爬取了海量国产电视剧数据的《剧本生成器》小程序可以帮你生成一段短剧梗概。提供故事题材和两个主要任务的名字后,一段「引人入胜」的剧情介绍倚马可待。

▲ 炊事员和薛司令的精彩故事永不落幕

输入题目(不重要)、学科和两个关键词后《小 *** 生成器》帮助 *** 苦手轻松写出 3000 字长文,一秒交作业再不是梦。

如果学科和关键词选择正确,而讨论的话题又比较简单,同时适合泛泛而谈时,《小 *** 生成器》给出的文章其实随便一看可以骗过不少人,假如再经过一定的编辑说不定还真就能帮你的期末作业拿个及格的分数、

智能第三步:降低重复率

如果说前面的几个工具还是「仅供娱乐」,那么接下来这款《智能伪原创写作工具》就真的有点实用 *** 了。

当我们把文章 *** 进网站后,网站会自动对文章的内容进行分析,再将词语同义替换、句子成分打散重组,最后处理成符合语法的「新」文章以降低重复率。

比如把:

古时候有一个叫彭祖的人,传说是大禹的玄孙。彭祖的母亲怀上彭祖之后没多久,彭祖的 *** 就死了……

改成:

在古代,有一个人叫彭祖。据说他是大禹的曾孙。彭祖的母亲怀上彭祖后不久,彭祖的 *** 去世了。

▲ 修改前

▲ 修改后

改动前《彭祖活了 800 岁竟然是因为一碗鸡汤?》一文原创分值只有 35%,改动后原创分值立刻提到接近 70%,「降重」从此不麻烦。

一轮测试下来,能自动写出稿件又能骗过编辑明察秋毫的法眼的文章生成工具最终还是没能找到,不过寻找的过程倒是产出了这篇文章以馈后来者。在那个文章「立等可取」的未来来临之前就让我们先精进文笔、耐心等待吧。

从此告别写作困扰!这5个自动写文案神器助力你创作绝佳文案


面对“无从下手”的写文案难题,你或许在电脑前坐上一两个小时都百思不得其解。然而,这篇文章即将为你揭秘十位行业大佬们背地里默默使用的自动写文案神器。如今,不再为文案创作烦恼,只需5分钟即可轻松撰写出迅速热销的十万字爆款文章。

在追求文案 *** 的道路上,不论你身处职场新媒体行业,还是自媒体领域的内容创作者,都能借助这些网站大幅提升你的工作效能。

一、稿见AI助手

稿见AI是一款智能化的助手工具,拥有强大的功能和智能的交互体验。它可以帮助用户完成各种任务,如自动回答问题、进行语言翻译、生成内容、 *** 文案等。无论是学习、工作还是生活中遇到的各种需求,AI助手都能快速响应并提供准确的帮助。

它的功能丰富多样,可以从事多个领域的任务,包括但不限于文书写作、数据分析、舆情监测、语音识别等。借助AI助手,用户不仅能提升工作效率,还能获得更便捷的生 *** 验。无论是职场中的专业人士还是日常生活中的普通用户,都可以轻松享受到AI助手带来的便利和智能化的服务。

二、毒鸡汤文案生成器

毒鸡汤文案生成器害怕写出来的汶上太平淡加点毒鸡汤句子或许能带来意想不到的效果这个网站非常简洁并且完全免费看到喜欢的直接 *** 直接用没有喜欢的就再来一条。


三、藏头诗生成器

藏头诗生成器输入关键词就能生成藏头诗,这个工具没别的用上就能提升文案的 *** ,据说他还是个表白神器,用了这个文案是不是成功的几率都能提高一个概率

四、get智能写作

Get智能写作十万加的文案模板轻松套用,全网热点选题,实时帮你捕捉热度趋势!还可以检测原创度,有标题脑洞功能,发散你的思维,取出画龙点睛的标题

五、完美韵脚

完美韵脚对账句子必备,只需要搜索关键词,网站就鞥智能识别词语的韵脚生成押韵结果。

AI工具的好用便捷 *** 将我们的工作和生活提升到了一个全新的层次。它们能够帮助我们快速完成各种任务,提供准确的信息和智能的建议。无论是在学习、工作还是日常生活中,AI工具都能够大大节省时间和精力,让我们更加高效和便捷地处理事务。借助AI工具,我们能够更好地应对挑战,实现目标,同时拥有更多的 *** 和灵感。享受它们带来的便利和创造力的激发吧!

热门免费伪原创文案生成器(文章生成器在线)

神经 *** 伪原创认为那么多人,那么聚精会神,有没有想过伪原创的文章如何实现高效率?


之一,像“爆文标题助手”这样单纯粗暴的名字,内心会涌起不好的感觉。 输入“苹果 *** ”“降价”这两个关键词后,果然诞生了很多极具 *** *** 的标题。


爱发猫AI人工智能“伪原创”,我是人工智能“伪原创”的道具万马奔腾,想了解为我们提供各种文章的咨询AI智能原创文章,可以在百度上搜索搜狗AI, *** 进行搜索。

第二,撰写原创文章时,可以将关键词密度控制在2%到8%之间。

1.这样,搜索引擎就会把它们当成原创文章,很少介绍。 称为营销号的文章生成器,当然不是很有名。 用这个工具生产的文章无论是标题还是内容都不会让你失望。 同样的内容让你改变了什么并表现出来,没有建设 *** 的新内容。


2.首先来到“热点文章”的布局,根据当天的热门话题选择“ *** ”这个话题,点击“智能文章”,一些AI写的文章会自动生成,左右滑动选择最满意的文章进入即可 *** 编辑当我们将文章 *** 到网站上时,网站会自动分析文章内容,将词语替换为同义,将句子结构进行碎片化重构,最后处理成符合语法的“新”文章以降低重复率。

3.伪原创工具使用的文章质量需要验证和慎重,但使用过的人应该知道夜晚还会持续。 现在市面上的一些文章基本上是用AI技术开发的。 你不需要担心文章的质量。 君子求诸人,小人求诸人。 输入文章关键词后,出现的文章总算有点知识科普的意味,只关注前面的“鸡汤”,没有注意后面的“长生不老”。


4.太简单的东西似乎只能用于娱乐,生成的文章不在桌子上。 接下来只能尝试使用更复杂的智能创作工具。 第二个工具是《 *** 不通文章生成器》,同样只是输入标题,产生的文章和前面一个的更大区别在于不仅文章长度大,而且擅长引用经典。 如果你想写普通的原创文章,更好结合具体情况写。 一句话的原始分数只有35%,但修改后原始分数很快就接近70%,“降低重量”并不麻烦。

第三,除了命名,《易撰》还有免费的功能——,主要检查有无违规内容和原创度。

智能ai伪原创工具,比如现在百度上使用的爱猫ai伪原创工具,是AI技术开发的文章。伪原创工具为了更好,要变大变小。 例如,创建原始文章时,可以包含关键字,并在文章中适当 *** 关键字以避免影响用户的阅读。


提纲写作”允许用户创建自己的个人提纲。 “主题”和“关键词”是文章的大致范围,它决定了过程应该从哪些方面为你寻找资料。 下方蓝框内的“提纲”是文章中的小标题,“提纲关键词”是该小标题下的主要内容。

我收集了 12 款自动生成器,效果太逆天

整理 | Jane

出品 | AI科技大本营

此前,CSDN为大家介绍一个火爆文章生成器 *** Bull *** Generator,专以生成各种奇葩、“ *** 不通”的文章,还因此上了微博热搜,只要你在上面写了主题,这个生成器就能给你生成“长篇大论”,能力非凡。

这一工具看似很智能,堪与 GPT 作比,但其实背后的逻辑与算法能力却不在一个层面,仍旧不妨碍大家对这类工具的关注与尝试。目前这个 Github 项目已经获得 10.9k Stars ,简直惊呆。

项目 *** :

https://suulnnka.github.io/Bull *** Generator/index.html

此外,还有网友搜集整合多方信息,又搜集了不少“可实用可玩味”的工具,下面就一起来看看,有没有你钟意的那一个。

特效生成器

1、 *** 加字效果器, 可以在一些场景 *** 上刻 *** 想要的文字

项目 *** :

https://m.photofunia *** /categories/all_effects/snow_writing

一开始被这个效果器吸引是可以做出在雪地里写字的效果,这简直是南方娃的福音啊,而且可以随时浪漫一把。后来研究这个工具,岂止是「雪地」这一个场景,整个网站上支持特殊节日、特殊场景等 21 个类目下 600 多个效果的生成,着实不赖。

不过经过使用体验,发现这个工具还不能支持中文,这么好用的工具,希望作者后续也能考虑设计与支持中文字的效果。

2、在线表情包 *** 器

这两个表情包在线 *** 工具,拥有其中任意一个工具,从此收藏里总是满满的,斗图没怂过。

之一个网站中,已经有很多表情包,在制图里,可以直接在已有的表情上更改文字和字体效果,然后搜图里可以从大量中快速搜索,也有一些大家使用很多的标签分类。

在第二个工具「斗图啦」中,提供了很多类型的模板与素材,可以自己 DIY。

终于知道我以前从别人那偷来的表情包是出自哪了,以后我也是表情包富有者,欧耶。

项目 *** :

https:// *** 52doutu *** / *** ker/2/?order=timedown

http:// *** doutula *** / *** ker

3、诺基亚 *** *** 生成器

这一张图瞬间把我们带回了十几年啊,在这个工具中,大家只需要输入文字,这样的效果图就可以一键自动生成。

项目 *** :

https://zzkia.noddl.me:8020/?from= *** shadiao.app

有了表情包、 *** 文字特效,下面给大家介绍两种特效字体 *** 工具。

4、特殊字体生成器,可以将文字生成其他有趣字体

项目 *** :

https://igfonts.io

内容生成器

5、抽象话生成器,也可以反过来还原抽象话到拼音

现在,表情、字符、特殊符号已经成为日常交流中使用率很高的一种表达形式,它在一定程度上增加了趣味 *** ,但是也会产生沟通交流中的理解偏差,造成不变。

而这个工具的功能就是把输入的文本转换成一些抽象符号,正在研发中的新功能是把一些抽象符号还原成文本,不过此功能目前还存在很多有待改进的地方,比如只能转换由这个 *** 生成的抽象表达,生成的结果也不是文字,而是拼音。同时,在试用过程中还发现了一些分词问题,以后 *** 还可以在 NLP 方面工作多下下功夫,加以改进与优化。

项目 *** :

https://cxh.papapoi *** /?from=groupmessage

6、cp短打生成器

输入你心目中的两个主角,生成器中就会编撰出一段故事,从此又一 *** 文学新写手诞生了,而且是不知疲倦,可以日夜随时在线帮你写文,直到生成你满意的为止。

项目 *** :

https://mxh-mini-apps.github.io/mxh-cp-stories/

7、Bgm自动生成器

这个网站收集了很多自动生成的音乐,神奇的是音乐就好像没有时长控制一般,只要你不暂停,就会一直播放;如果你按了暂停,重新播放的又会跟之前不同,每次都不一样,就好像在某些 *** 情景中,一段无限播放,又带着 *** ,诡异变化意境的 BGM。

项目 *** :

https://generative.fm

有趣应用的工具

8、实用工具,帮你决定“吃什么”

每天最重要和最难的事情是什么?答:今天吃什么?明天吃什么?

解决了这个问题,想必这一天里至少解决了 50% 会引发脑壳疼的事情。想当初为了做出一个抉择,什么猜拳、掷 *** 、抽签各种 *** 都用上。而下面这个网站就非常实用了,尤其是对吃什么这件事有选择困难症的患者来说,就是必备工具。

作者设计了一个随机抽签工具,就像 *** 一样,点击开始与停止,看 *** 为你选了什么午餐(or 晚餐)。菜单栏目前包含两类,一是通过内置输入提供的菜品作为 *** 数据,二是根据「附近美食」作为数据,目前这个功能还在测试中。

下次不知道吃什么,我们就随缘吧。

项目 *** :

http://mofun.c7sky *** /rnd4dinner/

9、爱豆翻牌生成器

是不是微博私信你的“现男友”、“前 *** ”、“男闺蜜”、“大 *** ”从来没收到回复?现在有一个可以“自欺欺人”的工具,让你可以随时翻牌他们,你想撩的他可能都在哦。

起初以为这个工具的配置类似聊天机器人,点进去发现,并没有其他功能,你点进你家爱豆的头像后,进入一个模拟微博私信聊天的界面,多次尝试后发现一些语料模板的组合使用的现象,而且相似度也比较高,如果后续这个 *** 功能做一些智能化的功能设计与实现,想必会吸引更多的粉丝来满足自己的幻想,现在的功能还是略显「沙雕」了。

项目 *** :

http://wb.newbfun *** /fanpai/sixin.html

其他

下面介绍的几个在工具中内置的文字内容,每次刷新可获得新内容的生成器。

10、干了这碗毒鸡汤,现在的苦都不叫苦了

项目 *** :

https:// *** nihaowua *** /home.

html http:// *** nows.fun

11、如何有技术的骂人?

这两个工具分别通过引用 *** 和马丁路德的作品,而且你不会白挨骂,工具会注明引用出处,告诉你被那部著作羞辱了,在线感受一下这波“高级” *** 作吧。

项目 *** :

http:// *** pangloss *** /seidel/Shaker/index.html?//@

http://ergofabulous.org/luther/?

这些工具里有大家曾经使用过的吗?欢迎大家尝试,可以把有趣的作品与我们分享,或者补充你知道的有意思的工具,大家一起 Happy 一下。

抢饭碗?00 后程序员来了!

微软张若非:搜索引擎和广告 *** ,那些你所不知的AI落地技术

舔 *** 记社会语录生成器

舔 *** 记社会语录生成器是一款可以帮助用户快速生成趣味语录的软件。该软件能够生成现在 *** 上更受欢迎的舔狗语录精神小伙社会语录还能够生成毒鸡汤文,感兴趣的朋友不要错过了。

http:// *** downxia *** /down *** /287 *** 1.html

我收集了12款自动生成器,无聊人士自娱自乐专用

来源:授权自AI科技大本营(ID:rgznai100)

本文约2600字,建议阅读9分钟。

OMG!太厉害了!

< 导读 >此前,我们为大家介绍一个火爆文章生成器 *** Bull *** Generator,专以生成各种奇葩、“ *** 不通”的文章,还因此上了微博热搜,只要你在上面写了主题,这个生成器就能给你生成“长篇大论”,能力非凡。

这一工具看似很智能,堪与 GPT 作比,但其实背后的逻辑与算法能力却不在一个层面,仍旧不妨碍大家对这类工具的关注与尝试。目前这个 Github 项目已经获得 10.9k Stars ,简直惊呆。

项目 *** :

https://suulnnka.github.io/Bull *** Generator/index.html

此外,还有网友搜集整合多方信息,又搜集了不少“可实用可玩味”的工具,下面就一起来看看,有没有你钟意的那一个。

一、特效生成器

1. *** 加字效果器
可以在一些场景 *** 上刻 *** 想要的文字。

项目 *** :

https://m.photofunia *** /categories/all_effects/snow_writing

一开始被这个效果器吸引是可以做出在雪地里写字的效果,这简直是南方娃的福音啊,而且可以随时浪漫一把。后来研究这个工具,岂止是“雪地”这一个场景,整个网站上支持特殊节日、特殊场景等 21 个类目下 600 多个效果的生成,着实不赖。

不过经过使用体验,发现这个工具还不能支持中文,这么好用的工具,希望作者后续也能考虑设计与支持中文字的效果。

2. 在线表情包 *** 器

这两个表情包在线 *** 工具,拥有其中任意一个工具,从此收藏里总是满满的,斗图没怂过。

之一个网站中,已经有很多表情包,在制图里,可以直接在已有的表情上更改文字和字体效果,然后搜图里可以从大量中快速搜索,也有一些大家使用很多的标签分类。

在第二个工具“斗图啦”中,提供了很多类型的模板与素材,可以自己 DIY。

终于知道我以前从别人那偷来的表情包是出自哪了,以后我也是表情包富有者,欧耶。

项目 *** :

https:// *** 52doutu *** / *** ker/2/?order=timedown

http:// *** doutula *** / *** ker

3. 诺基亚 *** *** 生成器

这一张图瞬间把我们带回了十几年啊,在这个工具中,大家只需要输入文字,这样的效果图就可以一键自动生成。

项目 *** :

https://zzkia.noddl.me:8020/?from= *** shadiao.app

有了表情包、 *** 文字特效,下面给大家介绍两种特效字体 *** 工具。

4. 特殊字体生成器
可以将文字生成其他有趣字体。

项目 *** :

https://igfonts.io

二、内容生成器
5. 抽象话生成器,也可以反过来还原抽象话到拼音

现在,表情、字符、特殊符号已经成为日常交流中使用率很高的一种表达形式,它在一定程度上增加了趣味 *** ,但是也会产生沟通交流中的理解偏差,造成不便。

而这个工具的功能就是把输入的文本转换成一些抽象符号,正在研发中的新功能是把一些抽象符号还原成文本,不过此功能目前还存在很多有待改进的地方,比如只能转换由这个 *** 生成的抽象表达,生成的结果也不是文字,而是拼音。同时,在试用过程中还发现了一些分词问题,以后 *** 还可以在 NLP 方面工作多下下功夫,加以改进与优化。

项目 *** :

https://cxh.papapoi *** /?from=groupmessage

6. cp短打生成器

输入你心目中的两个主角,生成器中就会编撰出一段故事,从此又一 *** 文学新写手诞生了,而且是不知疲倦,可以日夜随时在线帮你写文,直到生成你满意的为止。

项目 *** :

https://mxh-mini-apps.github.io/mxh-cp-stories/

7. Bgm自动生成器

这个网站收集了很多自动生成的音乐,神奇的是音乐就好像没有时长控制一般,只要你不暂停,就会一直播放;如果你按了暂停,重新播放的又会跟之前不同,每次都不一样,就好像在某些 *** 情景中,一段无限播放,又带着 *** ,诡异变化意境的 BGM。

项目 *** :

https://generative.fm

三、有趣应用的工具

8. 实用工具,帮你决定“吃什么”

每天最重要和最难的事情是什么?答:今天吃什么?明天吃什么?

解决了这个问题,想必这一天里至少解决了 50% 会引发脑壳疼的事情。想当初为了做出一个抉择,什么猜拳、掷 *** 、抽签各种 *** 都用上。而下面这个网站就非常实用了,尤其是对吃什么这件事有选择困难症的患者来说,就是必备工具。

作者设计了一个随机抽签工具,就像 *** 一样,点击开始与停止,看 *** 为你选了什么午餐(or 晚餐)。菜单栏目前包含两类,一是通过内置输入提供的菜品作为 *** 数据,二是根据“附近美食”作为数据,目前这个功能还在测试中。

下次不知道吃什么,我们就随缘吧。

项目 *** :

http://mofun.c7sky *** /rnd4dinner/


9. 爱豆翻牌生成器

是不是微博上私信你的“现男友”、“前 *** ”、“男闺蜜”、“大 *** ”从来没收到回复?现在有一个可以“自欺欺人”的工具,让你可以随时翻牌他们,你想撩的他可能都在哦。

起初以为这个工具的配置类似聊天机器人,点进去发现,并没有其他功能,你点进你家爱豆的头像后,进入一个模拟微博私信聊天的界面,多次尝试后发现一些语料模板的组合使用的现象,而且相似度也比较高,如果后续这个 *** 功能做一些智能化的功能设计与实现,想必会吸引更多的粉丝来满足自己的幻想,现在的功能还是略显“沙雕”了。

项目 *** :

http://wb.newbfun *** /fanpai/sixin.html

四、其他

下面介绍的几个在工具中内置的文字内容,每次刷新可获得新内容的生成器

10. 干了这碗毒鸡汤,现在的苦都不叫苦了

项目 *** :

https:// *** nihaowua *** /home.

html http:// *** nows.fun

11. 如何有技术的骂人?

这两个工具分别通过引用 *** 和马丁路德的作品,而且你不会白挨骂,工具会注明引用出处,告诉你被那部著作羞辱了,在线感受一下这波“高级” *** 作吧。

项目 *** :

http:// *** pangloss *** /seidel/Shaker/index.html?//@

http://ergofabulous.org/luther/?

这些工具里有大家曾经使用过的吗?欢迎大家尝试,可以把有趣的作品与我们分享,或者补充你知道的有意思的工具,大家一起 Happy 一下。

编辑:黄继彦

校对:林亦霖

— 完 —

关注清华-青岛数据科学研究院官方微信公众平台“THU数据派”及姊妹号“数据派THU”获取更多讲座福利及优质内容。

内部分享实录:32000 字畅聊互联网流量的一切概念,都说了啥?

编辑导读:互联网流量,是很多企业趋之若鹜的对象。从免费流量到付费流量,从公域流量到私域流量,随着互联网的发展,流量的概念也随之改变。本文作者围绕互联网流量分享了自己的一点看法,希望对你有帮助。

这是一篇现场实录,主要分享互联网流量相关的概念以及付费流量与免费流量的玩法,口述内容冗长请见谅。

今天给大家分享一下付费流量与免费流量,主要是整体讲一 *** 量本身是个什么东西,通过这一次分享让大家对流量有个整体的,比较全面的把握。

首先,大家觉得什么是流量?有人回答一下。对,移动上网流量,水流气流,那个也是流量。

一、什么是流量

1.1 流量的定义

我们先看流量的定义,刚才说的水流气流,如果在物理里边就单位时间流过的体积或者质量,这些都叫流量。还有上网流量也是,上网流量就是单位时间流过的比特,它其实就是特定的时间,特定的人/事或者行为,或者是你要衡量的某个变量。

往玄一点说就是一种时空关系,其实我们关注的流量是网上的流量,它背后都是人,网上的流量背后都是由人来触发的。所以我们要关注流量,就要关注这几个 问题。首先访问流量的主体是谁?然后它有什么特征?他们的需求是什么?他们的访问时间在什么时候?访问的访问频率,访问时长,在哪里访问的?什么样的环境,然后他们是通过什么设备,怎么访问的,线上还是线下?然后他们是怎么被吸引的,如何接触到他们信息如何曝光的?

所以,要理解流量。首先要理解人,流量本身就是人与人的连接,它是一个关系链的产物。那人 *** 基本上是永远不变的,有些变化,但不多。所以说,洞察人 *** 才是营销的核心,这个就是基本的定义部分。

1.2 流量的分类

那么流量怎么分类呢?其实有很多概念,互联网对不起的概念,这些概念大家也不用太去纠结细节,它都能从某一个方面反映流量的一些特质。

比如说如果按入口区分,那有线上流量线 *** 量,还有社群的入口,内容平台的入口,如果是线上流量,刚才说的通信互联网产品这个都是有流量,我们主要关注大家都听过的 PV/UV 还有最近的张小龙提的 VV,这些用户行为数据。通过各类的统计平台统计。还有我们做的埋点,这些东西,线 *** 量就是酒店商超 KTV 这些,你们平时逛街满大街晃悠的时候,都是流量。这个时候店面就会关注一些日均的 *** 量、到访量等。

怎么统计的?

比如说,如果你想开个店,一般的做法就是先蹲在商圈某个店铺的门口,或者是找一个椅子坐在那儿,拿个小本本在那记,看这个铺一天到底能来多少人,有多少人是拿着东西走的。

这个就是线下统计。现在也有一些智能 *** 头的识别,能数人头数,但人群标签是没有的,除非再加上人脸识别还有一些大数据才能知道这些人到底是什么,不然就只是数人头数。具体这些人是做什么的也不知道。

如果按成本区分,就是今天要展开讲的,付费流量和免费流量。付费流量,就是花钱的流量。主要就是关关注 ROI 的部分,到底你的投入产出比是怎么样的?怎么样把这个钱花得更好?精准引流主要在做这方面的事,就是研究怎么样去更好的花钱,不是缺钱,就是钱怎么花更值得。

第二个就是免费流量,我们关注就是怎么样能获得更多的免费流量,还有免费流量是不是真的免费?它有很多潜在的成本,还有一些其他的比如说按相关 *** 区分,就是精准流量和泛流量。如果我们不知道是什么,满大街逛的这些车来车往这些都可以算是泛流量,你也不能从上面赚到钱。

精准流量就是你明确的知道这些人是什么人,你能在他上面找到商机能去变现的这些我们叫做精准流量。还有按主动被动,有主动的流量和被动流量,就像赚钱一样,有主动收入和被动收入,主动流量就是你要主动去想办法去获取的被总流量。你在这什么也不做,他也会来的。

按影响范围,有公域流量和私域流量的区分,也是这几年比较火的。然后还有一个叫商域流量,其实就是在公域流量里边的付费的部分。这里跟付费流量其实是有点重合的。最近比较火的就是私域流量后面也会讲一讲,按平台派别分,百度系、阿里系、 *** 系、头条系这些概念就不说了。

二、通过广告投放获得的付费流量

2.1 传统媒体

首先,付费流量中的传统媒体大家都知道,一些媒体广告,还有像美的,年年都在做的「美的集团向全国人向全球华人拜年」。这个是每年都在做的媒体广告这种。你的受众是多少人,或者是有什么效果,你是不知道的。而且是这种效果一年比一年差。因为以前的媒体相对比较单一,大家基本都会看电视。

现在有很多像 B 站春晚,像天猫春晚之类的,还有很多 *** 春晚。真正看央视春晚的人就会少很多。还有户外广告,大家在街上或者是任何线下场所看到的各种广告都算。还有报纸 *** 。刷墙最近又火了起来,渠道下沉嘛,就是在各种村里县里去刷墙,跟每家去给一点钱,就可以把他的墙刷一下,他可能还觉得刷完了更好看一点。本来是一个破得不要不要的墙。

线下活动的运营推广,以前经常有这种线下敲锣打鼓的,然后扭秧歌或者找一些歌舞队,找一些小的乐队来搞活动,这种都是吸引流量的一些手段。

它的特点就是主要侧重在品牌曝光,就是你如果非常有钱,你的品牌非常有钱,你就去做品牌,你不在乎到底能有多大效果,只要品牌得到曝光就可以。

它不精准不可追溯,效果也不可查,除非是那种像线下活动的时候,现场卖货。现场卖多少,那一天或者是多少个城市同时举办这种活动,一天能卖多少,这个是有数的。但具体什么人买了这些,之前都是不可知的。

2.2 互联网广告 & 精准引流

互联网广告。首先就是搜索竞价,所有的搜索引擎都有这种服务,就是竞价排名,但是表现形式可能不一样。比如说,百度就是百度营销里可以进行这种竞价的排名,针对某一个关键词花钱买,花钱买完以后,在某个人搜索这种关键词的时候,它可能是全匹配,可能是半匹配的。这时候就会按照你的出价顺序,展示你的排名。比如说你出了 10 块,有人出了 20,那可能他就在你的前面。这个展示是要收钱的,如果有人点了,比如说关键词有两块钱,你展示了以后又被人点了一次,你就要付两块钱给百度。

搜索引擎的营销 SEM 和 ASO 后面也会再讲。Google 就是 AdWords。品牌专区,比如百度品牌专区,我们之前的商城都是有买的。这个是很贵的,可能一年几百万起这样。你在搜索跟这个品牌相关的关键词的时候,会有大概 1/3 屏幕来展示这个品牌的形象,还有一些快捷入口。 *** 直通车,就是 *** 站内的类似的平台。可以有首页的入口,还有一些各个频道页活动页的入口。

内容植入,比如说大家看电视剧有很多广告,有的时候植入得很生硬。比如说经常能见到一个 999 那个 *** 匣子,谁家都有。 *** 贴片广告大家都看了很多了,尤其是免费的时候,你前面就要过一个 30 秒,甚至有的七八十秒。还有更恶心的 「VIP 推荐」,你明明是买的是 VIP,然后给你一个 VIP 推荐剧集,或者 VIP 推荐综艺,其实都是广告。

下一个就是信息流广告。信息流广告有几个比较大的平台,比如头条有一个叫巨量引擎,还有一个叫穿山甲的平台。 *** 就是广点通,百度有一个叫百青藤,还有抖音的 dou+。这些都是在它的信息流中植入广告,你可能刷着刷着,忽然就出来一个广告,然后可能很小的字告诉你这个是广告。你看头条文章也是,往好了说是一种沉浸式的体验,就是让你看不出来是广告,他的样子长得跟普通的文章和信息是一样的。但在左下角有一个很小的字告诉你这个是广告,因为这是广告法规定的,必须这样写。

这个就是沉浸式的看广告。

平台广告历史比较悠久了,比如说一些垂直站点的广告,猫猫狗狗宠物这些,你就可以直接去卖 *** 。然后门户网站广告,像之前的搜狐、新浪、网易这些,你都是比如说卖一个 banner 位,每天多少钱,一个月多少钱。

短 *** 平台就不说了,游戏广告游戏里面植入的也很多,大家做小游戏、做小程序里面都看到了开屏广告,还有一些带激励的广告。小程序买量,在前几年小程序比较火的时候,有很多这种买量互相互相买,比如说我买你一个小程序的跳转入口这样。

软文广告和种草网站,典型 *** 就是小红书和什么值得买这种。社交渠道,有 KOL/KOC 的推荐,微商,这些都是社交渠道的。社群营销也有很多,还有裂变 *** 营销,朋友圈的营销。

流量互换,属于 B to B 的渠道了。像友情链接这些都是很早的,很原始的,它以前交换一个链接,大家感觉流量差不多就交换一下。现在其实是可以 *** 的。你可以把链接单独加个参数,你能知道你交换这个链接能给你带来多少流量,他都是什么人,你在百度统计里边去看一下来源就可以了。

公众号互推这个也算一种,几个差不多差不多量级的公众号互相推,大家也经常看到公众号里边时长出现推荐一些「不得不关注」的,或者是什么「优秀的人都关注的」。品牌联合就是两个品牌在一起搞活动或者搞一个什么事情。品牌跨界其实就是两个不同行业的或者是跨度比较大的,合在一起搞事情。

邮件营销现在在国内用的比较少,但国外还是很流行的,因为外国人有看邮箱看邮件的习惯。这种习惯比国人好。其实邮件营销还是很有效的。有很多小的商业刚刚起步的时候,就靠一个基本的邮件列表,维护那么一两千人或者是几百人,就能把业务跑起来了,所以也是值得重视的。

其他还有一些咸鱼转这些其实都可以打广告,还有很多专门做咸鱼引流的,怎么把咸鱼的用户引到我的商城来,或者是如何在咸鱼上面成交,咸鱼上面真正 *** 闲置东西的人已经越来越少了,很多都是专门去做的,找个货源以后立马拿到咸鱼去卖。

下一个就是问答平台,这些知乎什么、 58同城信息平台之类。早期有一些免费发信息的,很多人在里面 *** 发,比如说我有一个什么网站,或者是我有什么生意,比如说收废品,我就去个信息平台发,留 *** 号。还有社区论坛,百度知道贴吧这些东西,在这个里边还有一个生意,就是流量中介。流量本身也是可以作为商品存在的,只要是从源头到你的终端用户中间是有差价,这个生意就可以做。

比如说你在一些大平台你可以你可以采购比较便宜的流量,但是终端用户不一定能直接买。首先是可能有门槛,比如说他一定要达到多少钱,比如说一定要一个月100 万我才能卖给你,就可以做分发。还有一种可能是你的终端用户根本不知道有这个渠道,你可以去做发现商机和教育的事情。

这个行业也是有很多中间商存在的。比如说你去头条去投放,很多时候中间是要隔着 *** 商的,他们都是通过地区 *** 商,或者是某个架构上面分层的 *** 商来对接的。很少会直接去跟平台去对接,平台自己也没有办法去维护这么多的人力,他也没有精力。像微信的认证都是 *** 商来做的,300 块钱一次。

总结一下,互联网广告的特点就是精准引流,效果可追溯,数据驱动。有一本书叫《增长 *** 》,主要就是讲靠数据驱动来获得增长,然后持续优化。

这里边还有一个问题就是流量欺诈,是这个行业历史非常悠久的问题。早期这种是非常明显的在广告行业。基本上很大的流量都是假的。比如说,做技术的可能知道,你在页面上如果 PV 不做去重的话,那刷一次就是个 PV 这种哪怕我用人来点都也可以。

再往前追溯,比如说到 2003 到 2005 年,那段时间有很多广告联盟,国外的也很多。还有一些 *** 点广告的。 *** 点广告做的是什么事?你打开一个页面上满屏都是广告,你就一个一个点,点开以后放在那也不用看,过一会等它播放完了你关掉就可以了。

这种是层层分佣下来的,中间可能有 10 层或者是几十层上百层都有可能。一层一层往下转发,到最后可能一个人点个广告几分钱,都有人做。只要是有利可图就有人做。然后还可以用机器来点。早期的广告行业数据基本上都是这样来的。现在技术越来越发达,我们也会做很多去重,或者是羊毛的识别,就能识别出一部分,但多少还是会存在的。

*** 难度是有一定层级的,比如刚才说的展现量点击量这些都很好 *** ,然后你要说留咨量,可能就难一点。你起码要留一个差不多的 *** 号,哪怕是打不通,造个 *** 号也可以,还要造一些看起来像是真实的数据。潜在的客户量,订单量,这种就更难了。下单量是可以造,但是到了成交基本上已经不是造的问题,钱都给我了,你愿意怎么造怎么造,反正我收到钱就可以了。

还有很多刚才提到的可能有机器刷量和一些僵 *** 僵 *** 号。 *** ,不知道大家听没听说过?很多大批量的 *** 卡放在一起,这样的设备可以把一批 *** 号集中在一起,然后对外使用者像用真实的 *** 一样,去发 *** 收 *** 。甚至有的可以接 *** , *** *** 平台,可以直接通过 API 的方式接入,每次随机给我一个号,然后我去某个平台自动注册,注册完之后这个号再通过接口把验证码返回给我,我就可以注册成功了。

至于这个号后面会做什么我完全不管。临时的活动,我就通过这种平台去搞一下,搞个用户,然后搞积分,如果是积分可以转移那就更好了,如果不能转移那就积分攒到数量立马兑换掉,兑换券也可以或者买东西也可以。这个薅羊毛的基本 *** 作。

2.3 事件营销

最后一个就是事件营销,这个就不细讲了,这个话题比较大,像之前的「逃离北上广」这句话主要是新世相搞起来的,也是获得了很多关注。支付宝锦鲤,这个也是,其实他花不了多少钱,找各个商家过来提供一堆券,然后全国这样玩一圈,获得很大的曝光量,最后也没有多少成本,这就是事件营销。

这里可以多说一句,事件营销有好有坏,还有跟风追热点,也是事件营销的一部分,如果你贴得好的话,可能就会有比较好的效果。但如果贴不好,可能对品牌是一种损伤,甚至有可能有公关危机。

三、通过内容获取的免费流量

为什么叫通过内容获取?这里的内容是广义的,我们很多东西都可以叫内容,你能看到听到能感受到的都叫内容。内容的形式主要有这些,一个是文字的,大家看的公众号文章这些东西,然后 *** 、音频、 *** ,比如罗振宇的 60 秒音频,还有各种音频课程,这些都是内容。 *** ,可能简单的分就是短 *** 、长 *** 。短 *** 里边还有一个单独 vlog,为什么单独拎出来?它跟一般短 *** 还不太一样,比如说你看抖音快手,一般的短 *** 要尽快抓住你的眼球,可能在前 3 秒或者是前 15 秒,如果不能抓住你的兴趣,基本上就刷过去了。而 vlog 更倾向于个人生活的记录,它不需要去卡点,也不需要激动人心,就是你的生活状态,更有烟火气一点。

长 *** 可能是接下来一两年内比较火的,我们以前看的 *** 都可以叫做长 *** ,但是短 *** 搞了这么久,现在又回归了。

*** 号里面就可以看到,有过几次改版,最开始是不支持长 *** ,只有一分钟。后来是支持长 *** ,要点一下,现在已经可以做到很自然地去切换到长 *** 播放。下一个就是直播,也火了好几年了,直播从技术上讲,它确实是 *** 流,但实际上它跟 *** 不太一样,因为它侧重在互动这部分。你看普通 *** 的时候,除了弹幕,基本上是没有什么互动的。

下一个是消费场景。为什么说这个也是内容,举星巴克的例子,星巴克有两本书,一个是《一切与咖啡无关》,一个是《将心注入》。主要是讲星巴克第三空间这个概念,它营造的是除了工作和生活,除了日常的工作和家庭之外的第三空间。让你在这个空间就有一种放松的感觉,暂时逃离的感觉,就跟中年人回家之前在车里待一会,不上楼是一个样子。还有他在服务中有很多细节会给你体现这种 *** 和优越感。虽然说本身看上去也没有什么,就 30 多块钱一杯,但它是会通过很多服务的细节让你有这种感觉,而且确实有很多人去了以后会有优越感。

所以说,消费的内容应该是用户得到的综合价值,付出的可能就是他的付出的综合成本。

比如说售后维修这种,可能维修本身并不贵,100 块钱 80 块钱这样,但你要去维修的时候,你要抢号,你要排队,然后你来回交通时间成本,这些其实都是你作为用户要付出的成本。这个时候就不能考虑你这个东西本身要多少钱。如果想把你的服务做得更好,要考虑用户在这个消费场景中到底付出了什么。也可能是面子,可能他用这个东西或者服务会觉得丢人,这个也是他付出的成本,那最明显的就是时间成本了。

内容来源,我们知道内容可以带来流量,怎么去解决内容来源的问题呢?首先我们最常见的也是最烂大街的就是文字内容和 *** 内容,在网上可能 90% 多都是这种文字和 *** 的内容,有很多是垃圾内容,比如说你想去建一个网站来堆砌这种内容,来获得一些流量。那内容到底哪里来呢?

大概就会从下面这些部分,首先是素材,素材网上有很多公开的素材素材库,比如说一些作文网站,它就会有很多文字内容,作文、诗词、 *** 、小说这些都是文字内容。然后比如说 300 字作文,可能我们正常的一篇 SEO 文章 300 字左右就够了。你把一篇作文改一改,也能作为你的内容。诗词也是,诗词混一混翻译一下,也能作为内容。

还有就是品牌故事,很多品牌有自己的品牌故事。可能是你把几篇故事拼一拼,合成你自己的故事,或者是你写你自己的品牌故事,一定会有很多故事。如果真正是一个从零做起的创业公司,哪怕只有一两年的时间,在你整个过程中也有很多故事可以讲,很多时候做品牌其实就是讲故事。比如说美的有 50 多年的故事可以讲,前面是怎么创业的,中间经历了什么困难,是怎么度过的,然后有哪些变革,都可以在讲故事。还有品牌的产品库知识库,你看有些品牌它会有自己的产品库或者知识库,还有服务支持,这里面都会有大量的内容存在,都是可以利用的素材。

其实就是,任何的文字内容都可以作为素材,就是怎么获得的问题。做新媒体的有很多新媒体,新媒体的工具,大家可能也见过一些新媒体工具里边也会想办法去帮大家解决这种内容的问题,它会提供一些素材库,这些素材库其实也都是网上爬来,或者搜集来的。还有平时的积累,大家平时用印象笔记、微信收藏也会收藏文章。如果你想发展写作的部分,重点就是平时积累,你觉得好的句子,好的段落都可以积累下来,不定哪天就能用上。也可能是在述职汇报就用上了一句名人名言,或者是你的 PPT 上面用到一些比较好听的句子。纸质素材库,一些书籍,纸质作品,这个只是素材库,怎么用呢?现在有很多工具,比如 OCR 识别这些,手抄就不说了。

朗读识别,为什么单独列在这,有的东西你没有 OCR 识别或者 OCR 不好识别,你可以把它念出来,比如说用微信的语音识别,念出来以后,他就能把你识别成文字,像 iOS 的也有这些朗读者,其实都可以识别。还有讯飞,专门做这个,硬件设备和 APP 都有。这个时候就可以很方便的把这些纸质内容转成文本,扫描识别也是,印象笔记这些都可以直接识别。

音 *** 识别也是。你如果你本身有一些音频、 *** 的积累,你可以把它转成文本,这些都是有 *** 的工具和 API 可以实现的。

*** 的素材库就不说了,本质上还是搬运,只要不是自己拍,都是搬别人的。但文字不一样,因为每一个字都没有版权,就看怎么组合。但是 *** ,别人拍的就是别人拍的。

第二个,单独针对文字部分,首先是人工写作这几个概念,PGC / UGC / OGC / PUGC,大家回去自己查,对这些都是内容生产的方式。

首先,你如果做一个内容平台,比如说我要做一个跟头条差不多的,做一个头条新闻,你就要解决这个问题。你要想你的内容到底从哪里来?肯定不能开始就爬了,虽然也有很多平台开始就是爬,到处爬。如果靠人工写作的话,到底是由专家来生产,还是由普通用户来生产,还是你的组织生产,还是你的专业用户生产,要事先想好,不然的话后面是没有办法推进的。

还有个工种叫人工 *** ,大家搜一下会有这种人工 *** 平台,大概一篇三五百字的就是 50 块钱这样子。这些人工 *** 它的用处在哪?就是那种 SEO 文章,靠爬虫或者是靠机器去拼凑的时候,质量非常差。

人工 *** 的作用就是帮你拼一篇,看起来还质量比较高的,或者是基本上看得过去,是说人话的文章。然后就是 *** *** ,投稿之类。 *** *** 单独也列了一下,比如找大 *** *** 。投稿也算,跟 *** 差不多。你找些人写一些文章,然后你来看,觉得合适就给点钱。这种的特点就是成本比较低,质量也不一定会很差。

像「十点读书」这种号全都是投稿,在投稿的基础上,他可以慢慢去找一些专家,再来培育一些写得比较好的,然后再扶持他们做自己的 IP,再去帮助他们出书之类,这样的话整个生态就玩起来了。还有就是自己写,不说了。

下一个就是洗稿和伪原创,刚才前面说那些素材库的拼接,这些其实都是有洗稿的嫌疑。这些事情其实我们在中学就开始做了,中学你们有没有买过那种作文素材库?作文素材库里面其实都是别人写过的,你可能为了应付 *** ,你要背几段下来,比如说写人物的背一段,写风景的背一段对吧?这个其实都是洗稿。

手动洗稿,就是把一些公开的文章,公众号, *** 这些你都可以拿来洗,看洗到什么程度,你也可以把它洗得面目全非,它就是你的文章了。比如大家作 *** ,做 *** 怎么做的?你一定是去知网这些搞个几十篇 *** 回来,然后前面摘要或者是行业现状基本上都是抄的,改一改只要识别不出来就可以了。后面可能自己写的部分占10%~20%,可能还是师兄做的。

然后刚才提过的新媒体工具辅助写作,会帮助你做智能段落的拼接,还有 *** 素材。智能伪原创工具,它是通过自然语言处理的算法,把这个话拼得更自然一点。现在做得比较好的,会从网上找内容,先用关键词搜索相关的文章,然后自动抓一些段落出来。再自动洗一遍,然后你再来看再来整理。现在这种工具也很多,对应的就有「原创度检测」,其实也是洗稿用的。普通人如果自己写的,没有必要去做原创度检测,这跟 *** 查重差不多, *** 查重是跟别的 *** 去对比。原创度检测是跟网上已有的,被搜索引擎收录的文章去对比。它会告诉你这一段的这一词或者这一段的几个字,重合的概率是多少?如果都标红了,就要把它改一改,加个什么的地得之类的,可能就好一点。但是现在都是自然语言处理算法的。这种简单的加小词作用不太大。

AI 写作,有文章生成器。你可以把它理解为一个专家库,里边有大量的素材,然后根据你的关键字和线索随便拼凑一下。

还有个叫 *** 不通文章生成器,这个就是找了各种经典著作,什么名著、哲学、天文地理著作全都有,不管你输入什么都随便给你一段,跟输入的内容一点关系都没有。

然后最后还有一个机器生成,机器生成首先就是爬虫,既然是机器,素材肯定不能自己去录入了,一定是爬虫实现。比如浏览器爬虫,服务端的爬虫。各有各的特点。浏览器爬虫用起来比较方便,什么页面都能爬,而且它不存在这些登录态的问题,因为你在页面上已经登录了,就相当于一个自动化 *** 作。

服务端爬虫就要自己写了,也有些开源的工具。还有就是采集工具,如果大家玩过的 WordPress 里面就会有很多采集的 *** 件,像火车头这种。你设定一些规则,它就去全网爬,爬完了以后自动为你发布一篇文章,这个网站就出来了,垃圾站都是这么来的。

还有各种其他的 CMS *** 都有这种 *** 件。还有智能软文 *** ,就是在刚才这种 *** 件基础上,把东西爬回来以后,再去混入你需要的关键字。比如说电饭煲,然后爬虫爬了一堆跟家电相关的,比如红烧排骨怎么做,盐焗鸡怎么做之类,再把「美的电饭煲」混在内容里面。这些基本上就是爬虫再加伪原创功能,相当于把前面的几个功能结合在一起了。

还有爬虫可以加 OCR,你爬过来的 *** ,再用 OCR 识别。比如 *** 什么这些都是 OCR 的识别。智能写作,跟刚才的还不太一样,智能写作它是另一个概念。现在大家如果买股票基金,你看那些新闻报价,基金股票那些报价,全是自动生成的。它有一个固定的模板,然后固定模板上面会有很多可替换的变量,你比如说今天明天然后涨了跌了,然后建议是买还是建议是卖等等。

这些都是可替换的变量,它在抓到你今天的股票数据之后,再根据这些变量生成一篇文章。文章大同小异,也可以做得差异很大,你可以把每一个字都做成变量,随机生成以后,可能每个段落每个字都不一样。那就是两篇看起来完全不一样的文章,还可以有 if – else 的条件。

If,出这段,else,出那段,这种是智能写作,它可以自定义模板和数据源,常用的就是赛事、天气、股票这些东西,因为这些本身输出的文章是结构化的。哪个队,得多少分,哪个股票怎么样,再混一些新闻和热点信息之类。

也可以通过这种思路来生成你的文章,你做一个非常强大的,非常智能的模板,然后每天就是随机生成,随机一个月都不会重复。随机一个月就一个月的文章都不重样了,其中再混入你需要的关键字,如果被搜索引擎抓取到的话,并且没有识别出来你这个是机器写作的,可能就能很快的提升网站的流量。

智能文章摘要这个也是 NLP 的,百度 *** 都有这种接口,你随便拿一篇文章过来可以给你自动生成摘要。比如说你写的 *** ,可以自动生成一个中文摘要,再加一个百度翻译,自动翻译成英文摘要,基本上 *** 的摘要部分就有了。

双向翻译伪原创之前也玩过,因为翻译这个事,不管是机器翻译还是人翻译,都不可能很准,从中文翻译成英文,就会有一些失真变化。再从英文翻译回中文,这篇文章就变样了。几次双向翻译,再人工过一遍,就是另外一篇文章。这也是一个路子。

还有 *** 语音的识别, *** 语音识别刚才提过了,这里还可以再说一下。刚才是说,你如果已经有了语音识别语音和 *** 的素材,如果没有,比如我现在想想搞点心灵鸡汤,怎么搞?你关注一堆抖音的心灵鸡汤号,然后拿一个智能录音笔放在边上,他这边放一遍,你这边出来一段文字,你再改一改,素材就有了。或者你把几个人的综合一下,素材就来了。是不是思路又拓宽了许多?

下面是 *** 了。 *** 有很多,网上有很多无版权的 *** 。之前大家认为网上 *** 都是没有版权的,现在版权意识越来越好了,所以才会出现真正的无版权 *** 网站。这些无版权 *** 网站是大家自己拍摄的贡献的,然后一般是 CC0 协议,你可以随便用,这种国外的网站比较多,国内的一般没有人愿意搞。

第二个就是 *** 搜索,百度 Google 这些都可以,这个时候要注意版权,现在百度的版权意识也提升了,会有很多打了版权标的,你搜出 *** 下面会写这个是有版权的。还有就是拍照,随便拍。还有刚才说的 *** ,单独截取某一帧,这些都是 *** 素材,不过这个也是有版权的。

自动化生成这也是个路子。大家有的时候会看一些传播比较火的动图,可能是用 echarts 的这些软件去生成,我拿了一堆数据,拿一些比如说 10 年股票走势,10 年比特币 *** 走势,这些可以做一个动画 *** 出来,都是自动生成的内容。爬虫再加报表的库来自动生成。

下面就是音 *** ,这是人工拍摄的,没什么好说的,就是拍这里边拍摄的时候也不是瞎拍,即使你不是专业的,也有网站会提供脚本库,比如说抖查查,这上面就有专门的拍摄脚本库。你其实什么都不需要知道,你去照着他的脚本拍就行了。

比如说需要几个人,需要一个 *** ,需要一个大爷,需要一条狗,然后你就准备。你把这些找到,然后在什么样的场景,可能是大街上或者是小区里,谁在哪里,什么机位,该说什么词,这些都是有公共的素材库的。也可以临场发挥一下,比如说大爷突然想到更好的台词,狗突然乱叫几下啥的,这些都是可以临场发挥的。

还有,模仿现有 *** 这些在抖音快手也是非常火爆,而且,怎么说呢,是非常有可行 *** 的。对尤其是抖音,尤其头条系的,为什么?因为头条系他那个算法是按照你单条的质量,它不在乎你有多少粉。你有 100万粉丝,之一条上千万的播放,到下一条就完全没有人看也是有可能的。所以这个时候,模仿 *** 才这么火,你一个大 V 100 万的粉丝,拍了一个 *** ,看起来很不错,但是由于种种原因,可能分配的池子或者怎么样,一些随机算法的原因,没有火起来。但是被你看到了,你觉得这个创意非常不错,自己再拍一个一模一样的,但是由于一些原因,你这个可能就火了,对。

所以说这种模仿怎么说呢,只要你不觉得这个事情有问题,就没关系。还有就是虚拟形象的软件,不知道大家看不看 *** 号,或者有没有看到一些,有的人在那说也是他在动,但他的脸被换掉了。这些虚拟形象现在的技术已经很成熟了,可以完全动态识别的脸,甚至换脸都可以。比如川普换脸这种都可以,但需要生成的时间比较长了。但是你说贴个 *** 形象,贴片的这种这个已经很成熟了,有很多应用可以做到,苹果内置的就可以。

你就对着 *** 头去说话做表情,然后你把这段 *** 录屏录下来以后,就可以做素材了。比如你想开个 *** 号,想讲一个什么东西,但是你又不想露脸,你就可以拿苹果的「拟我」表情功能,你就对他一直讲。然后最后再 P 个什么背景或者把文字 P 上去,这个课程就有了。

字幕这些也都是,刚才说的语音识别已经都集成到各种 APP 里面了,可以自动识别添加字幕。还有人工搬运其他平台的 *** ,这个也是好多年了,尤其是从油管往回搬的,国内的很多很火的 *** 都是油管搬回来的。

对,搬哪都有,搬到 B 站,搬到快手搬到抖音的全都有,反正就是搬。这里也可以提一下,搬运这个思维其实在哪里都可以用。有句话说,任何在一个平台火的内容,都可以在另外一个平台再做一遍。你在油管火的,可以在其他平台再搞一遍。在快手火的在 B 站可以搞一遍,B 站火的也可以再拿到抖音、 *** 号去搞一遍。

当然各个平台它的调 *** 是不一样的,你要看一下你的内容到底适不适合这个平台的调 *** ,也可能不适合,不适合的拿过来可能就没有用。比如头条系可能就更倾向于新闻和热点之类的,心灵鸡汤你放到头条新闻里边可能就没有用。再比如说一些饮食或者是 *** 倾向的这种,可能在快手就比较火。放到 *** 号就不一定有用。这些是搬运思想。

扯远一点,像比特币当时也是有很多搬运的,比特币的 *** 是怎么来的?它其实有很多交易市场,你是看交易市场 *** 。但是不同的交易市场之间是会有差价的,早期的时候,在各个市场之间搬运也能获利。股票也是,股票你的高频交易在人的手没那么快的时候,通过电脑去查到你买和卖之间微小的利益差,然后快速的去 *** 作,那就能赚到中间微小的利差。

这里说下扮搬运的版权风险。搬运一定是侵权的,是游走在法律边缘,就是盗版。就看告不告,一告一个准。注明出处也不行。首先大家是做软件的,一定要熟悉这几个版权协议,比如说 CC0 ,基本上可以随便用,但是也是有版权的,不是没有版权,只是我授权你可以随便用。还有 MIT, Apache 之类。大家要知道,一切的创作作品都是有版权的,尤其是软件,还有 *** 、文章这些都是知识产权,都是 IP。

为什么现在 IP 这个概念这么重要,就是知识产权很值钱,既然值钱,一定要拼死保护。 *** 也是,别人拍了一个非常好的课程或者 *** ,被你搬走了,并且完全看不出来是他拍的。对别人的利益是有损失的。本来他想借这个好的内容去传播,去建立影响力,建立品牌,但是被你拿过去,你可能把自己的品牌贴上去,你获利了。

这个地方有什么好的办法吗?首先,这个内容本身就是你品牌的东西你就不怕,比如说我在讲美的电饭煲,你随便盗版,你盗了我也不会告你的。或者是我自己就真人出镜,你总不能把我的脸换掉吧,其实理论上也是可以的,但成本会很高。

这个问题无论从渠道上还是法律上都是拦不住的,技术上也拦不住。你唯一能做的就是,让他的盗版成本变高,像搬 *** 去水印这种成本就很低。你看 *** 号上面很多都是什么名人演讲这些,就是直接搬运油管,去水印。就算保留水印,也是侵犯版权的。什么 Ins 精选这种,也是搬别人的,尤其是搬个人的,都是侵权。首先大家一定要清楚这个概念,这些就是盗版,就是侵权。但总有擦边球,总有一个模糊的边界,然后大部分时候人家没有时间告你。没有作者授权就是侵权。

如果是把某一个平台的比较好的东西,你本来想随便搬一下,但它突然火了,真正影响到平台利益了,那是有可能有法律风险的。大家自己产生的内容也是一样,你用的软件,大家可能用盗版都比较习惯了。但假设你自己写一个作品,自己写一个软件,放到应用市场上去卖,但是第二天你就发现有个人发了盗版,你来不来气?最可怕的是,人家还做了微创新!

在 App Store 里面经常会出现有很多同质的 App,小程序更是,刚发出去以后很快就会有类似的小程序出现,因为小程序可以直接扒源码。比如「 *** 助手」这种出来以后,然后扒源码稍微改一改,甚至有人改都不改,直接塞两个广告就再发布一遍,这都可以。所以微信才要求必须有软著嘛。你发的小游戏必须要有软件著作权证书,即使你是扒的,你能搞到证书也可以,你可以先申请软著。

这个又扯远一点了,所谓的版权,其实是一个法律意义上的版权。你说你写的?不行!你要专利证书,你要有你的著作权证书,要有你的商标品牌,这个才算你真正有版权。所以才会有抢注出现,大家应该听过商标抢注。专利抢注也是有的,因为专利它的生效范围是在是在国家范围内生效生效的。比如说你发现美国人发明了一个新专利,你觉得这个比较好,但是国内没有,你立马把它原样搬过来,在国内申请一个专利。如果先批了,你可能这个专利在国内就算你的,这是有漏洞的。

所以如果觉得这个东西是有商业价值的,都会在各个国家去注册专利,除非这个国家的专利根本没有什么价值。所有涉及版权地方,都会涉及到这种抢注抢版权的事情。

机器生成图文转 *** 接口,这个不知道大家见没见过,也是一个比较新的。比如说我有一篇文章,然后有一些 *** 素材,我可以通过 *** 转 *** 接口,让它快速的生成一个 *** ,这有什么用呢?其实是针对不同的平台,比如我写了一篇很好的文章,但是我又没有拍 *** 的能力,就可以用这个接口去把它转成一个 *** 放到 B 站放到抖音上面去玩一下。还可以放到 *** 号,然后再把它引流回到这篇文章。图文转 *** 接口都是可以通过 API 来实现的,而且前面讲的这些都可以组合,比如说你可以爬虫爬到以后, OCR 识别,然后就变成你自己的文字了。再利用无版权 *** 的 API 去自动抓一些 *** 回来,再用图文转 *** 接口自动生成一个 *** ,全程都没有人工参与,就有了 *** 内容。

最后一个,创造消费场景,就不展开了。我也不专业,而且有很多细节可以讲。

下一个就是内容生产的边际成本,本身这个内容行业是有一个相互制约的关系的。首先比如说是你自己来写,你又想写的质量很高,又想日更,每天都能发,又想一直坚持,其实很难的。因为人的精力有限。放到公司或者是组织也是一样的,这几个都是相互制约的,你要想质量高,可能频次数量就要降低一点。要想频率高,质量就不可能太高,除非你一直投入大量资源,找很多人很多厉害的人来写,对于爬虫和机器其实也是一样的,你又想抓的频次高,又想质量好,你要更好的算法,你要更多的服务器,更多的硬件资源,才能去把它做得更好。

还有相同模式的边际成本。写文章也是,如果说今天想个话题,明天突然掉线了,想了一天没想出来,这个就不具有持续 *** 。假设你找到了一个模式,可以持续的输出内容,一天写一篇可以,一天写 5 篇,你要做什么事情?一天写 10 篇,你要做什么事情?或者是规模化,同样模式那种再把它增加几个数量级,你需要付出什么样的成本?所有的内容平台都会涉及这个问题,就是边际成本的问题,你自己如果做内容的话,就要想,等到规模起来以后,要付出什么样的成本。

下一个就是内容的传播,好内容自己会传播的。然后还有用户分享的部分,也有营销的部分了,也可能是被转载。

还有一个多平台发布,这个也是经常会用到的。一个内容可以通过工具在不同的平台发布,比如说写一篇文章,你可以在在开源中国,在知乎在 CSDN,在在自己的博客,简书都可以去一次 *** 的发布。

回到刚才说的边际成本,刚才说的是频次,就是多平台的边际成本,你写了一篇文章,换到另外一个平台需要付出什么样的成本,它并不是直接可以贴过去的,你从本地的 *** rkdown 到知乎也是有成本的。

首先它的 *** rkdown 不一定完全识别,然后 *** 直接外链也不一定能抓取到,有的时候可能是内网的,有时候可能需要你自己重新传一下,有的时候是内容不适合。还有被动的传播,就是你的内容可能会被别人的爬虫爬取,就是被动传播。站内推荐也是一种,好的内容,在站内被小编推荐。

下面要说到一个比较大的,SEO 的部分,之前讲过,应该大部分同学是听过的,我就快点过了。大家知道 SEO 就是搜索引擎优化,ASO 就是应用的搜索优化,如果放到苹果就是 App Store Optimization,然后如果安卓就是 Android Store Optimization。白帽优化,就是我们正常的,比较常规手段的优化,包括站内优化部分,还有一些工具,还有新站 SEO 的基本步骤。

战内优化的站点地图,如果是文件,然后站点本身的 *** IP,显示速度,同 IP的站点数量,包括你的域名的是不是权威 DNS,域名用了多少年。 *** 了多少年?域名当前的收录情况,网站历史之前是做什么的?有没有什么黑历史?有没有做一些 *** 毒 *** 之类的?通过搜索引擎的 site 命令就可以看到当前收录情况。也有很多工具可以看到,还有就是 whois 的信息,能不能查到,能查到什么样的信息。

这个可以给产品同学讲一下,所有的域名都有 whois 信息,来表明这个域名是谁注册的。它服务器在哪里?它的 *** 器是哪个 *** 商提供的。所有域名都有 whois 信息,但不是所有的 whois 信息都可以查到。你注册域名的时候,可以多花钱隐藏这个信息,别人就查不到。

下一个就是一些 404 页面的处理,301,50x 处理,还有我们之前做过的伪静态。网站 URL 的层级,针对 SEO 的文件名。还有 canonical 这个标签可以说一下。没有这个标签之前,很多搜索引擎会收录大量类似的重复的页面,可能只有一些微小差别,比如说分类不一样,或者是商品详情这些,大部分差不多。

这个标签的作用就是规范 URL,告诉搜索引擎这些差不多内容的页面,都有一个规范的 URL。就拿 PHP 举例,可能有的 URL 多个问号参数,有的可能多了些没有用的参数,有些可能多了一些哈希值之类的。这个标签就是告诉搜索引擎,不管我上面的 URL 长什么样,这个页面内容它的规范的 URL 就应该是这样。这个是跟搜索引擎说的。

下一个就是页面的 TDK,title,description,keywords。这里边跟 SEO 相关的有,核心关键词设置,还有热门关键词,长尾关键词。大家可以关注一下这几个网站,这些做云服务的网站,因为它有技术优势,它本身就是做技术的,所以它知道 SEO 该怎么玩,就会有一些投机取巧的办法。

你去阿里云这些去看,去 *** 云华为云这些看,他的帮助中心其实有很多跟他自己的业务一点关系都没有的关键词,他把所有的关键词都占了,所有跟技术或者是互联网相关的关键词全都生成一个页面,你们进去以后,除了关键词有差别,下面就是随机推荐的内容,这个就会造成大量的垃圾内容,但是会增加收录的权重。

还有一些通过 *** 隐藏的 SEO 内容。之前你如果用 *** s 里面的 display 属 *** ,有些搜索引擎可以识别的,但如果飘出去飘到屏幕外边,或者是被其他元素挡住,这种是很难判断的。它没有办法去完全解析你的样式文件。所以有些 SEO内容你不想让用户看到,是可以通过一些办法隐藏的,这个是技术相关的,非技术的可以了解一下,这些东西都是怎么玩的。

还有收录的数量,关键词的已经被收录了多少页面?他现在排名什么样,优化难度什么样,关键词的布局密度,这个跟刚才的内容生产有关,在你生产一篇内容的时候,你就要想好这个里面关键词怎么布局,在头尾出现多少次,然后一共出现多少次。这样的话这个文章对 SEO 才能更友好。

这里有一个说法叫「四处一词」,前面的 TDK 再加尾部或者是锚文本,这里边都要出现你想优化的关键词,还有网站导航的关键词,上面导航一定是要跟你的业务想做的核心关键词是有关系的,不是有关系,是要包含你的核心关键词才行。

H1,strong 标签,大家写代码的时候会说这个页面没有 H1,对搜索引擎是非常不友好的。不管这个页面是不是文章,它都要有一个 H1 *** 页面的标题,就是一句话点明这个页面到底是什么内容,是这样一个作用,并不一定是文章页。

还有就是语义化的标签,跟前端相关的就是标签本身的语义化。你到底是用了一个 P 段落,还是随便用的 DIV 和 SPAN,这些没有意义的标签。

下一个就是内链建设,这个有点像设计一个迷宫,更好让搜索引擎的爬虫(搜索引擎也是爬虫,搜索引擎收录的时候其实也是按你的站点地图和页面来爬)更好让它进来以后,就一直在那里边出不去。就是让搜索引擎的蜘蛛在你的网站里面多留一会儿,但是更好不要出现死循环。如果死循环就不太友好,还有死链,它走一走,走到死胡同,回不去了。内容部分刚才讲了很多了,这里面说到内容的总量,页面总量,就是你到底被搜索引擎收录了多少页面?几百个,几千个,还是几十万。

还有更新频率,蜘蛛会定期来一次,多久来一次你不知道,你的网站越活跃,它来的越频繁,然后但更新频率也不要太频繁,如果太频繁就不太自然,显然是一个。除非你是一个非常大的网站,真的从一开始有很多人给你贡献内容,这个其实是不太现实的。你就算去招人,你去招募作者,也是需要有时间的。

这里面还有一个点,就是你新建站点的时候,不用太快去提交搜索引擎,因为这个时候你没什么内容,你给搜索引擎看了,他之一次来,之一印象就觉得你这个网站可能没什么东西了。第二次来的时候如果还没有什么变化,基本上就认定你这个是没有什么变化。这里还可以多提一句,搜索引擎流量池,并不是说你一旦被搜索引擎收录了,就一定会被搜到。它是有两个层级的,有个底层流量池,还有上层的流量池。

在你自己提交的或者是只收录了几个页面,这种可能就是在底层的流量池,这个绝大部分时候你是不会出现的。就算这个关键字跟你相关,可能排到 100 页以后,别人根本看不到你。只有通过各种优化去进到顶层的流量池才有意义。

下面就是原创度,刚才说到了。有自己直接写的拼凑的,有机器生成的。不管你怎么搞的,最后都是要注意原创度,你可以通过原创度检测工具,来看一下这个东西到底搜索引擎认为你是不是原创。是不是你自己写的不要紧,关键是搜索引擎认为你是不是原创。这个加入收藏就是方便别人加入收藏,要在页面留一个。还有用户体验,界面的设计,打开速度这些。推荐 *** 这个就不说了。站外优化主要是以上这些。

外链建设也是涉及到流量的部分,站内只是你自己怎么把你的房子,把你的客厅,把你的家装修好。有没有人来还是另外一件事。既然说到流量,站外优化就是你的流量怎么来的问题。首先,刚才提到的友情链接交换这是一种,还有博客,这种嵌入的外链,一些书签网站论坛。这些大家看一眼,论坛,掘客,百科问答。

这些自媒体等都可以带来流量。然后刚才提到的这种,自然流量和搜索引擎流量, SEO 主要做的就是搜索引擎的流量部分,我们最开始可能是自己主动去到处发链接,去搞友情链接,到处去宣传网站。当这些外链达到一定数量级的时候,可能就变成被动流量了。每天总会有一些曝光。比如说你在外面发了100 个,过了两个月之后,可能每天有那么十几个人会看到,会进到你的网站来,这是一个长期的流量建设过程。

广告投放这个,是刚才付费流量的部分,说过了。这里还有一些奇技 *** 巧,之前看到了,比如说你的域名,你想宣传的网站,可以假装要卖域名,把你的域名放到各大域名交易所的网站上,如果域名看起来有点意思,可能就会有些流量进来,来看一下这个域名现在是个什么东西。

工具,这里边也有很多了,有统计分析相关的这些工具。我讲的主题比较深,大家可能都忘了前面是什么了,这个工具是 SEO 相关的工具,比如说统计分析的,关键词的工具,查关键词排名的,查长尾关键词的。长尾关键词挖掘是什么意思呢?你有一个词,比如说电饭煲,这种是核心关键词。那么,比如说电饭煲怎么维护?电饭煲坏了怎么修?这些就是长尾关键词。这些长尾关键词平时的量很小,但是你把长尾关键词建设好以后,因为他的时效 *** 比较长,比如说每天可能只有几十个,但是你大量的长尾关键词建设好之后,流量也是非常可观的。

比如说像刚才 *** 云阿里那种,可能都是有上千或者是几千个这种关键词。平时通过这种大量长尾关键词进来的量也是非常可观的。还有知乎引流工具。知乎引流,之前也提到一点,怎么从知乎把流量引进来,现在已经有对应的工具去帮你发现那些热门的回答。然后你再通过这些热门的回答,形成一篇你自己非常高质量的回答。你在这个回答里面在嵌入你的公众号,嵌入你的品牌,嵌入你要卖的东西,嵌入你的网站,都可以。这个也是常规 *** 作。

如果你没有这些东西的话,知乎好物推荐也可以。有很多人靠好物推荐,现在也过得不错。写一篇非常好的回答,然后就直接用知乎好物推荐去赚佣金,它走的是京东 *** 联盟这些的分佣。其实核心也是我今天要讲的,通过内容获取的流量。知乎本身就是一个内容平台,他是问答的形式内容平台。你作为一个个体,你想去吸引好的流量进来,吸引高赞,吸引高转发,你也是要做一个非常高质量的回答才行。

内容工具刚才也说过了。快排,其实是黑帽 SEO 的部分。这个后面再说。新站 SEO 的基本步骤,之前也说过了。先确定关键词,然后建站充实内容,不要太早去提交搜索引擎,还有外链建设这些,然后通过刚才说的统计分析工具,还有一些增长工具,前面提到的增长 *** ,比如像 GrowingIO这些,它本身形式上看起来是一个埋点统计的东西,其实侧重在增长。你把埋点埋进去以后,你会看到数据,它会针对数据给你一些模型和建议。

下一个就是黑帽的部分,之前可能提过一点。首先是霸屏,怎么实现呢?就是通过短时间内大量生成内容,聊天也是,聊天刷屏就是一直发表情了。或者发大量的废话。

百度霸屏,比如说每天 300 篇每天 500 篇文章,这个文章是怎么生成的呢?前面提到这些,机器来生成,可能质量不太高,但是通过欺骗搜索引擎也可以做 SEO。SEO 本身也是一个攻防博弈的过程,大家一直在想方想办法找它的算法漏洞,然后搜索引擎就一直在提升算法,让它变得更智能,来识别出那些好的内容。如果搜索引擎有点追求的话,还是想识别好的内容出来。

第二个就是站群,这个很古老的东西,早期都是靠站群来搞的。最明显的就是 *** 站,大家一不小心进了一个挺好看的 *** 站,然后发现点一点又到了另外一个站,再点一点又到了一个站。每个站的域名 *** 都不一样,然后不断有惊喜。其实如果你仔细去分析,有的时候可能是一个 IP,有可能是根本完全不同的 IP,你根本看不出来,它其实是一个人生成的。不只是 *** 站,有很多网站都是,比如说一些加盟的网站,然后什么 *** 卖 *** 的这种,都是通过站群的做的。

把刚才的那些批量生成的内容换成不同站点的形式,然后通过友情链接把你圈在里面,你只要在任何一个渠道进了它的站,然后他通过一些擦边球的内容,让你一直在里面转,即使你想跳走,忽然看到另外一个站跳走以后,其实还是他的站点。

那站群有什么用?你的流量一直在他的站里边玩,我一个站流量可能不多,但是我有 100 个站,流量是非常可观的,还可以通过工具去批量发广告。比如说做个管理后台,我一上架广告,它就在 100 个站里面全都出现广告,这个流量就很值钱了。

广告联盟也是,这些站都可以通过广告联广告联盟来赚钱。微信群控,大家应该也听过,网上有一些图,满墙都是 *** 的那种,这个就是群控的方式来实现的。它可以模拟不同用户,模拟大量真实用户的点击和访问。你比如说一篇公众号的文章,可能会通过微信群控这种,短时间把粉丝或者阅读量刷上去,你想要 10w+ ?很简单,出钱就可以了。你要 10w+ 赞都可以,反正就是花钱。这种有可能会被微信识别出来,这也是一个博弈的过程。抖音 *** 也是,这些都是刷赞之类的。好了,SEO 的部分讲完了。

SEM 这个也是很 *** 题,就是搜索引擎营销,前面的 SEO 也是有营销的部分。我们主动去买外链,主动去让流量进来,这也是营销的一部分。这个就涉及到自然搜索,还有花钱的部分,CPM/CPC 后面列了这么多方式,就不说了。做搜索引擎营销,百度品专这些都是,你花钱来做营销。

下面还有一些奇技 *** 巧。首先是关键词截流,因为前面提到的关键词的部分,比如说大家微信搜一搜的时候,会有很多推荐内容,尤其是在搜热点的时候。如果突然看到一些热点,然后你看微信指数,热点关键词的指数会突然飙上去。这个时候就会有人做关键词截流的事情,他可以快速发一篇文章,比如说头盔。头盔当时就是一个热点,有人很快地写了一篇文章,标题带头盔字样,然后里面就是卖头盔。在很短的时间卖出去很多头盔。

关键词截流的原理是什么呢?就是蹭热点关键词,然后在大家都没反应过来的时候,有人去搜热点相关的新闻或者是相关的消息的个时候,因为网上内容很少,只有你的内容被收录了,那就只能出现你的内容,就相当于把这个位置站住了。

知乎引流也是。你现在搜很多东西,前几个出现的都是知乎。之一页一定会有知乎。如果真的是你想要的关键词,可以把你的内容埋到之一页的知乎的问答的回答里面。如果你的回答非常好,可能在话题下面的回答会被置顶。一旦再有人在百度搜索你的关键词,知乎出现的之一页他点开看,就会看到你的之一个回答,流量就进来了。你的回答里面可以再继续向你的网站引流,或者是卖东西之类的,更好是沉淀到你自己的流量里边,你可以放个人个人的私域流量。

AppStrore 也有很多关键词截流,大家应该也有体会,你随便搜一个常规的音乐 App, *** App 的名字,会发现很多其他跟它类似的全都能出现。真的是因为它智能吗?并不是。因为他把应用的介绍里面,其他同类的竞争者全都写上去了。比如说我某某 App 是「像 xxx,xxx,xxx,xxx 一样的 App」。这样的话就相当于把关键词全都占了。

这个 AppStrore 是没有什么惩罚机制的,有一些搜索引擎,年头比较久了,是比较成熟的,你如果堆砌大量的关键字,比如说一个页面堆砌二三十个关键词,这种是会被惩罚的。但应用商店还没有这方面的措施,所以所有的应用都是把同类的东西全贴上去,你只要搜类似的都能把它搜出来。

还有一些意想不到的曝光,刚才提到的域名交易网站,还有一些输入错误的,我不知道大家有没有类似的经历,你想搜一个比较知名的网站,但是打错了,发现到了另外一个网站,这种流量也是也是很可观的。比如这个我有时候就会打错,sougou *** ,它真的是一个搜「狗」的网站。这个就是域名错误带来的流量。这个就是一些意想不到的曝光。

内容红利,内容其实是有红利的,在这些内容平台上面非常明显。因为内容平台它依赖的核心竞争力就是它的内容的数量和质量。所以在它早期的时候,一定会非常重视那些质量好的内容。比如说像知乎、小红书这些,为什么那些早一点的知乎大 V,如果认真回答问题,慢慢都能成为大 V?早期平台非常重视扶持这些愿意生产内容的用户。羊毛出在羊身上,你就是羊,平台要想办法让你去生产内容。

有很多人是分自愿分享的,自己什么利益也没有,就是愿意分享。还有是需要激励的,可能给个级别,给个什么专栏作家,给个什么优质作者,有一些荣誉。然后每年给一些小礼物之类的。

还有些要付钱的就给钱了,给稿费。有时候这两条路很难并行,因为有些人他就是为了情怀,他写完了以后你如果给钱,除非这个钱已经能盖过情怀。如果说钱不多,可能我因为你给我钱我反而不写了,会有这种情况存在。比如说本来我挺爱写的,开一个赞赏可能每天几块钱,但是也可能就不写了。

小红书也是,小红书红了好多年了,现在仍然是一个非常有价值的入口。这种种草的模式缺的就是一些优质的内容作者,并不一定自己要多能写,你可以去研究它的模式,可以去研究那些写得好的人,你把那些写得好的模式全都抄一遍,然后你按照他们方式去模仿,你就能写得很好。因为这些都是结构化写作,什么叫结构化写作?跟八股文差不多,跟写作文差不多,你只要固定套路就可以了。不需要像虚构类的的就那么随意,沿着套路,前面什么样后面什么样,把这个框架天天贴到你的桌子上,你就天天按照框架一条条去搜集素材,就能写得差不多。但不一定说能一下就红,但只要量足够,总会有一些能带来流量。

所以说,想做内容营销的话,一定要重视这些平台的早期红利,如果现在突然有一个什么新的内容平台出来,你如果是想建立一些影响力的话,就要抓住这种机会。

像 CSDN 上面很多比较大的号,其实都已经是爬虫爬取的了,都是做技术的,这些东西轻车熟路了。你看那些几百万的百万粉丝的,基本上都是爬虫,然后就搬运,有的下面会写「我只是互联网的搬运工」,你去告他也没什么办法,有些可能过了很长时间才发现被人抄了。告也没什么办法,抄一两篇文章平台也不至于把它打死。

这些是有共生的关系的,平台知道要维护那些真正的原创作者的版权,但是它也需要大量内容来充实。所以他不能一棒子把这些爬虫都打死。如果说全靠原创内容,是非常有限的,而且跟开饭店一样嘛,你的竞争力建立在厨子身上,你的核心价值在厨子身上,如果厨子都走了怎么办?所以说平台想积累自己能力,一定是这个平台本身的影响力。

抖音和快手早期都有这些问题,他的那些网红他那些 KOL 如果走了,有些对平台会造成很大的伤害。那平台就一定要在这方面权衡,他一方面要帮他上位去帮他建立影响力。一方面又希望影响力大部分是留在平台手里,而不是被个人带走。当然那些大的网红,他们自己也是有自己的调 *** ,他的粉丝都是根植在这个平台,比如说从抖音挪到快手,虽然也会带过去一些人,但是真正跟他过去开始用快手的还是会比较少,他们也是有很大迁移成本的,轻易也不会做这种事。

最后一个,没有免费午餐。因为这一条讲的是免费流量。其实任何的免费流量都是要付出的,你起码是要付出你的时间、精力、注意力。注意力其实也是金钱。之前跟父母讲他们就不懂,我用这些东西我都没花钱,我用微信我也没花钱,我看头条我看文章我也没花钱,他们挣什么钱?羊毛出在猪身上,然后狗付钱,就是这个逻辑。你也不是完全没有付出的,你付出的时间,你的注意力就是他们想要的。未来的互联网产品就是在争夺注意力,你 *** 上那么多应用,你有那么多文章要看,你有那么多 *** 要看,你还有那么多的网课要学习,你的时间到底会花在哪里,这就是需要选择的问题。

平台通过什么样的手段,通过什么样的营销能让你把更多的注意力花在我这里,这个是平台要思考的问题。你贡献的就是你的活跃度,你的内容,还有,国内更大问题,你贡献的是你的隐私。在中国互联网有句话是说,互联网是没有隐私的。做技术的就更清楚了。你可以这样来想象,互联网本身是什么,它不是一个虚构的,它是有实体在的。它实体在哪?是在另外一个地方的电脑里,在网线上。

假如说我用我自己的电脑搭了一个网站,你并不知道我背后是什么网站,我用自己的电脑,我申请了一个 *** IP,申请一个域名,它在网上看起来就是个网站,你在这网站注册,可能会要求你输入一些信息,哪怕不是一些很敏感的信息,或者一些看起来很正式的网站,你就把你的 *** 什么这些东西输入了之后。它的本质上什么?本质上是你把这个信息存到我电脑里了,这个比较好理解。

现在网上这些服务其实本质上也是一样的,你把你的信息存在各个商家的电脑里,这个是一个最基本的原理。但现在隐私都重视起来了,会通过层层的加密,加密至少会保证一般人看不到或者是普通员工看不到。这个是一些举措,我还有一些是比如说 *** 号一般会做一个单向的加密,在客户端就直接加密成一个字符串,比如说一般都是 MD5 或者是再加一个其他的混合的算法,然后再存到数据库里面。

这样的话在数据库里面,也就说在我的电脑里,我只能看到一个加密的字符串,但是我不知道它是怎么加密的,如果别人拿到数据以后不知道怎么解密。不,我还是知道如何加密的。我通过同样的加密方式,如果能跟匹配上,说明它是对的,但我并不知道它本身解密出来是什么样子。 *** 号这个例子并不贴切,因为 *** 号是可以穷举的,大概一两百亿的数据。你用同样的算法去撞,只是时间问题,可以把所有的结果都撞出来。但前提是你知道是怎么算的,如果是不知道怎么算的,这个还是比较安全的。其他的信息也可以通过这种方式来加密。

刚才提到单向加密,这里也可以说一下,加密是有单向和双向区分的。单项加密只能加密出一个东西,但你并不知道是什么,也没有办法根据这个东西来解密。双向就是你拿到串之后,能按照一定的方式把它给解出来。因为 MD5 已经好多年了, MD5 虽然说是单向加密,但如果只是用一个 MD5 函数,现在网上有很多网站,做了这种大数据的撞库,你如果只是 MD5,可以放到这些网站上查一下,有可能能「解密」出来。所以隐私信息大家可以多注意一下。

还有注册的时候,大家都看隐私协议,我不知道大家有没有看过《硅谷》,里边那个创始人,他有一次跟另外合伙人讨论这个问题,他是个程序员,他就说没有人会看隐私协议。但是另外一个人,因为他是做行政管理出身的,他就说所有人都会看这个协议。这就是「知识的诅咒」,你自己去做什么的,你就觉得所有人都会都会这样。

现场也可以调查一下,我觉得应该大部分人还是不看的。里面大概有几部分你们知道吗?比如说最基本的你的信息会怎么使用?这个是最重要的。我会怎么用你的信息你都不看一下吗?虽然你觉得确实是看了也嘚用,但你起码能知道他大概说了什么。比如说「我不会把你的数据交给未授权的第三方」,言下之意就是我授权我就可以给第三方,对吧?你就知道你的信息是可以给第三方的,只要这个公司授权就可以。大部分都会这么写的。他不会写「我不会给任何人」,没有这么写的。还有「不会在你不允许的情况下,给任何第三方」,有的时候就会问,就会让你授权。这个就是说明谁要用你的信息,你要不要允许?你要允许才能用。还有一个关于未成年人的部分,你如果未成年你能不能用这个应用?未成年一定是要监护人的允许才行。如果是 14 岁以下那就犯法了。

还有一个跟技术相关的就是关于 cookie 的使用,在 PC 上面现在很多国外网站下面都会弹个框,说我们的网站会用你的 cookie,你要不要同意?你如果不同意的话,有些功能可能用不了。

那 APP 里面也是有一个关于你的 cookie 是会怎么用的,会在哪保存。说我们会在服务器上保存,保存多久这些。大概都会说。大家可以随便找一个看看,大同小异。但是也会有一些会留坑的地方。

还有西部世界第三部,我不知道你们看没看过。那里边最厉害的那个球,他那个公司是怎么建立起来的?就是在互联网早期人们还不太重视隐私的时候,录入了全世界所有人的信息,包括他们各种出生信息,生活习惯,所有的 *** 使用习惯。其实我们现在基本上还是处于这个时代,再过 50 年可能就会有这样一个东西出来。它能根据现有的所有信息,再加上一些算法,能算出来你未来会做什么事情,甚至能算出整个世界是怎么演化的。

对。人工智能算命就是这么来的。他只要掌握的信息足够,是能算出你的,不能说完全算出命,肯定是有个概率要有一个大概率的事件。然后 *** 讲的 *** 通过这些来整个掌控人们的生活,所有人都不知道, *** 控着。

所有人都上网,所有都是通过计算机控制的,他可以通过比如说他觉得你这个人有危险,这辈子不能做太重要的事情。当你找工作的时候,他就只能给你分配一些打杂的活,然后你就只能找到这种工作,其他工作就找不到。但是普通人是不知道有这么个东西存在的。还是挺震撼的,大家可以看一下。而且这里面涉及到语音识别这些。

那个主角就是。就是《绝命毒师》里边那个小伙子,他最开始就是一直在打 *** ,一直在跟他的战友打 *** ,但后来你才发现他其实是个 AI,因为他战友已经去世了,他买了个服务,通过他战友生前的一些影像资料,来模拟他的声音,然后天天跟他聊天,这是一个心理心理医生的治疗手段。给他开了这样一个方子,他的方子就是天天跟他已经逝去的战友聊天,因为他没有办法接受 *** 这些创伤和战友的逝世。

对,后来他找工作也是有个「人」给他打 *** ,然后就拒绝了他。他就问为什么拒绝我?我还有什么可以改进的?然后那个人一直重复非常客套的话。然后他就做了个「图灵测试」,问了一句很难回答的问题,然后 AI 就又说了一句完全不相关的话。他就知道整个来把他辞掉的这个「人」是 AI,连人都没有,就直接把拒绝了。

最后,就是免费的才是最贵的,大家都懂。其实主要是时间了,因为时间才是最贵的。像比特币大佬李笑来,之前新东方的老师,他有一本书叫《把时间当做朋友》,其实奉行的一个观点就是:能用钱解决的才是更便宜的。

三、流量池思维

还有最后一部分,流量池思维。我手边这个 luckin 嘛,后来翻车了。他当时的 CMO 写了一本书叫《流量池》,所谓的流量池思维,主要是根据这本书出来的。思维其实还是很有价值的,所以这里单独讲一下。

首先就是这个私域流量建设,刚才说到了。未来一定是这种基于社会关系,基于信任的商业。微商这个事最开始可能有些人看不起,有些人不齿。但是它可能真的是未来。像社区团购这些,一定是你能接触到的人,你相信的人,你信任的人,你才会购买。直播也是,很多时候,大家就是信任主播,比如说李佳琦的粉丝,都是建立在信任基础上,并不是他的名气有多大,东西就一定好用。是你相信他给你推荐的,一定物美价廉的东西。

罗振宇在他的 2019 年的跨年演讲上面说到保险的事,保险 *** 人,可能后面几十年都会是你的 *** 人。哪怕他不做保险,或者不在这 *** 司了,你后面有什么事情都可以找他。以后的生意应该就是这种样子的:互相信任的人,或者是你周围的圈子,他们发现什么好玩实用的东西,或者是你需要他们去给你推荐一些什么东西。并且他们能很方便地获得这种渠道,顺便还能有利润。这个可能是未来主要的商业模式。

流量池思维说的是什么呢?前面说了那么多,如何生产内容,如何产生流量,公域流量私域流量这些东西。流量池思维就是,你想象在整个公域流量就是所有的世间万物,都是流量,怎样把它们汇集到一起?变成你能用的,你能变现的,有商业价值的流量。这个就是流量池思维,根本就是连接。

微信上经常有些「交际花」,喜欢到处加人,群里面也会经常有加的。但是有些可能是机器人,还有些是用工具加的。最开始你也不知道为什么要加你,就留一句「你好,我是什么?什么?连接一下」。这个「连接一下」是为了什么?连接一下,你就变成他的私域流量了。还有人签名说「我把你当朋友,你把我当私语流量?」。

目前主要的一些工具,可以落地这个私域流量的,就是企业微信、公众号,还有个人微信号,还有社群,比如说微信群、知识星球,企业微信群这些。只要能沉淀下来,你能直接触达的,都算你的私域流量。

朋友圈也是,微商主要是靠朋友圈多一点,尤其是母婴圈子。母婴圈子,朋友圈还有微信群是成交非常高的。可能尿片或者是什么东西,在群里面随便喊一喊,就能有个几万块钱的订单,这些都是经常能见到的。

还有就是流量池思维里边用这个「鱼塘」打比方是非常贴切的。首先公域的流量你可以想象成大海、湖泊、或者是别人的鱼塘。通过前面讲的那些东西去引流成交,那就变成了你自己的鱼塘,就是私域流量。然后还可以通过做营销活动做裂变,裂变出更多的,自己的鱼塘。整个路线就是寻鱼、找鱼,然后圈鱼,最后就是钓鱼,养鱼,生鱼,这样的话大家可能印象比较深了。网上还有一些图,真的是有画鱼,这个就是鱼塘的思维,重点就是从公域流量到私域流量。

比如说刚才说到,大街上过的车,你可以把它当成公域流量,这个车你没有办法让产生利润。大街上每天过那么多车,每天在商圈有那么多人,你如果通过门口搞活动,让他进来了,就算是把鱼圈住了。过的车也是,如果想收钱,高速公路收费可以收到钱,或者是你在十字路口擦个玻璃什么的,可以收到钱。这个就是从公域流量到私域流量的事情。

最后一个点,流量就等于钱吗?我看也有人点头的。早期的互联网流量,流量就是等于钱。一个网站,只要有人访问,它就能卖钱。至于说你在里面打广告有什么作用,会有什么人看,根本不重要。可能这个网站是养宠物的,但是你想你在那个里面,放理财广告,可能就没什么效果。现在已经很清晰了,流量完全不等于钱,甚至跟钱可能完全没关系,亏钱都有可能。你如果用网站来承接流量的话,需要很大的服务器资源。所以可能是亏钱的。而且,现在互联网上的获客成本是非常高的。

有数据表示,你在互联网上达成一个成交,获客成本大概要 100 块以上,100~200 之间平均。虽然你没花钱,但是商家为了能触达到你,为了能让你成交,要花 200 多块钱才能给你接上线。对,现在成本就是这样的。

所以说,如果从最开始没有想到怎么落地,怎么变现,你的商业模式是什么样的时候,流量是没有任何意义的。首先你要想到如何去承接你的流量,到底是用网站落地页?还是把它转到你的公众号?还是转到你的微信的个人号?一定要先想好,把每一步都想好。我怎么获取流量,流量来了以后我用什么接?我用微信接了以后,我一个人能不能接得住?比如说我拉了一个群,突然到 100 满了,那有解决这个问题的「活码」工具,每 100 个人建个群,通过「活码」来解决承接流量的问题。

这些人进来了,突然来 1000 人,你能不能忙得过来?拉完群以后,你怎么样让他们不走?之一步「寻鱼」、「诱鱼」,可能有个低成本的勾子产品,比如9 块 9,或者是免费体验课,你先来体验一下。怎么听课呢?我拉你进一个听课群,然后到时候有老师讲课,然后有免费资料发放。由于这个圈已经把你圈住了,然后课结束之后,我再送一个价值 288 元的听课体验券,你只需要再付200 元,就能获得一个什么样的课程。这个都是一步一步的转化,现在玩法都是非常复杂的,没有办法很简单地就能获得成交。大家也可以想一下,你的钱花得也没有那么容易,你都是要想想,然后一言不合就关掉了。一言不合就付钱的还是比较少吧。

所以商业模式还有整个的落地过程一定要先想好,才能更好地承接流量。还有技术方面也是,这个人来了,你能不能接得住?我们之前做过一些活动,开始没有预想到有那么大量,真正流量来的时候,可能是接不住的。有可能是你只有实体服务器,不好扩容;也可能是你用了云计算,但是你的扩容机制没那么好。比如说加机器,这三个字说起来简单,但并不是说点个按钮加上就完事了。这里面有很多部署上的问题,还有数据同步的问题。分布式的 CAP 原则(CAP原则又称CAP定理,指的是在一个分布式 *** 中,一致 *** (Consistency)、可用 *** (Availability)、分区容错 *** (Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾),你要遵守。并不是加机器就能解决所有问题。如何承接流量技术上也是要想好的,没有办法变现的流量,是浪费资源。

差不多就这么多了。前面最开始是讲流量这个事情,就后面涉及到一些关于运营营销,然后还有一些技术相关的东西。覆盖的细节比较多,大家有没有什么问题?

四、互动环节

问:我个人感觉他最多就是比较常见的是以广告的方式去变现。除了以广告方式面向还有什么其他方式吗?

答:付费产品或服务。要么是卖产品,要么是卖服务。相当于直接销售产品,销售服务都是。可以直接卖给他实体的产品,像我们做家电的主要就是把它引流过来,卖家电就是。对,就是带货。然后销售服务也是,比如说我的咨询服务,你像律师,比如说 *** 律师可能一小时都是1000~3000 港币起的,这个就是服务的钱。

你想想你平时的钱都花在哪?刚才说到电信流量,电信流量你花的什么钱?也是服务嘛。这里我想起来有一本书叫《管道的艺术》,就是讲这种赚钱的方式。我们日常打工就是一种提水桶的模式,我们上一天班就是提一天桶,如果哪天不提水桶了,你就没有钱。

管道是什么?管道就是建一个自来水厂。你想想,你平时交的水费电费他们做什么了?他们平时只要日常维护就可以了。电厂那个厂本身是不能停,但是大部分人他睡觉的时候,你还是要交电费的,你还是要交水费的。整体这个模式是一直有钱在流的。这就是管道的艺术。所以你想商业模式的时候,一定要想那种「雁过拔毛」的生意,只要有人或者有流量,或者有什么东西在你这里流动(整个 *** 是流动的)你就能收钱。像高速公路,你只要过就要收钱。

只要有人来人往都可以,或者有现金流在那流动,你可以收点位。比如微信支付、支付宝支付,这些都是要扣点的。这也是一个流水生意,他什么都不做,你只要有 100 块钱,我就扣你一块钱,对吧?如果大点企业可能是 0.6%,100 块钱我扣你 6 毛钱。

利息也是,水在你这留,你可以薅毛,可以用它来生钱。为什么现在很多充值都不让搞?比如说一个 *** ,每一个人都冲 300,我手里边可能几十万,我几十万不干别的,先去做理财也有利可图。

现在很多很多充值的都已经叫停了,不允许充值了。还提前给钱对还。对,提前给钱我就可以蓄水了。这相当于我在水流中间挖了个坑。买房也是,像华润城那些,一瞬间几个亿留在开发商那里,一天就很多钱,做短贷就很多钱,如果把整个链路都事先聊好的话。

你自己也是,如果突然有大笔资金过手,然后搏一搏??嘿嘿,是吧。可能就没了。期货是吧?快进快出,对。生猪期货!商业模式大家可以了解一下,其实还挺有意思的。

问:你自己的 *** 号和知乎要去做引流吗?

答:没有。首先这个东西客观讲还是需要一定的精力的,比如说 *** 。我刚才有提到内容生产的成本问题,那拍 *** 的成本相对是比较高的。除非你就拍生活 *** ,比如现在我们在这讲课, *** 往这一支,我就随便说一段。这个成本可能比较低,但它的质量也会比较低。你如果想做好的 *** ,要先想文案,你要想怎么拍?你的机位,穿什么衣服,你也不能太随意。像 *** 有很多油腻大叔,或者直接怼镜头的这种,就很粗制滥造。

这些都是潜在的成本。可能一个 *** 一两个小时的 *** 时间。现在成熟的 *** 大号, *** 一分钟 *** ,可能就要三四个小时来拍,中间可能还会 NG,不一定就能一次成功。念稿也可能会念错,不管是念稿还是背稿,念也要念得自然才行吧。就算照着屏幕上的提词器,照着词念也不是说所有人都能念得很溜。中间如果卡了觉得不满意,就要再来一遍。

我发的是读书 *** ,你看着只是照着念,但如果想念得顺畅,有的时候也要好几遍。有时候一条下来嗓子也都哑了,这个就是成本。

文章也是,你想写好一点的文章,除非突然灵感来了拦都拦不住,可能十几二十分钟就能写一篇。如果平时(还是刚才说的边际成本的问题)你没有非常成熟的写作框架,是很难持续产出的。

还有就是你觉得这个事重不重要?你如果觉得不重要就很容易耽误,就像健身一样,你如果没得过什么大病,总觉得它不是个事儿,肯定是能推就推。所以说,所有的没有时间,其实都是优先级的问题。每个人时间都是一样的,只是这个时间你用来做什么的问题。

#专栏作家#

姬小光,微信公众号:姬小光(ID:hi-laser),人人都是产品经理专栏作家。现任美的集团电子商务有限公司商城前端组负责人,曾就职于 *** / *** /京东,拥有 10 年电商研发经验,对产品、设计、研发、运营都有一定见解。

本文原创发布于人人都是产品经理。未经许可,禁止转载。

题图来自Unsplash,基于CC0协议

标签: 文案 鸡汤 生成器 高级 ***

抱歉,评论功能暂时关闭!