讨论gta5出现一个问题题

评论该主题
作者:您目前是匿名发表 &
作者:,欢迎留言
提示:用户在社区发表的所有资料、言论等仅代表个人观点,与本网站立场无关,不对您构成任何投资建议。用户应基于自己的独立判断,自行决定证券投资并承担相应风险。讨论一个问题?_百度知道
讨论一个问题?
证明灵魂和鬼神的不存在。2.证明灵魂和鬼神的存在1
我有更好的答案
对于“灵魂”的传说由来已久,一直是人们争论的话题之一。相信“灵魂”存在的人认为:人的“灵魂”和人的肉体是组成人生命的两个缺一不可的部份,即使人的肉体死亡了,其“灵魂”依然存在。各种正统宗教信仰都相信有“灵魂”的存在。例如,基督教认为,信基督的人的“灵魂”在人死后可以进入天堂,而不信基督的人则要下地狱。佛教认为,人的肉体死亡之后,“灵魂”要转生,即六道轮回,转生成什么取决于其在世间的所作所为,善有善报,恶有恶报。
不相信“灵魂”存在的人认为:“灵魂”是人们出于对死亡的恐惧而想象出来的东西,人肉体死亡了,那么这个生命就结束了,他的思维停止,一切都过去了。他们的理由是,“灵魂”看不见、摸不着,连最先进的现代科学仪器也探测不到它的存在。还有一种观点认为,人类...
`1以风水师的观点`2以科学家的观点!回答完毕
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁HotSpot VM Serial GC的一个问题 - 讨论 - 高级语言虚拟机 - ITeye群组
& 上一页 1
看了一段时间的HotSpot GC代码,一直有一个问题,就是新生代上的对象收集:栈上引用的对象最终似乎都是通过FastScanClosure::do_oop(oop* p)方法移动并修改栈上指针指向移动后新位置的,但这个方法中仅仅移动了被p直接引用的对象,那么被p间接引用的对象呢,它们是如果被移动的,相应的指向它们的指针又是如何修改的。注意到putfiled方法在实现过程中调用了do_oop_store,其中会将CardTable置dirty。不知两者之间有关系吗?
好,多谢开帖!欢迎以后也多来参与讨论。
普及一下背景知识。楼主问的是HotSpot VM中的Serial GC,特别是其中的minor GC的实现细节。Minor GC只收集young generation,而使用Serial GC时这个young generation的实现类叫做DefNewGeneration。
关于这些DefNew啊ParNew啊啥的名字的历史,可以参考我之前写的一帖:
FastScanClosure只在DefNewGeneration的收集中有用到。
HotSpot VM里有很多以*-Closure方式命名的类。它们其实是封装起来的回调函数。为了让GC的具体逻辑与对象内部遍历字段的逻辑能松耦合,这部分都是通过回调函数来连接到一起的。ScanClosure与FastScanClosure都可用于DefNewGeneration的扫描。
顺带一提,之前在HLLVM群组发表过一篇,说的正好就是Serial GC的minor GC,值得配合本文一读。
===============================================
然后从基本入手。HotSpot VM Serial GC的minor GC使用的是的变种,所以先理解基本的Cheney算法有助理清头绪。
说啥都没代码直观,先上代码:星期天陪老婆去理发的时候有空闲写了个Cheney算法的伪代码:
这个伪代码采用近似C++的语法,其实稍微改改就能实际运行。
这个算法的原始论文是C. J. Cheney在1970年发表的:
该算法在,例如在《》第44页,第4章4.1小节、《》第4章4.4小节。每个版本的算法描述都稍微不同,我的伪代码也跟这两本书写的方式稍微不同,但背后要表达的核心思想是一样的就OK了。
Tracing GC的核心操作之一就是从给定的根集合出发去遍历对象图。对象图是一种有向图,该图的节点是对象,边是引用。遍历它有两种典型顺序:深度优先()和广度优先()。
广度优先遍历的典型实现思路是三色遍历:给对象赋予白、灰、黑三种颜色以标记其遍历状态:
* 白色:未遍历到的对象
* 灰色:已遍历到但还未处理完的对象(意味着该对象尚有未遍历到的出边)
* 黑色:已遍历完的对象
从Wikipedia引用一张动画图来演示三色遍历:
遍历过程:
1. 一开始,所有对象都是白色的;
2. 把根集合能直接碰到的对象标记为灰色。在只有一个根对象的地方就只要把那个对象标记为灰色。但GC通常不是只有一个特定根对象,而是有一个集合的引用作为根,这些引用能直接碰到的对象都要标记为灰色。
3. 然后逐个扫描灰色对象的出边,把这些边能直接碰到的对象标记为灰色。每当一个对象的所有出边都扫描完了,就把这个对象标记为黑色。
4. 重复第3步直到不再有灰色对象,遍历结束。
这黑白灰要怎么跟实际实现联系起来呢?基本算法会使用一个队列(queue)与一个集合(set):
void breadth_first_search(Node* root_node) {
// 记录灰色对象的队列
Queue&Node*&
// 记录黑色对象的集合
Set&Node*&
// 1. 一开始对象都是白色的
// 2. 把根对象标记为灰色
scanned.add(root_node);
scanning.enqueue(root_node);
// 3. 逐个扫描灰色对象的出边直到没有灰色对象
while (!scanning.is_empty()) {
Node* parent = scanning.dequeue();
for (Node* child : parent-&child_nodes() { // 扫描灰色对象的出边
// 如果出边指向的对象还没有被扫描过
if (child != nullptr && !scanned.contains(child)) {
scanned.add(child);
// 记录下它已经被扫描到了
scanning.enqueue(child); // 也把该对象放进灰色队列里等待扫描
}
在这种伪代码中,队列scanning与集合scanned组合起来记录了对象的颜色:
* 所有没进入过scanning队列的对象是白色的;
* 进入了scanning队列与scanned集合,但还没离开scanning队列的对象是灰色的;
* 离开了scanning队列并且在scanned集合里的对象是黑色的。
假如对象内可以记录遍历状态的话,那算法可以变为只用一个队列:
void breadth_first_search(Node* root_node) {
// 记录灰色对象的队列
Queue&Node*&
// 1. 一开始对象都是白色的
// 2. 把根对象标记为灰色
root_node-&set_marked();
scanning.enqueue(root_node);
// 3. 逐个扫描灰色对象的出边直到没有灰色对象
while (!scanning.is_empty()) {
Node* parent = scanning.dequeue();
for (Node* child : parent-&child_nodes() { // 扫描灰色对象的出边
// 如果出边指向的对象还没有被扫描过
if (child != nullptr && !child-&is_marked()) {
child-&set_marked();
// 记录下它已经被扫描到了
scanning.enqueue(child); // 也把该对象放进灰色队列里等待扫描
上面两个版本是有且只有一个特殊对象作为根对象的有向图的广度优先遍历。假如不是这样而是有一个集合的引用作为根的话,算法会变为:
void breadth_first_search(Graph* graph) {
// 记录灰色对象的队列
Queue&Node*&
// 1. 一开始对象都是白色的
// 2. 把根集合的引用能碰到的对象标记为灰色
// 由于根集合的引用有可能有重复,所以这里也必须
// 在把对象加入队列前先检查它是否已经被扫描到了
for (Node* node : graph-&root_edges()) {
// 如果出边指向的对象还没有被扫描过
if (node != nullptr && !node-&is_marked()) {
node-&set_marked();
// 记录下它已经被扫描到了
scanning.enqueue(child); // 也把该对象放进灰色队列里等待扫描
// 3. 逐个扫描灰色对象的出边直到没有灰色对象
while (!scanning.is_empty()) {
Node* parent = scanning.dequeue();
for (Node* child : parent-&child_nodes() { // 扫描灰色对象的出边
// 如果出边指向的对象还没有被扫描过
if (child != nullptr && !child-&is_marked()) {
child-&set_marked();
// 把它记录到黑色集合里
scanning.enqueue(child); // 也把该对象放进灰色队列里等待扫描
有没有觉得这算法的样子跟GC越来越像了?
Cheney算法正如上面说的一样,用一个队列来实现对象图的遍历。比较完整的伪代码可以参考我发这节开头给的链接,其中核心的部分抽取出来如下:
void garbage_collect(Heap* heap) {
Semispace* to_space = heap-&to_space();
// 记录灰色对象的队列:从scanned到to_space-&top()
address scanned = to_space-&bottom();
// 1. 一开始对象都是白色的
// 2. 把根集合的引用能碰到的对象标记为灰色
// 由于根集合的引用有可能有重复,所以这里也必须
// 在把对象加入队列前先检查它是否已经被扫描到了
for (Object** refLoc : heap-&root_reference_locations()) {
Object* obj = *refL
if (obj != nullptr) {
if (!obj-&is_forwarded()) {
// 记录下它已经被扫描到了,也把该对象放进灰色队列里等待扫描
size_t size = obj-&size();
address new_addr = to_space-&allocate(size);
// address Semispace::allocate(size_t size) {
if (_top + size & _end) {
address new_addr = _
return new_
// to_space-&allocate()移动了to_space-&top()指针,
// 等同于scanning.enqueue(obj);
copy(/* to */ new_addr, /* from */ obj, size);
Object* new_obj = (Object*) new_
obj-&forward_to(new_obj);
// 设置转发指针(forwarding pointer)
*refLoc = new_
// 修正指针指向新对象
*refLoc = obj-&forwardee(); // 修正指针指向新对象
// 3. 逐个扫描灰色对象的出边直到没有灰色对象
while (scanned & to_space-&top()) {
Object* parent = (Object*)
// 扫描灰色对象的出边
for (Object** fieldLoc : parent-&object_fields()) {
Object* obj = *fieldL
// 如果出边指向的对象还没有被扫描过
if (obj != nullptr) {
if (!obj-&is_forwarded()) {
// 尚未被扫描过的对象
// 记录下它已经被扫描到了,也把该对象放进灰色队列里等待扫描
size_t size = obj-&size();
address new_addr = to_space-&allocate(size);
// to_space-&allocate()移动了to_space-&top()指针,
// 等同于scanning.enqueue(obj);
copy(/* to */ new_addr, /* from */ obj, size);
Object* new_obj = (Object*) new_
obj-&forward_to(new_obj);
// 设置转发指针(forwarding pointer)
*fieldLoc = new_
// 修正指针指向新对象
// 已经扫描过的对象
*fieldLoc = obj-&forwardee(); // 修正指针指向新对象
scanned += parent-&size();
// 移动scanned指针等同于scanning.dequeue(parent);
}
它的设计非常精妙:
1. 它使用一块连续的地址空间来实现GC堆,并将其划分为2个半分空间(semispace),分别称为from-space与to-space。平时只用其中一个,也就是from-space;
2. 逐个扫描指针,每扫描到一个对象的时候就把它从from-space拷贝到to-space,并在原来的对象里记录下一个转发指针(forwarding pointer),记住该对象被拷贝到哪里了。要知道一个对象有没有被扫描(标记)过,只要看该对象是否有转发指针即可;
3. 每扫描完一个指针就顺便把该指针修正为指向拷贝后的新对象。这样,对象的标记(mark)、整理(compaction)、指针的修正就合起来在一步都做好了;
4. 它不需要显式为扫描队列分配空间,而是复用了to-space的一部分用作隐式队列。用一个scanned指针来区分to-space的对象的颜色:在to-space开头到scanned指针之间的对象是黑色的,在scanned指针到to-space已分配对象的区域的末尾之间的对象是灰色的。如何知道还有没有灰色对象呢?只要scanned追上了to-space已分配对象区域的末尾就好了。
这种做法也叫做“两手指”(two-finger):“scanned”与“free”。只需要这两个指针就能维护隐式扫描队列。“free”在我的伪代码里就是to_space-&top()。
Cheney算法GC工作时,to-space中各指针的样子如下:
|[ 已分配并且已扫描完的对象 ]|[ 已分配但未扫描完的对象 ]|[ 未分配空间 ]|
在GC结束时,不需要对原本的from-space做什么清理动作,只要把它的分配指针(top)设回到初始位置(bottom)即可。之前在里面的对象就当作不存在了。自然,也就不需要清理其中设置了的转发指针。
要想看图解Cheney算法的工作过程的,请参考这个幻灯片:
我现在懒得画图…这个幻灯片已经画得足够好了,直接看它吧。
(不过它所图解的过程跟我的伪代码有一点点细微的差异,别介意…)
后面的回复LeafInWind问道:
LeafInWind 写道不知理解是否有误,感觉while的条件应该是*scanned==null。
while的条件就是scanned & to_space-&top()。或者说条件是scanned != to_space-&top()也行。反正就是:如果scanned还没追上to_space-&top(),继续循环。
scanned是一个指针,*scanned是一个Object实体。只有指针可以等于null,对象实体就是一个实在的东西,不可能是“null”。
--------------------------------------------------------------
Cheney算法是一个非常非常简单且高效的GC算法。看前面我写的伪代码就可以有直观的感受它有多简单。它的实现代码恐怕比简易mark-sweep还简单。
但为啥很多简易的VM宁可采用mark-sweep而不用Cheney算法的copying GC呢?
因为mark-sweep GC的常规实现不移动对象,而copying GC必须移动对象。移动对象意味着使用GC的程序(术语叫做mutator)需要做更多事情,例如说要能准确定位到所有的指针,以便在对象移动之后修正指针。很多简易VM都偷懒不想记住所有指针的位置,所以无法支持copying GC。
关于找指针的问题,我之前也写过一点:
有一种叫做Bartlett风格的mostly-copying GC可以弱化定位指针的需求:根集合之中不需要准确定位指针,只要保守的扫描;在GC堆内的对象则必须要能准确定位其中的指针。有兴趣的可以参考其原始论文:
--------------------------------------------------------------
Cheney算法的简单优雅之处来自它通过隐式队列来实现广度优先遍历,但它的缺点之一却也在此:广度优先的拷贝顺序使得GC后对象的空间局部性(memory locality)变差了。但是如果要改为真的深度优先顺序就会需要一个栈,无论是隐式(通常意味着递归调用)或者是显式。
使用递归实现的隐患是容易爆栈,有没有啥办法模拟深度优先的拷贝顺序但不用栈呢?这方面有很多研究。其中一种有趣的做法是IBM的hierarchical copying GC,参考:
===============================================
相比基本的Cheney算法,HotSpot VM Serial GC有什么异同呢?
相同点:
1. 使用广度优先遍历;
2. 使用隐式队列;
3. copy等同mark + relocate (compact) + remap (pointer fixup)三件事一步完成。
在HotSpot VM里,copying GC用了scavenge这个名字,说的是完全相同的事。
相异点:
1. 基本Cheney算法不分代,而HotSpot的GC分两代
2. 基本Cheney算法使用2个半分空间(semispace),而HotSpot的GC在young generation使用3个空间——1个eden与两个survivor space。注意这两个survivor space就与semispace的作用类似。
在G1 GC之前,所有HotSpot VM的GC堆布局都继承自1984年David Ungar在Berkeley Smalltalk里所实现的Generation Scavenging。参考论文:
GC堆布局:
那我们一点点把基本的Cheney算法映射过来。
* 基本Cheney算法用from-space和to-space,而HotSpot VM的DefNewGeneration有三个空间,eden space、from-space、to-space。后者的eden space + from-space大致等于前者的from-space,而后者的to-space + old gen的一部分大致等于前者的to-space。
* 拷贝对象的目标空间不一定是to-space,也有可能是old generation,也就是对象有可能会从young generation晋升到old generation。
为了实现这一功能,对象头的mark word里有一小块地方记录对象的年龄(age),也就是该对象经历了多少次minor GC。如果扫描到一个对象,并且其年龄大于某个阈值(tenuring threshold),则该对象会被拷贝到old generation;如果年龄不大于那个阈值则拷贝到to-space。
要留意的是,基本Cheney算法中2个半分空间通常一样大,所以可以保证所有from-space里活着的对象都能在to-space里找到位置。但HotSpot VM的from-space与to-space通常比eden space小得多,不一定能容纳下所有活的对象。如果一次minor GC的过程中,to-space已经装满之后还遇到活对象要拷贝,则剩下的对象都得晋升到old generation去。这种现象叫做过早晋升(premature tenuring),要尽量避免。
* 既然拷贝去的目标空间不一定是to-space,那原本Cheney算法里的隐式扫描队列会在哪里?
答案是既在to-space,也在old generation。很简单,在这两个空间都记录它们的scanned指针(叫做“saved mark”),这俩空间各自原本也记录着它们的分配指针(“top”),之间的部分就用作扫描队列。
* Forwarding pointer安装在对象(oopDesc)头部的mark word(markOop)里。只有在minor GC的时候才会把已拷贝的对象的mark word借用来放转发指针。
* 通过回调,把遍历逻辑与实际动作分离。例如说,遍历根集合的逻辑封装在GenCollectedHeap::gen_process_strong_roots()、SharedHeap::process_strong_roots()里,遍历对象里的引用类型字段的逻辑封装在oopDesc::oop_iterate()系的函数里;而实际拷贝对象的动作则由FastScanClosure::do_work()负责调用。
* 基本Cheney算法的“scanned”指针,在HotSpot Serial GC里是每个space的“saved mark”。相关操作的函数名是:“save_marks()” / “set_saved_mark()”、“reset_saved_mark()”、“no_allocs_since_save_marks()” / “saved_mark_at_top()”
看看遍历循环的结束条件(循环条件的反条件):
bool saved_mark_at_top() const { return saved_mark_word() == top(); }
跟基本Cheney算法的循环条件 scanned != top() 一样。
为啥我的伪代码里scanned是个局部变量,而HotSpot里变成了每个空间的成员字段?因为使用回调函数来分离遍历逻辑与实际动作,代码结构变了,这个scanned指针也只好另找地方放来让需要访问它的地方都能访问到。
* HotSpot VM的分代式GC需要通过写屏障(write barrier)来维护一个记忆集合(remember set)——记录从old generation到young generation的跨代引用的数据结构。具体在代码中叫做CardTable。在minor GC时,old generation被remember set所记录下的区域会被看作根集合的一部分。而在minor GC过程中,每当有对象晋升到old generation都有可能产生新的跨代引用。
所以FastScanClosure::do_work()里也有调用写屏障的逻辑:OopsInGenClosure::do_barrier()。
* HotSpot VM要支持Java的弱引用。在GC的时候有些特殊处理要做。可以参考这帖:
* HotSpot VM的GC必须处理一些特殊情况,一个极端的例子是to-space和old generation的剩余空间加起来都无法容纳eden与from-space的活对象,导致GC无法完成。这使得许多地方代码看起来很复杂。但要了解主要工作流程的话可以先不关心这些旁支逻辑。
--------------------------------------------------------------
HotSpot代码与我的伪代码的几个对应关系:
HotSpot =& 我的Cheney算法伪代码
* saved mark =& scanned
* FastScanClosure =& process_reference()
* GenCollectedHeap::gen_process_strong_roots()、SharedHeap::process_strong_roots() =& 遍历根集合的循环逻辑
* FastEvacuateFollowersClosure =& 遍历扫描队列的循环
* oopDesc::oop_iterate() =& 遍历对象的引用类型字段的循环,Object::object_fields()
* DefNewGeneration::copy_to_survivor_space() =& 拷贝对象的逻辑,Heap::evacuate()
其它应该都挺直观的?
===============================================
Oracle Labs的Maxine VM里也有过Cheney算法的实现,在这里:
也可以参考来看看。纯Java实现的GC喔。
===============================================
顺带一提,早期V8的分代式GC中的minor GC也是基于Cheney算法,而且更接近原始的基本算法——只用2个半分空间。最大的区别就是由于是分代式GC的一部分,它也跟HotSpot一样要处理对象晋升和写屏障。
Jay Conrod:(中文翻译:)
就先写这么多了?
R神何时继续
LeafInWind 写道R神何时继续
马上马上。家里有点事结果没来得及把字码好。楼主先看这个,我待会儿码字说明它是什么:
看了伪代码,觉得最精妙的地方就在下面这段to-space中的宽度优先scan
// breadth-first scanning of object graph
while (scanned & _to_space-&top()) {
Object* parent_obj = (Object*)
foreach (Object** slot in parent_obj-&obejct_fields()) {
process_reference(slot);
scanned += parent_obj-&size();
由于对象是被顺序依次移动到to-space的,因此上述宽度优先的scan过程能保证所有间接引用都被扫描到移动到。上述过程实质是一个队列的填充过程。
不知理解是否有误,感觉while的条件应该是*scanned==null。
另外仍然有两个问题:
1。上述scan过程对应的hotspot代码是什么?
2。parent_obj-&object_fields()在hotspot中有对应的直接实现吗?
其实被stack上root引用的对象从from区移动到to区的过程也蛮精妙的:先移走,然后修改原对象的mark指向新位置,这样如果下次遇到一个root也指向该对象,就再不需要移动而可以直接修改root的指向了。
更新了我前面的回复。楼主看看?
感谢R神精彩的讲解
LeafInWind 写道感谢R神精彩的讲解
有疑问的话欢迎继续提
引用
后面的回复LeafInWind问道:
LeafInWind 写道
不知理解是否有误,感觉while的条件应该是*scanned==null。
while的条件就是scanned & to_space-&top()。或者说条件是scanned != to_space-&top()也行。反正就是:如果scanned还没追上to_space-&top(),继续循环。
scanned是一个指针,*scanned是一个Object实体。只有指针可以等于null,对象实体就是一个实在的东西,不可能是“null”。
R神的代码没有问题,是我对top的理解有误,top其实是随着对象的分配在不断的递减的,我把它当做end了。另外本意是想说*scanned!=null,并且这里只是将null当做一个空间未被分配的标记,当然设这个标记还需要对空间初始化什么的,不好,所以还是R神的条件好。
& 上一页 1输入关键字进行搜索
讨论一个电商问题:1、整体而言,目前是pc电商转化率高、还是移动电商转化率高?2、细分来说:pc淘宝与手机淘宝,pc京东与京东无线(pc之B2C与手机B2C),微信京东入口京东无线、微信小店及各种微信电商pk微信朋友圈,目前哪个转化率高?(请有实践过的电商人来回答,不要臆想)
不考虑平台与类目去讨论pc或手机端的转化是没有意义的,尤其是产品品类。
一般来说,标品现在手机端流量大涨,选择简单快捷,手机端应该特别重视,流量和转化都不错;
而女装类似这样个性化的非标品,用户更愿意深涉了解,仔细分析图片、尺寸、风格后再下单,当然pc端更重要!
但不考虑以上因素,但说转化率,手机端的特点就是快速决策、快速下单,转化率当然更高,各平台的数据已经证明了这点。数据的东西,无需讨论!
前两天在亿邦动力网上看到一则消息,想与各位来分享下,在京东上市后首份财报公布后的分析师电话会议上,移动端业务成为高密度提问区,而京东高管也花了很长时间解答京东移动端(尤其是微信端)的发展现状。
京东本季度的财报显示,京东商城移动端订单数占了总订单数量的24%。据亿邦动力网了解,京东移动端目前主要包括“App+微信+手Q”三大业务块。京东商城CEO沈皓瑜介绍了京东在微信入口几个维度的现状:
1、微信入口用户转化率低于京东App。沈皓瑜表示,由于手Q购物入口刚刚开通不久,谈转化率还为时尚早。不过据他估计,手Q转化率同样会低于京东App。
2、微信和手Q入口的订单均价低于京东App,而京东App的订单均价又略低于PC端。
3、微信入口的订单大部分通过微信支付完成。另外,京东CFO黄宣德透露,京东接下来还将在PC端提供微信支付和京东自己的支付解决方案。
4、微信和手Q的重要价值在于覆盖新用户。沈皓瑜表示,上述两个渠道能帮助京东覆盖新用户和较低线城市的消费者,也是推出新产品的良好渠道。而黄宣德则表示,京东Q2的活跃用户数相比Q1增加了700万,这其中有微信和手Q的功劳。
对于目前并不竟如人意的微信端转化率,黄宣德分析,通信应用(指微信和手Q)的用户通常是即兴、冲动性的消费,而在移动应用和PC端用户,访问时本来已经有着明确的购买意图,所以会有更好的转化率。
刘强东则表示,自开通以来,京东微信入口的转化率和每个独立用户数的价值都在提升。“不过,关于在社交软件上的购物并没有很好的先例,我们与腾讯正在进行合作,不断提升转化率。无论微信还是移动QQ都是一个金矿,当前的开发尚未达到最好的状态,还有很大的潜力继续挖掘。”
(来源:亿邦动力网)
个人感觉还是看什么行业,商品类电商,移动端会超越PC端。某些高端服务,PC端还是教育阶段,移动端还需要点时间。
我感觉二楼是来负责搞笑的。
个人从消费者角度来谈谈PC 移动的区别吧
整体来讲,PC目前有绝对优势,很多消费者看似是移动付的钱,但大多是PC选择后后才进入移动的流程。也就是说PC有移动不可替代的优势。a 大屏幕 b 交流方便 c 信息核对方便
移动只有支付方便、无聊的时间会使用。但是真正上下班时段购物的有多少呢?拥有挨拍得和平板并使用流畅的有几人呢?
至少5年内看不到移动的绝对优势。
有人危言耸听地说移动会替代PC,个人感觉是不太可能的。就像馒头和大米,谁替代谁呢?
就算市场的人群不同,但是购物者的行为还是有共性的。你50 60
70 80 90 00后 买衣服绝对是要穿的 ,不太可能这几代人行为不同地买件衣服有穿 的有吃的 有喝的。当然衣服以后可能会有吃穿喝的功能,但是目前来看是不必的。
其它如游戏币等虚拟的效果,或许会在移动端体验的更容易便利。但是生活中的购物虚拟产品的消费个人感觉比例还是比较小的,最大的头可能是移动充值了,几个运营商加起来有服装行业消费多吗?有化妆品贡献大吗?能赶上餐饮行业的几成?
所以PC有不可替代的地位,移动只是补充做些小修小补的事情,不会是电子购物的主要载体。什么行业都来拼移动端注定拼的只是信心和PC的血泪。
要回复问题请先
问答二维码(手机扫描分享)
浏览: 1344
关注: 5 人}

我要回帖

更多关于 lol遇到一个网络问题 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信