2乘ln4等于多少

有一个笑话说,计算机科学界有两大难题:一是缓存失效问题,二是命名问题。但我认为还有第三个更难的问题:相等问题。你没看错,等号“=”看似简单,但等号的使用和误用,是软件工程中许多重大问题的根源。

声明:本文已获作者Craig Stuntz翻译授权。

2乘ln4等于多少

作者 | Craig Stuntz

译者 | 弯月,责编 | 郭芮

头图 | CSDN 下载自视觉中国

出品 | CSDN(ID:CSDNnews)

以下为译文:

2乘ln4等于多少

相等的原理

我来展示一下在编程语言中相等有多么容易出错。但首先我要解释一下相等应有的模样,而这其实非常难解释!当我们讨论相等“应该如何”时,我们必须指出是特定语境下的相等,因为相等的成立有许多方式,许多方式在不同的语境下都是成立的。

“数学的精髓在于,同一个东西可以用不同的方式呈现给我们。”

——Barry Mazur,《When is one thing equal to some other thing》

定律

我说过,在不同的语境下,相等有不同的含义,但尽管如此,有些东西是永远成立的。这就是相等的定律。

相等是一个二元操作,它是:

反射的,即对于任意值 a 都有 a = a

对称的,即a = b可以推出b = a,反之亦然

传递的,即如果a = b且b = c,则a = c

在编程的世界中,我们需要增加一条定律,因为有时候程序员会做一些奇怪的事情:

相等必须是:

一致的,即如果a = b且a或b的任何字段都没有发生变化,那么稍后再次检查时a = b应当依然成立。

上面的定律看似简单,但流行的编程语言甚至连如此简单的定律都无法遵守。但更严重的关于相等的问题甚至都很难精确描述。

结构相等性

在编程语言对于相等的各种实现中,一个重要的区别就是结构相等和引用相等。

结构相等会检查两个引用是否为同一个值。F#默认采用了结构相等:

type MyString = { SomeField : string }let a = { SomeField = “Some value” }let b = { SomeField = “Some value” }if a = b then // 返回true, 进入 “then” 代码块

但在C#中则不是这样,C#使用的是引用相等。引用相等要求两个被比较的对象是同一个对象。换句话说,它会比较两个变量是否指向同一个内存地址。指向两个不同内存地址的引用会被判为不相等,即使它们的值完全一样:

class MyString { private readonly string someField; public string SomeField { get; } public MyString(string someField) => this.someField = someField;}var a = new MyString(“Some value”);var b = new MyString(“Some value”);if (a == b) { // 返回 false, 不会进入代码块

其他语言会让你选择。例如,Scheme提供了equal?来检查结构相等,eq?来检查引用相等。Kotlin提供了==用于结构相等,===用于引用相等(不要与JavaScript的==和===操作符混淆,JavaScript的那个是完全不同的东西)。

程序中何时应当使用结构相等?如果变量的值不会改变更,那么几乎任何情况下都应该使用结构相等!我所知的绝大多数编程语言在诸如integers之类的类型上都使用结构比较。除了Java之外,int类型进行结构比较,Integer类型进行引用比较,这迷惑了一代又一代的程序员。Python的is也有类似的问题。

对于引用类型(如对象)也应当进行结构比较。考虑一个单元测试,你希望检查返回的对象是否等于你期待的值。在使用结构相等的语言中,这个操作非常简单:

[<TestMethod>]let “The result of the calculation is the expected value“ = let expected = { SomeField = “Some value”; SomeOtherField = 15; StillAnotherField = true; … } let actual = calculate Assert.AreEqual(expected, actual)

但如果语言不支持结构相等,而开发者需要自行开发,就会遇到难题。

引用相等

但正如我刚才说过的那样,某些特定情况下不应该使用结构相等。一种情况就是语言支持变量内容改变的情况,而绝大多数编程语言都支持。当某个变量的值被改变后,说这个变量等于另一个变量显然是不合理的。当然,你可以说在进行比较的时刻,这两个变量(在结构上)是相等的,比如在单元测试的最后一行时是相等的,但一般情况下你无法假设这两个变量是同一个东西。这点理解起来有些困难,我来举例说明。

我们假设有一个对象,表示一个人。在采用了结构相等的F#中,我可以这样写:

type Person = { Name : string; Age : integer; Offspring : Person list }

现在我有两个朋友Jane和Sue,她们都有一个叫John的儿子,年龄都是15岁。他们是不同的人,但姓名和年龄都一样。没问题!

let jane = { Name = “Jane”; Age = 47; Offspring = [ { Name = “John”; Age = 15; Offspring = [] } ] }let sue = { Name = “Sue”; Age = 35; Offspring = [ { Name = “John”; Age = 15; Offspring = [] } ] }

也可以这样写:

let john = { Name = “John”; Age = 15; Offspring = };let jane = { Name = “Jane”; Age = 47; Offspring = [ john ] }let sue = { Name = “Sue”; Age = 35; Offspring = [ john ] }

这两段代码的功能完全一样。我没办法区别两个儿子,即使我知道他们是不同的人。但这没有问题!如果我需要区别他们,我可以把他们DNA的hash之类的属性加到Person类型中。但如果我只需要知道他们的名字和年龄,那么是否能区分两个对象并不重要,因为不管怎么区分,它们的值都是一样的。

假设Jane的儿子改名成Pat。F#不支持改变变量的值,所以我需要为John(还有Jane!)创建新的Person实例:

let newJane = { Name = “Jane”; Age = 47; Offspring = [ { Name = “Pat”; Age = 15; Offspring = [] } ] }

这个新的变量newJane似乎有点奇怪,但实际上并不会构成问题。上面的代码没有问题。现在用C#试一下,在C#中,变量默认情况下是可以修改的:

var john = new Person(“John”, 15, );var jane = new Person(“Jane”, 15, new List<Person> { john });var sue = new Person(“Sue”, 15, new List<Person> { john });

这段代码显然是不正确的:如果Jane的儿子改名为Pat,我可以直接改变引用的值:

jane.Offspring.First.Name = “Pat”;

但我就会发现Sue的儿子也改名了!因此,即使两个儿子最初的名字是一样的,但他们并不相等!所以我应该写成:

var jane = new Person(“Jane”, 15, new List<Person> { new Person(“John”, 15, ) });var sue = new Person(“Sue”, 15, new List<Person> { new Person(“John”, 15, ) });

这样Jane和Sue的孩子就是引用不相等。所以,在可以改变变量内容的语言中,默认采用引用相等是合理的。

另一种应该采用引用相等的情况是,事先知道引用相等的结果与结构相等相同。测试结构相等显然需要额外开销,如果真的需要测试结构相等,那么这个额外开销是正常的。但是,假设你创建了大量的对象,而且事先知道每个对象都是结构不相等的,那么花费额外开销来测试结构相等是没有必要的,因为仅仅测试引用相等就可以得出同样的结果。

2乘ln4等于多少

相等性的表示

在实数中,0.999……(无限循环小数)等于1。注意这里说的“实数”与编程语言中的Real类型不一样。在数学中,实数是无限的,而编程语言中的实数是有限的。因此,编程语言中没有0.999……这样的写法,但没关系,你可以使用1,反正两者的值是一样的。

这本质上是数学家在表示实数系统时采用的一种选择。如果在系统中加入另外一种对象,比如无限小的数,那么0.999……和1就不相等了。

“但是这并不等于说规范可以任意确定,因为不接受一种规范,必然会导致不得不发明奇怪的新对象,或者不得不放弃某些熟知的数学规则。”

——Timothy Gowers,《Mathmetics: A Very Short Introduction》

类似地,在实数系统中,1/2和2/4表示同样的值。

不要把这些“相等”与JavaScript或PHP中的“不严格”相等运算符==混淆。这些相等跟那些运算符不一样,这些相等依然遵循相等的定律。重要的是要认识到,对象的相等可以用不同的方式来表达。

在IEEE-754浮点数系统中,-0 = 0。

内涵和外延

一个函数何时等于另一个函数?绝大多数编程语言会进行引用相等的比较,我觉得这没有问题。因为,对函数进行结构比较有什么意义呢?也许我们可以使用反射来检查函数的实现,看看它们实现是否一样?但怎样才叫“一样”?变量名是否必须完全一样?快速排序和归并排序是不是“一样”的函数?

因此我们说,只要函数对于同样的输入返回同样的输出(不管其内部实现如何),函数就是外延相等的,而如果内部定义也一样,则是内涵相等的。当然,这也取决于语境。可能在某个语境中,我需要常数时间的函数,在另一个语境中,速度无关紧要。重要的是,必须有语境才能定义相等,才能用它来比较两个函数。

我不知道是否有哪种语言在比较函数时尝试过采用引用相等之外的方法。但很容易想出,这会很有用!(例如,优化器尝试移除重复的代码等。)你只能自己实现,但我不得不说,没有相等比较,总要比错误的相等比较强。

相等和赋值

当程序员的第一天就学过,“等于”这个名字有两种不同的概念。一种是赋值,另一种是测试相等性。在JavaScript中需要这样写:

const aValue = someFunction; // 赋值if (aValue === 3) { // 测试相等

这两者本质上是不同的。比较返回布尔值,而在面向表达式的语言(如Ruby)中,赋值返回被赋的值。

所以Ruby代码可以这样写:

a = b = c = 3

实际上会把3赋给变量a,b和c。不要在引用类型上尝试,很可能得不到你想要的结果!

在非面向表达式的语言(如C#)中,赋值没有返回值。

在数学中,赋值和测试相等性都使用相等运算符:

if aValue = 3 … where aValue = someFunction

(而且在数学中,有时候=还用于其他关系,如合同(congruence)。与数学中的其他东西一样,这里也要区分语境;在阅读论文或书籍时必须注意语境。)

为什么数学不要求两种不同的操作,而编程语言要求?因为在数学中可以轻易判断出语境,而且也并非所有语言都要求不同的运算符。例如,F#中赋值和测试相等都采用=。尽管两者采用相同的符号,但赋值和测试相等是完全不同的操作。

let aValue = someFunction; // 赋值if aValue = 3 then // 测试相等

语法的选择部分出于历史原因:F#基于ML,而ML基于数学;而JavaScript的语法基于Java→C→Algo→FORTRAN。

用于编译FORTRAN代码的机器很难根据语法来区分两种情况,因此采用不同的运算符是合理的。于是C语言把这个“特性”带到了新的高度,所以你甚至可以写:

int aValue = someFunction; // 赋值if (aValue = 3) { // 也是赋值!

给没有C语言经验的人解释一下:这段代码先用3覆盖aValue,然后由于表达式aValue = 3的值为3,因此if的条件为真,因此会继续执行if块内的代码。通常这种写法都是错误的,因此许多C程序员会将if块的条件反过来写,来避免造成该错误:

int aValue = someFunction; // 赋值if (3 == aValue) { // 测试相等
// […]
if (3 = aValue) { // 语法错误:无法将 aValue 赋值给 3.

2乘ln4等于多少

相等性的使用错误

通过上面的说明,希望大家都已经明白相等性并不简单,“正确”的实现取决于语境。尽管如此,编程语言经常会把最容易的地方搞错!很多时候,这是相等性与其他语言特性的组合造成的,如隐式类型转换。

2乘ln4等于多少

常见错误:相等性不是反射的

回忆一下相等性的反射率,即任何值都等于它自身,a = a。

在.NET中,如果在值类型上调用Object.ReferenceEquals,其参数会在执行方法之前分别进行打包,因此即使传递同一个实例,也会返回假:

(来自文档的例子)

int int1 = 3;Console.WriteLine(Object.ReferenceEquals(int1, int1)); // 输出 False

这意味着在任何.NET语言中 a = a 都不一定为真,因此不满足反射率。

在SQL中,不等于自身,因此表达式 = (或者更可能的情况是,SOME_EXPRESSION = SOME_OTHER_EXPRESSION时两者都可能为)会返回false。这会导致下面乱糟糟的语句:

WHERE (SOME_EXPRESSION = SOME_OTHER_EXPRESSION) OR (SOME_EXPRESSION IS AND SOME_OTHER_EXPRESSION IS )

而更可能发生的情况是,开发者会忘记的特殊规则从而导致bug。一些数据库服务器的SQL语言支持IS NOT DISTINCT FROM,它的功能才是=应该有的功能。(或者我应该说,它没有不做=应该做的事情?)否则,就必须使用上面例子中的SQL语句。最好的解决办法就是尽可能使用不允许的列。

IEEE-754浮点数也有同样的问题,即NaN != NaN。一种解释是,NaN表示某个不确定的“非数字”结果,而不同计算得出的NaN并不一定是同一个不确定的非数字,所以这个比较本身就是不正确的。例如,square_root(-2)和infinity/infinity两者的结果都是NaN,但显然它们不一样!有时候SQL的问题也可以类似地解释。这样造成的问题之一就是术语的含义过多:NaN和表示的是“未知”,还是“不精确的值”,或者是“缺少值”?

对于此类正常的浮点运算中不会出现的问题,解决方法之一就是采用联合(union)类型。在F#中可以这样写:

type Maybefloat = | Float of float | Imaginary of real: float * imaginary: float | Indeterminate | /// …

然后就可以在计算中正确处理这些情况了。如果在计算中遇到预料之外的NaN,可以使用signaling NaN来抛出异常。

Rust提供了Eq和PartialEq两个trait。没有实现Eq,是==运算符不遵从反射率的一个信号,而Rust中的浮点类型就没有实现Eq。但即使不实现Eq,你依然可以在代码中使用==。实现Eq可以将对象作为hash map的键使用,可能会导致其他地方的行为发生变化。

但是=和浮点数还有更严重的问题。

2乘ln4等于多少

常见错误:相等过于精确

我想许多开发者都熟悉IEEE-754浮点数的比较问题,因为绝大多数语言的“float”或“double”的实现都是IEEE-754。10 *(0.1) 不等于1,因为“0.1”实际上等于0.100000001490116119384765625,或0.1000000000000000055511151231257827021181583404541015625。如果你对此问题感到陌生,你可以阅读这篇文章(https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/),但这里的重点是,在浮点数上使用==进行比较是完全不安全的!你必须决定哪些数字是重要的,然后据此进行比较。

(更糟糕的是,浮点数是许多其他类型的基础,如某些语言中的TDateTime类型,所以即使一些相等比较本该合理的地方,也不能正常工作。)

比较浮点数的正确方法是看它们是否“相近”,而“相近”在不同语境下有不同的含义。这并不是简单的==能够完成的。如果你发现经常需要做这种事情,那么也许你该考虑使用其他数据类型,如固定精度的小数。

既然如此,为什么编程语言要在无法支持的类型上提供==比较呢?其实编程语言为每一种类型都提供了==,程序员需要依靠自己的知识来判断哪些不能用。

SML的实现说明(http://sml-family.org/Basis/real.html)上这样说:

判断real是否为相等的类型,如果是,那么相等本身的意义也是有问题的。IEEE指出,零的符号在比较中应当被忽略,而任意一个参数为NaN时,相等比较应当返回false。这些约束对于SML程序员来说非常麻烦。前者意味着 0 = ~0 为true,而r/0 = r/~0为false。后者意味着r = r可能出现返回false的异常情况,或者对于ref cell rr,可能存在 rr = rr 成立但是 !rr = !rr 不成立的情况。我们可以接受零的无符号比较,但是认为相等的反射率、结构相等,以及<>和not o =的等价性应当被保留。这些额外的复杂性让我们作出决定,real不是具有相等性的类型。

通过禁止real拥有=运算,SML强迫开发者思考他们真正需要什么样的比较。我认为这个特性非常好!

F#提供了[<NoEquality>]属性,来标记那些=不应该被使用的自定义类型。遗憾的是,他们并没有将float做上标记!

2乘ln4等于多少

常见错误:不相等的“相等”

PHP有两个单独的运算符:==和===。==的文档将其称为“相等”,并记载到“如果在类型转换后$a等于$b则返回TRUE”。不幸的是,这意味着==运算符是不可靠的:

<?php var_dump(“608E-4234” == “272E-3063”); // true?>

尽管这里比较的是字符串,但PHP发现两者都可以被转换为数字,所以就进行了转换。由于这两个数字非常小(例如第一个数字是608 * 10^-4234),而我们之前说过,浮点数比较非常困难。将这两者都转换成浮点数float(0)将导致它们被四舍五入成同一个值,因此该比较返回真。

注意这与JavaScript的行为不同。JavaScript也有与PHP类似的(但并不是一样的!)==和===运算符;但JavaScript会认为两侧都为字符串,然后返回比较结果false。

幸运的是,PHP提供了===(“全等”)运算符,在这种情况下能给出正确结果。我想说永远不要使用==,但==会在对象上执行结构比较,有时候正是你需要的!因此我只能说,使用==时要格外小心,因为它不能在基础类型上正确工作。

2乘ln4等于多少

常见错误:相等不是对称的

如果你要在Java中重载.equals,那么你必须负责确保相等的定律成立!

如果不加注意,那么很容易就会导致不对称的相等,即a.equals(b) != b.equals(a)。

即使不考虑的情况(因为会导致PointerException,而.equals()是允许这种情况发生的:https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-),如果你继承一个类并重载.equals,也最好多加小心!

@Overridepublic boolean equals(Object o) { if (this == o) return true; if (o == ) return false; if (!o.getClass.isAssignableFrom(getClass)) // 危险!这一步是错的! return false; ThisClass thisClass = (ThisClass) o; // 字段比较 // …}

如果ThisClass和ASubtypeOfThisClass都用类似上面的代码重载了.equals,那么a.equals(b)就可能不等于b.equals(a)!正确的比较应该是:

if (getClass != o.getClass) return false;

这不仅仅是我的个人看法,也是Object.equals的契约的要求(https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-)。

2乘ln4等于多少

常见错误:相等没有传递性

回忆一下相等比较的定律之一就是应当具有传递性,即如果a = b 且 b = c,那么 a = c。不幸的是,与类型转换(type coersion)放在一起后,许多语言都会在这里出问题。

在JavaScript中,

” == 0; // true0 == ‘0’; // true” == ‘0’; // false!

因此在JavaScript中永远不要使用==,应该使用===。

2乘ln4等于多少

常见错误:相等性不一致

在Kotlin中,==会根据变量类型返回不同的值,即使对于同一个变量:

fun equalsFloat(a: Float, b: Float) { println(a == b);}
fun equalsAny(a: Any, b: Any) { println(a == b);}
fun main(args: Array<String>) { val a = Float.NaN; val b = Float.NaN; equalsFloat(a, b); equalsAny(a, b);}// prints false, true

这是一个非常不幸的语言特性组合,可能会导致违反直觉的行为。

2乘ln4等于多少

常见错误:在应当使用结构相等的地方使用引用相等

考虑如下用C#编写的MSTest单元测试:

[TestMethod] public void Calculation_Is_Correct { var expected = new Result(SOME_EXPECTED_VALUE);
var actual = _service.DoCalculation(SOME_INPUT);
Assert.AreEqual(expected, actual);}

这段代码能正常工作吗?我们不知道!Assert.AreEqual最终会调用Object.Equals,默认会进行引用比较。除非你重载了Result.Equals进行结构比较,否则这个单元测试无法正常工作。Object.Equals认为,如果类型是可改变的,那么不应该重载。通常来说这是合理的,但在单元测试中却未必。(这是因为.Equals()本应比较.GetHashCode(),而一个对象的hash code在对象的生命周期中应该不发生改变。).NET framework中对于引用类型的最接近“有保证的结构比较”的是IEquatable<T>,但Assert.AreEqual并没有使用,即使实现了也不会使用。

而NUnit的情况更糟(https://github.com/nunit/nunit/issues/1249)。

(相反,Java的Object.hashCode在对象的字段发生变化时是允许变化的。https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode())

2乘ln4等于多少

应该怎样看待相等

没想到关于=运算符我写了这么多还没写完!好吧,这已经远远超过了运算符本身。为什么如此复杂?基本上有两个原因:

非本质的复杂性:我们的编程语言在相等比较方面做得并不好。经常完全不能正常工作,甚至在不能正常工作时也不会明确表示这一点,例如会在本应进行引用比较的地方使用结构比较。

本质的复杂性:相等性本身就是复杂的,如比较浮点数。而在诸如比较函数等边缘情况下就更为复杂。

另一种划分方法就是“应该由编程语言的实现者负责解决的问题”(上面的“非本质的复杂性”)和“应该由编程语言的使用者负责解决的问题”。

编程语言应该怎么做?

关于非本质的复杂性,现状是几乎每一种主流编程语言对于相等性的实现都有问题。这个“必须遵循几个定律的简单运算”正是编程语言为了保证正确性而依赖的东西!但在我看来,只有SML真正思考了怎样在语义和运行时/标准库方面同时保证符合定律的相等性,而SML完全不是主流语言。

首先,在禁止相等比较的地方,编程语言应该很容易创建不允许相等比较的类型,因为这易操作完全没有必要复杂(如F#中的[<NoEquality>]),然后应该在标准库中尽可能多地使用该特性,如浮点类型。

编程语言必须非常明确地指出结构相等和引用相等之间的差异。永远都不应该存在行为不确定的情况。绝大多数编程语言会重载==,根据引用的类型(多数情况是根据值或引用的区别),用它来表示结构相等或引用相等,这样做一定会让开发者感到困惑。

Kotlin已经非常接近正确了,它的===表示引用相等,==表示结构相等,尽管出于某些原因,对于值类型它会将===看做==,而不是引发编译错误。目标应该是减少开发者的困惑。它希望让开发者明白,===表示“引用相等”,而不是等号越多越好。

我不知道还有哪些允许改变变量值的语言能够用不困惑的方式处理结构相等的。但很容易想象理想状态应该怎样!准备两个运算符,一个表示结构相等,一个表示引用相当,只在编程语言可以合理地支持的语境下才允许相应的运算符。例如,如果.NET的Object.ReferenceEquals和值类型不进行包裹,并且使用类似于IEquatable<T>的东西允许成功够许愿使用结构相等运算符,那么开发者就很容易弄清楚哪个是哪个。

程序员应该怎么做?

也许你读了这篇文章后会觉得,“哇,相等好复杂!我还是不要编程了,回家种地算了。”但这篇文章如此之长的原因主要是太多的语言都做错了。都作对的确需要些心思,但并不是太难。肯定比种地要简单。

在已有的类型上进行相等比较时,先问问自己:

在这里进行相等比较本身合理吗?

如果合理,那么是应该进行结构比较,还是引用比较?

对于相应的比较方法,我采用的编程语言提供了哪些支持?

我采用的编程语言对于该比较方法的实现是正确的吗?

在设计自定义类型时也可以询问类似的问题:

我的类型应该支持相等比较吗?还是需要一个更复杂的比较,就像float那样?

我的类型应该是可改变的吗?它会对相等性产生怎样的影响?

应该支持引用比较?还是结构比较?还是应该同时支持两者?

如果你的类型是可改变的,则应该考虑将其改成不可改变的。即使语言默认是可改变的,这一点也可以实现!这样做除了能在相等性比较方面获得许多好处之外,不可改变的架构还有许多其他的好处。采用了不可改变数据结构的C# Roslyn编译器就是非常好的例子:

语法树的第三个属性是,它们是不可改变的,而且是线程安全的。这意味着,在获得一棵树之后,它就是当前代码状态的快照,而且永远不会改变。这样多个用户可以在不同的线程中与同一个语法树同时进行操作,而无需担心死锁或重复的问题。由于树是不可改变的,也不能针对树进行直接的改变,因此负责创建和修改语法树的工厂方法实际上会创建树的新快照。树本身的效率很高,因为它会重用底层结点,所以创建新版本的速度很快,只需要使用少量内存。

——.NET Compiler Platform SDK文档

原文:https://www.craigstuntz.com/posts/2020-03-09-equality-is-hard.html

☞现代编程语言大 PK,2020 年开发者关心的七大编程语言!

☞MySQL 狠甩 Oracle 稳居 Top1,私有云最受重用,大数据人才匮乏!| 中国大数据应用年度报告

☞如何用CNN玩转AlphaGo版的五子棋?

☞曾经摸鱼的程序员,如今在武汉自愿加班

☞区块链和大数据一起能否开启数据完整性的新纪元?

☞以太坊2.0、分片、DAG、链下状态通道……概述区块链可扩展性的解决方案!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至827202335@qq.com 举报,一经查实,本站将立刻删除。文章链接:https://www.eztwang.com/dongtai/147108.html

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 2023年4月18日 21:36
下一篇 2023年4月18日 21:40

相关推荐

  • 找手工活在哪个平台上找比较真实可靠(外发加工接单平台)

    关于手工活代加工你知道多少?前两天跟一个朋友聊天,他跟我聊起来这个话题,我对这方面不懂,然后就听他给我讲。 大概去年三月份时候,他在1688上面找了一个手工活代加工的,当时说的很好很好,还给他看了他们的营业执照和签订合同,想着营业执照什么都看了应该没什么事。当时他就激情澎湃了,脑子一热当时就让他们发了第一批货。 第一批货到了,是需要快递到付,付了四百多块,是…

    2024年3月25日
    1400
  • 拼多多开店要钱吗(网上开店铺需要什么流程)

    拼多多作为中国的电商平台之一,吸引了越来越多的商家入驻。本文将详细介绍在拼多多开店的流程以及所需的费用。 一、拼多多开店流程1. 注册账号首先需要在拼多多官网上注册一个账号,填写正确的手机号码,并设置密码。平台会通过短信验证码的方式验证手机号是否正确,并完成账号的注册。2. 完善店铺信息在注册账号后,需要填写店铺的基本信息,包括店铺名称、店铺LOGO、经营类…

    2024年3月24日
    900
  • 兼职拿我身份证开淘宝网店(别人拿我的身份证开网店)

    遥想当年,电商刚开始发力的阶段,身边经常有人借身份证开淘宝店铺。究其原因,主要就是平台规定一人一店,所以为了多开店铺提高成功率,“七大姨八大姑”借了个遍,甚至村里的留守老人都不放过。时至今日,还不乏这样的人存在。 再说几年前,不少之前的电商创业者成了大老板,事业飞黄腾达,开了公司,买了奔驰。虽然小日子越过越滋润,但也遇到烦心事。 “啥事呢”? “不能大声说的…

    2024年3月24日
    1400
  • 闲鱼一键转卖怎么赚钱(闲鱼的一键转卖是赚佣金吗)

    “现在去闲鱼上买东西,刷好几屏都是职业卖家,真正卖闲置物品的个人越来越少了。”有网友吐槽。 知乎、百度等平台上也充斥着闲鱼赚钱攻略:“去1688、拼多多、义乌购、微商手里找货源找文案,自己不要的东西,低于均价快速卖出刷好评,提升闲鱼账号的成交量,带动流量和活跃度,权重也会变高。” 就像闲鱼的Slogan所说的,闲鱼本身是一个“卖闲置,淘二手”的平台,因其只需…

    2024年3月24日
    2000
  • 不小心把收款码发给别人了怎么办(如何重置微信收款二维码)

    众所周知,微信付款二维码不能随便发给人。但是,收款二维码能不能随便发给别人呢,会不会存在什么风险呢?事实上,还是存在一定风险的。下面简单分析一下: 1、财务风险 我们都知道,收款码是我们向别人收钱的二维码。如果发给别人,别人扫码了,我们也只是进账资金,财务上不可能会造成损失,反而是赚了钱。但是,如果正当的钱,我们可以收。如果进账的是不正当的钱,那就会给自己带…

    2024年3月24日
    17900
  • 闲鱼到付安全吗(闲鱼卖家顺丰到付对谁有利)

    贩卖二手商品,可以直接把家中闲置物品换成真金白银,把不常用的、或者根本不用的东西变卖后,购入更加常用、更加心仪的产品。对比在各大电子平台开店售卖的方式,二手交易平台是更加合理的选择。 闲鱼平台是小编用着最好的闲置物品贩卖平台,下面我所教的基本内容也是适合个人“开店”的方法。此文为经验交流,并不是教授论文,希望各位看官摆平姿态,吸收干货。 第一,取得开门红。 …

    2024年3月24日
    900
  • 1688开店铺需要多少钱(入驻1688一年要多少钱)

    阿里巴巴国际站-重庆 阿里巴巴国际站有22年的建站历史,目前已经成为全球最大的做外贸B2B(批发)网站,主要招商对象是中国商家,买家分布在200多个海外国家和地区。国际站俗称“1688海外版/英文版”,其实国际站除了有1688相似的找批发买家流量提供之外,还提供了出口、报关退税、出口物流,还有现如今最受关注的收外汇等多项国际贸易辅助业务。 先来说说入驻费用:…

    2024年3月24日
    900
  • 抖音商城怎么开店(怎样在抖音上开店铺卖商品)

    抖音上怎么开店,目前在抖音很多用户都在推销自己的视频时候,都附带了很多商店的连接,其中的流量可想而知,对于很多刷抖音的人来说这里是最好的推销地方,那么如何在抖音上开店呢?开店铺需要什么条件?下面就跟小编一起来看看抖音开店教程步骤! 抖音开店教程步骤 1.首先你要有自己的抖音号,注册一个并且登录,在“我”这个页面右上角有三条整齐的横线“三”点开,底下有个“设置…

    2024年3月24日
    400
  • 淘宝中评对卖家的影响(淘宝中评多久显示)

    淘宝的评价系统规定只有在商家购买了商品之后才能对其进行评价,一般来说,买家购买的商品只要不和商家描述的有太大出入的话,那么买家是不会恶意给中评的,除了恶评师。店铺很可能会因为顾客的一个差评或者一个中评而对店铺的权重产生影响,从而使店铺的销量下降和声誉受损。那么一个淘宝店铺被给于中评,会对其产生什么影响?以下是关于淘宝的评价系统的介绍。 一、淘宝店被中评有啥影…

    2024年3月24日
    700
  • 女生学美甲赚钱吗(女孩子做美甲行业好吗)

    有很多人问我当美甲师一个月能挣多少钱?我告诉你挣不了多少钱。很多女孩喜欢去做美甲,美甲师看似很挣钱,不过挣的也是辛苦钱。美甲师的月收入一般有两种:一种是有底薪的,一种是底薪加提成。在一般城市的美甲师底薪不超过3000,另一种底薪不高,一般提成在20%-30%左右,是一项多劳多得的技术。 美甲师的工资还和很多因素有关: ·1.所在地消费水平不同。消费水平高的城…

    2024年3月23日
    2700
  • 速卖通是b2c还是c2c(速卖通跨境电商)

    今天,我们将探索的是“速卖通”——被誉为“国际版淘宝”的跨境电商平台! 速卖通作为阿里巴巴旗下的跨境电商平台,在中国,它是最大的跨境出口B2C平台之一。同时,速卖通也在俄罗斯、西班牙等国家排名榜首,站点覆盖超过200个国家,广受欢迎。 平台费用与平台物流 速卖通的费用模式相对灵活,只需要支付佣金,佣金范围为3%到8%,并且享有无月租费优势。收款方面,买家确认…

    2024年3月23日
    700
  • 一般什么地方招暑假工(暑假临时工招聘网)

    马上就要放暑假了,各位大学生们的暑假工作是不是找好了呢。还没有找到的小伙伴们不要着急,我们现在就来分享一下2022网上找暑假工比较靠谱的软件。看看有没有让你心仪的那一款呢?可以根据以下平台来选择,比较可靠真实: 1. BOSS直聘、58同城、赶集网、智联招聘、前程无忧51Job、拉勾招聘等平台都有海量的优质岗位,可以根据自己的需求选择合适的平台。 2. 探儿…

    2024年3月23日
    600
  • 美甲店一天能挣1000吗(开美甲店会亏钱吗)

    我是一家个人美甲店,每天能赚多少钱呢? 我是一家个人美甲店,位于谷埠街国际商城。今天的收入达到了1200元,其中包括两个指甲的美甲服务、一个美睫和一个眉毛。 ·第一位顾客是通过抖音视频找到我的,她看到我们家有特色的建构养甲项目,毫不犹豫地选择了纯色加建构的服务,价格为49.9元。 ·第二位顾客是我的老顾客,一直对我的技术非常认可。上个月她在我这里做了一个不开…

    2024年3月23日
    800
  • 开网店卖什么东西好赚钱(网店初学者适合卖什么)

    开网店卖小饰品是一种越来越受欢迎的创业方式。随着人们对个性化产品和定制化服务的需求不断增加,小饰品作为一种简单易行、价格亲民的商品形式,具有很大的市场潜力。 虽然开网店卖小饰品是一种相对容易入门的创业方式,但是赚钱并不是轻松的事情。首先,您需要有一个新颖独特的产品系列,以吸引消费者的吸意力;其次,您需要掌握一些基本的营销技巧,例如拍摄高质量的产品图片,并在社…

    2024年3月23日
    500
  • 电商怎么发货才便宜(拼多多无货源在哪里找货源)

    如今快节奏的生活环境下,人们对于生活质量的要求和物质享受的追求也是逐步的提高,单单的吃饱穿暖已经不太符合如今的生活的追求。 创业项目,副业项目,现在已经成为了年轻人们的新选择,尤其是目前互联网创业前景广阔,正适合年轻人大展拳脚。 但同样,经常有人会说十个创业九个死,虽然机会多,但竞争也更大,在潮流中倒下的创业者同样是一波接着一波。 随着拼多多的快速崛起和发展…

    2024年3月23日
    800
  • 初中学历的宝妈适合考什么证(四十多岁还能考什么证)

    初中学历可以考多种证书,以下是一些可供参考的证书类型: 会计从业资格证:初中以上学历,年满18周岁即可报名。 电工操作资格证(上岗证):年满18周岁且符合相关工种规定的年龄要求,经医院体检合格且无妨碍从事相应特种作业的疾病和生理缺陷,初中及以上学历,符合相应特种作业需要的其他条件。 计算机等级证书:考生不受年龄、职业、学历等背景的限制,均可根据自己学习情况和…

    2024年3月23日
    700
  • 什么工作可以在手机上做(手机上的兼职有哪些)

    1.网上问卷调查 网上问卷调查是一个简单的赚钱方法,只需要你花费一些时间填写一些调查问卷,就可以获得一些报酬。一些市场调研公司和在线调查平台,经常需要人们填写一些问卷来帮助他们更好地了解市场和消费者需求。你可以去一些问卷调查网站注册,填写一些问卷调查,一般每份问卷的报酬是2-5元不等,根据问卷的难度不同而有所区别。如果你愿意花费更多时间填写问卷,你可以得到更…

    2024年3月23日
    1100
  • 1688一件代发利润大概在多少(免费一件代发正规平台)

    肯定能啊!不然不赚钱为啥有这么多人去做! 但是也不是说你做了就能赚钱,就跟做生意一个道理,能不能赚钱看的是个人能力! 但是相对来说,一件代发是非常简单的了,机会也比较大,投入和产出的回报比也比较高! 至于题主说的一些费用,很多都没有必要,如果想尝试我建议的是以最小的投资来做。 先简单说说一件代发: “一件代发”顾名思义,就是你作为卖家,哪怕你只卖出一件产品,…

    2024年3月21日
    900
  • 暑假工干什么比较好(暑假工一般找什么工作)

    给你几点建议,希望能帮到你。 01 如果你去电子厂或者机械厂打工,要防止招你的人是不是中介,干多久可以离职,根据我的经验,一般厂里是干三个月才能走,如果你干两个月,到最后离开会很困难,可能到时候干了中介会不断拖你工资。 另外还有一点要注意,在一些APP上找工作,一般招聘者都是中介公司。当你面试之后,不可能马上入职。 就例如我和我同学在58同城找工作去了之后才…

    2024年3月21日
    1000
  • 品牌折扣店的货是真是假(折扣店的东西为什么便宜)

    你在网上看到那些价格很便宜的品牌折扣网站,比如唯品会,会不会想:“这么便宜,质量能保证吗?”今儿我们就讲讲,他们怎么做到比传统的零售商卖的便宜,还是真货。大概四个原因。 第一、品牌折扣平台一般卖的都是品牌的过季产品或者库存产品,品牌商需要清理库存,愿意以很低的价格把产品出掉。 第二,品牌折扣品牌所在的品类一般都是服装和家居产品,这类产品的定价策略一般都是按照…

    2024年3月21日
    700

发表回复

登录后才能评论

联系我们

18312384410

在线咨询: QQ交谈

邮件:827202335@qq.com

添加微信