范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

面试中经常被问到Java引用类型原理,带你深入剖析

  1.选择唯一性索引
  唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。例如,学生表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的信息。如果使用姓名的话,可能存在同名现象,从而降低查询速度。  2.为经常需要排序、分组和联合操作的字段建立索引
  经常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作会浪费很多时间。如果为其建立索引,可以有效地避免排序操作。  3.为常作为查询条件的字段建立索引
  如果某个字段经常用来做查询条件,那么该字段的查询速度会影响整个表的查询速度。因此,为这样的字段建立索引,可以提高整个表的查询速度。  4.限制索引的数目
  索引的数目不是越多越好。每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大。修改表时,对索引的重构和更新很麻烦。越多的索引,会使更新表变得很浪费时间。  5.尽量使用数据量少的索引
  如果索引的值很长,那么查询的速度会受到影响。例如,对一个CHAR(100)类型的字段进行全文检索需要的时间肯定要比对CHAR(10)类型的字段需要的时间要多。  6.尽量使用前缀来索引
  如果索引字段的值很长,最好使用值的前缀来索引。例如,TEXT和BLOG类型的字段,进行全文检索会很浪费时间。如果只检索字段的前面的若干个字符,这样可以提高检索速度。  7.删除不再使用或者很少使用的索引
  表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再需要。数据库管理员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响。  8.最左前缀匹配原则,非常重要的原则。
  mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a 1="" and="" b="2" c=""> 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。  9.=和in可以乱序。
  比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式  10.尽量选择区分度高的列作为索引。
  区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就 是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条 记录  11.索引列不能参与计算,保持列"干净"。
  比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本 太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’);  12.尽量的扩展索引,不要新建索引。
  比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可
  注意:选择索引的最终目的是为了使查询的速度变快。上面给出的原则是最基本的准则,但不能拘泥于上面的准则。读者要在以后的学习和工作中进行不断的实践。根据应用的实际情况进行分析和判断,选择最合适的索引方式。
  Java中一共有4种引用类型(其实还有一些其他的引用类型比如FinalReference):强引用、软引用、弱引用、虚引用。
  其中强引用就是我们经常使用的Object a = new Object(); 这样的形式,在Java中并没有对应的Reference类。
  本篇文章主要是分析软引用、弱引用、虚引用的实现,这三种引用类型都是继承于Reference这个类,主要逻辑也在Reference中。  问题
  在分析前,先抛几个问题?
  1.网上大多数文章对于软引用的介绍是:在内存不足的时候才会被回收,那内存不足是怎么定义的?什么才叫内存不足?
  2.网上大多数文章对于虚引用的介绍是:形同虚设,虚引用并不会决定对象的生命周期。主要用来跟踪对象被垃圾回收器回收的活动。真的是这样吗?
  3.虚引用在Jdk中有哪些场景下用到了呢?  Reference
  我们先看下Reference.java中的几个字段  public abstract class Reference {     //引用的对象     private T referent;             //回收队列,由使用者在Reference的构造函数中指定     volatile ReferenceQueue<? super T> queue;      //当该引用被加入到queue中的时候,该字段被设置为queue中的下一个元素,以形成链表结构     volatile Reference next;     //在GC时,JVM底层会维护一个叫DiscoveredList的链表,存放的是Reference对象,discovered字段指向的就是链表中的下一个元素,由JVM设置     transient private Reference discovered;       //进行线程同步的锁对象     static private class Lock { }     private static Lock lock = new Lock();     //等待加入queue的Reference对象,在GC时由JVM设置,会有一个java层的线程(ReferenceHandler)源源不断的从pending中提取元素加入到queue     private static Reference pending = null; }
  一个Reference对象的生命周期如下:
  主要分为Native层和Java层两个部分。
  Native层在GC时将需要被回收的Reference对象加入到DiscoveredList中(代码在referenceProcessor.cpp中process_discovered_references方法),然后将DiscoveredList的元素移动到PendingList中(代码在referenceProcessor.cpp中enqueue_discovered_ref_helper方法),PendingList的队首就是Reference类中的pending对象。
  看看Java层的代码  private static class ReferenceHandler extends Thread {          ...         public void run() {             while (true) {                 tryHandlePending(true);             }         }   }  static boolean tryHandlePending(boolean waitForNotify) {         Reference r;         Cleaner c;         try {             synchronized (lock) {                 if (pending != null) {                     r = pending;                      //如果是Cleaner对象,则记录下来,下面做特殊处理                     c = r instanceof Cleaner ? (Cleaner) r : null;                     //指向PendingList的下一个对象                     pending = r.discovered;                     r.discovered = null;                 } else {                    //如果pending为null就先等待,当有对象加入到PendingList中时,jvm会执行notify                     if (waitForNotify) {                         lock.wait();                     }                     // retry if waited                     return waitForNotify;                 }             }         }          ...          // 如果时CLeaner对象,则调用clean方法进行资源回收         if (c != null) {             c.clean();             return true;         }         //将Reference加入到ReferenceQueue,开发者可以通过从ReferenceQueue中poll元素感知到对象被回收的事件。         ReferenceQueue<? super Object> q = r.queue;         if (q != ReferenceQueue.NULL) q.enqueue(r);         return true;  }
  流程比较简单:就是源源不断的从PendingList中提取出元素,然后将其加入到ReferenceQueue中去,开发者可以通过从ReferenceQueue中poll元素感知到对象被回收的事件。
  另外需要注意的是,对于Cleaner类型(继承自虚引用)的对象会有额外的处理: 在其指向的对象被回收时,会调用clean方法,该方法主要是用来做对应的资源回收,在堆外内存DirectByteBuffer中就是用Cleaner进行堆外内存的回收,这也是虚引用在java中的典型应用。
  看完了Reference的实现,再看看几个实现类里,各自有什么不同。
  SoftReference  public class SoftReference extends Reference {      static private long clock;      private long timestamp;      public SoftReference(T referent) {         super(referent);         this.timestamp = clock;     }      public SoftReference(T referent, ReferenceQueue<? super T> q) {         super(referent, q);         this.timestamp = clock;     }      public T get() {         T o = super.get();         if (o != null && this.timestamp != clock)             this.timestamp = clock;         return o;     }  }
  软引用的实现很简单,就多了两个字段:clock和timestamp。clock是个静态变量,每次GC时都会将该字段设置成当前时间。timestamp字段则会在每次调用get方法时将其赋值为clock(如果不相等且对象没被回收)。
  那这两个字段的作用是什么呢?这和软引用在内存不够的时候才被回收,又有什么关系呢?
  这些还得看JVM的源码才行,因为决定对象是否需要被回收都是在GC中实现的。  size_t ReferenceProcessor::process_discovered_reflist(   DiscoveredList               refs_lists[],   ReferencePolicy*             policy,   bool                         clear_referent,   BoolObjectClosure*           is_alive,   OopClosure*                  keep_alive,   VoidClosure*                 complete_gc,   AbstractRefProcTaskExecutor* task_executor) {  ...    //还记得上文提到过的DiscoveredList吗?refs_lists就是DiscoveredList。    //对于DiscoveredList的处理分为几个阶段,SoftReference的处理就在第一阶段  ...       for (uint i = 0; i < _max_num_q; i++) {         process_phase1(refs_lists[i], policy,                        is_alive, keep_alive, complete_gc);       }  ... }  //该阶段的主要目的就是当内存足够时,将对应的SoftReference从refs_list中移除。 void ReferenceProcessor::process_phase1(DiscoveredList&    refs_list,                                    ReferencePolicy*   policy,                                    BoolObjectClosure* is_alive,                                    OopClosure*        keep_alive,                                    VoidClosure*       complete_gc) {    DiscoveredListIterator iter(refs_list, keep_alive, is_alive);   // Decide which softly reachable refs should be kept alive.   while (iter.has_next()) {     iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */));     //判断引用的对象是否存活     bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive();     //如果引用的对象已经不存活了,则会去调用对应的ReferencePolicy判断该对象是不时要被回收     if (referent_is_dead &&         !policy->should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) {       if (TraceReferenceGC) {         gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s"  ") by policy",                                (void *)iter.obj(), iter.obj()->klass()->internal_name());       }       // Remove Reference object from list       iter.remove();       // Make the Reference object active again       iter.make_active();       // keep the referent around       iter.make_referent_alive();       iter.move_to_next();     } else {       iter.next();     }   }  ... }
  refs_lists中存放了本次GC发现的某种引用类型(虚引用、软引用、弱引用等),而process_discovered_reflist方法的作用就是将不需要被回收的对象从refs_lists移除掉,refs_lists最后剩下的元素全是需要被回收的元素,最后会将其第一个元素赋值给上文提到过的Reference.java#pending字段。
  ReferencePolicy一共有4种实现:NeverClearPolicy,AlwaysClearPolicy,LRUCurrentHeapPolicy,LRUMaxHeapPolicy。
  其中NeverClearPolicy永远返回false,代表永远不回收SoftReference,在JVM中该类没有被使用,AlwaysClearPolicy则永远返回true,在referenceProcessor.hpp#setup方法中中可以设置policy为AlwaysClearPolicy,至于什么时候会用到AlwaysClearPolicy,大家有兴趣可以自行研究。
  LRUCurrentHeapPolicy和LRUMaxHeapPolicy的should_clear_reference方法则是完全相同:  bool LRUMaxHeapPolicy::should_clear_reference(oop p,                                              jlong timestamp_clock) {   jlong interval = timestamp_clock - java_lang_ref_SoftReference::timestamp(p);   assert(interval >= 0, "Sanity check");    // The interval will be zero if the ref was accessed since the last scavenge/gc.   if(interval <= _max_interval) {     return false;   }    return true; }
  timestamp_clock就是SoftReference的静态字段clock,java_lang_ref_SoftReference::timestamp(p)对应是字段timestamp。如果上次GC后有调用SoftReference#get,interval值为0,否则为若干次GC之间的时间差。
  _max_interval则代表了一个临界值,它的值在LRUCurrentHeapPolicy和LRUMaxHeapPolicy两种策略中有差异。  void LRUCurrentHeapPolicy::setup() {   _max_interval = (Universe::get_heap_free_at_last_gc() / M) * SoftRefLRUPolicyMSPerMB;   assert(_max_interval >= 0,"Sanity check"); }  void LRUMaxHeapPolicy::setup() {   size_t max_heap = MaxHeapSize;   max_heap -= Universe::get_heap_used_at_last_gc();   max_heap /= M;    _max_interval = max_heap * SoftRefLRUPolicyMSPerMB;   assert(_max_interval >= 0,"Sanity check"); }
  其中SoftRefLRUPolicyMSPerMB默认为1000,前者的计算方法和上次GC后可用堆大小有关,后者计算方法和(堆大小-上次gc时堆使用大小)有关。
  看到这里你就知道SoftReference到底什么时候被被回收了,它和使用的策略(默认应该是LRUCurrentHeapPolicy),堆可用大小,该SoftReference上一次调用get方法的时间都有关系。  WeakReferencepublic class WeakReference extends Reference {      public WeakReference(T referent) {         super(referent);     }      public WeakReference(T referent, ReferenceQueue<? super T> q) {         super(referent, q);     }  }
  可以看到WeakReference在Java层只是继承了Reference,没有做任何的改动。那referent字段是什么时候被置为null的呢?要搞清楚这个问题我们再看下上文提到过的process_discovered_reflist方法:  size_t ReferenceProcessor::process_discovered_reflist(   DiscoveredList               refs_lists[],   ReferencePolicy*             policy,   bool                         clear_referent,   BoolObjectClosure*           is_alive,   OopClosure*                  keep_alive,   VoidClosure*                 complete_gc,   AbstractRefProcTaskExecutor* task_executor) {  ...    //Phase 1:将所有不存活但是还不能被回收的软引用从refs_lists中移除(只有refs_lists为软引用的时候,这里policy才不为null)   if (policy != NULL) {     if (mt_processing) {       RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/);       task_executor->execute(phase1);     } else {       for (uint i = 0; i < _max_num_q; i++) {         process_phase1(refs_lists[i], policy,                        is_alive, keep_alive, complete_gc);       }     }   } else { // policy == NULL     assert(refs_lists != _discoveredSoftRefs,            "Policy must be specified for soft references.");   }    // Phase 2:   // 移除所有指向对象还存活的引用   if (mt_processing) {     RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/);     task_executor->execute(phase2);   } else {     for (uint i = 0; i < _max_num_q; i++) {       process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);     }   }    // Phase 3:   // 根据clear_referent的值决定是否将不存活对象回收   if (mt_processing) {     RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);     task_executor->execute(phase3);   } else {     for (uint i = 0; i < _max_num_q; i++) {       process_phase3(refs_lists[i], clear_referent,                      is_alive, keep_alive, complete_gc);     }   }    return total_list_count; }  void ReferenceProcessor::process_phase3(DiscoveredList&    refs_list,                                    bool               clear_referent,                                    BoolObjectClosure* is_alive,                                    OopClosure*        keep_alive,                                    VoidClosure*       complete_gc) {   ResourceMark rm;   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);   while (iter.has_next()) {     iter.update_discovered();     iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));     if (clear_referent) {       // NULL out referent pointer       //将Reference的referent字段置为null,之后会被GC回收       iter.clear_referent();     } else {       // keep the referent around       //标记引用的对象为存活,该对象在这次GC将不会被回收       iter.make_referent_alive();     }     ...   }     ... }
  不管是弱引用还是其他引用类型,将字段referent置null的操作都发生在process_phase3中,而具体行为是由clear_referent的值决定的。而clear_referent的值则和引用类型相关。  ReferenceProcessorStats ReferenceProcessor::process_discovered_references(   BoolObjectClosure*           is_alive,   OopClosure*                  keep_alive,   VoidClosure*                 complete_gc,   AbstractRefProcTaskExecutor* task_executor,   GCTimer*                     gc_timer) {   NOT_PRODUCT(verify_ok_to_handle_reflists());     ...   //process_discovered_reflist方法的第3个字段就是clear_referent   // Soft references   size_t soft_count = 0;   {     GCTraceTime tt("SoftReference", trace_time, false, gc_timer);     soft_count =       process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,                                  is_alive, keep_alive, complete_gc, task_executor);   }    update_soft_ref_master_clock();    // Weak references   size_t weak_count = 0;   {     GCTraceTime tt("WeakReference", trace_time, false, gc_timer);     weak_count =       process_discovered_reflist(_discoveredWeakRefs, NULL, true,                                  is_alive, keep_alive, complete_gc, task_executor);   }    // Final references   size_t final_count = 0;   {     GCTraceTime tt("FinalReference", trace_time, false, gc_timer);     final_count =       process_discovered_reflist(_discoveredFinalRefs, NULL, false,                                  is_alive, keep_alive, complete_gc, task_executor);   }    // Phantom references   size_t phantom_count = 0;   {     GCTraceTime tt("PhantomReference", trace_time, false, gc_timer);     phantom_count =       process_discovered_reflist(_discoveredPhantomRefs, NULL, false,                                  is_alive, keep_alive, complete_gc, task_executor);   }     ... }
  可以看到,对于Soft references和Weak references clear_referent字段传入的都是true,这也符合我们的预期:对象不可达后,引用字段就会被置为null,然后对象就会被回收(对于软引用来说,如果内存足够的话,在Phase 1,相关的引用就会从refs_list中被移除,到Phase 3时refs_list为空集合)。
  但对于Final references和 Phantom references,clear_referent字段传入的是false,也就意味着被这两种引用类型引用的对象,如果没有其他额外处理,只要Reference对象还存活,那引用的对象是不会被回收的。Final references和对象是否重写了finalize方法有关,不在本文分析范围之内,我们接下来看看Phantom references。  PhantomReferencepublic class PhantomReference extends Reference {      public T get() {         return null;     }      public PhantomReference(T referent, ReferenceQueue<? super T> q) {         super(referent, q);     }  }
  可以看到虚引用的get方法永远返回null,我们看个demo。   public static void demo() throws InterruptedException {         Object obj = new Object();         ReferenceQueue refQueue =new ReferenceQueue<>();         PhantomReference phanRef =new PhantomReference<>(obj, refQueue);          Object objg = phanRef.get();         //这里拿到的是null         System.out.println(objg);         //让obj变成垃圾         obj=null;         System.gc();         Thread.sleep(3000);         //gc后会将phanRef加入到refQueue中         Reference<? extends Object> phanRefP = refQueue.remove();          //这里输出true         System.out.println(phanRefP==phanRef);     }
  从以上代码中可以看到,虚引用能够在指向对象不可达时得到一个"通知"(其实所有继承References的类都有这个功能), 需要注意的是GC完成后,phanRef.referent依然指向之前创建Object,也就是说Object对象一直没被回收!
  而造成这一现象的原因在上一小节末尾已经说了:对于Final references和 Phantom references,clear_referent字段传入的时false,也就意味着被这两种引用类型引用的对象,如果没有其他额外处理,在GC中是不会被回收的。
  对于虚引用来说,从refQueue.remove();得到引用对象后,可以调用clear方法强行解除引用和对象之间的关系,使得对象下次可以GC时可以被回收掉。  End
  针对文章开头提出的几个问题,看完分析,我们已经能给出回答:
  1.我们经常在网上看到软引用的介绍是:在内存不足的时候才会回收,那内存不足是怎么定义的?为什么才叫内存不足?
  软引用会在内存不足时被回收,内存不足的定义和该引用对象get的时间以及当前堆可用内存大小都有关系,计算公式在上文中也已经给出。
  2.网上对于虚引用的介绍是:形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。主要用来跟踪对象被垃圾回收器回收的活动。真的是这样吗?
  严格的说,虚引用是会影响对象生命周期的,如果不做任何处理,只要虚引用不被回收,那其引用的对象永远不会被回收。所以一般来说,从ReferenceQueue中获得PhantomReference对象后,如果PhantomReference对象不会被回收的话(比如被其他GC ROOT可达的对象引用),需要调用clear方法解除PhantomReference和其引用对象的引用关系。
  3.虚引用在Jdk中有哪些场景下用到了呢?
  DirectByteBuffer中是用虚引用的子类Cleaner.java来实现堆外内存回收的,后续会写篇文章来说说堆外内存的里里外外。
  资料获取方式:关注小编+转发文章+私信【13】免费获取
  重要的事情说三遍,转发+转发+转发,一定要记得点赞转发哦!!!
二十四节气养生清明养生清明是二十四节气中的第5个节气,此时气清景明,万物皆显,故名清明。清明分为三候初候桐始华二候田鼠化为鴽三候虹始见,意即在这个时节先是白桐树开花,接着喜阴的田鼠不见了,田野中可以见到长津湖之水门桥美军的火力有多猛?在长津湖里面,有这么一个桥段,不知道细心的观众有没有注意到呢?就是在电影里面,美军兴致冲冲在介绍自己的武器装备,什么轻机枪重机枪反坦克火箭筒等等,可以说,美军的这一波介绍可谓是富到奔驰率先涨价,豪华车迎来全面涨价潮?面对造车原材料价格的不断上涨,传统豪华品牌也难逃涨价命运。在见证了过去的一个月内接连不断的新能源品牌涨价潮后,强如梅赛德斯奔驰也扛不住了。作为国内豪华品牌的标杆,同时也是国内市场传RedmiNote12被曝搭载联发科处理器,高配版或是天机8000?由于红米Note11系列发布至今已经有一段时间,所以也快到了红米Note12系列发布的时候。而来自站哥的最新爆料显示红米Note12系列将在今年4月或者5月登场,同时站哥除了爆料红它是鸡肉的克星,炖鸡肉时放一点,鸡肉口感鲜嫩,不腥不柴它是鸡肉的克星,炖鸡肉时放一点,鸡肉口感鲜嫩,不腥不柴。亲爱的好朋友们,大家好,我是大厨江一舟,今天又到了,给大家分享美食的时刻了,你们准备好了吗?鸡肉很多朋友都喜欢吃,我江一舟本正式签约!顶级内线加盟中国篮坛豪门全力冲击总冠军连续两个赛季无缘总冠军,让四川女篮的高层有些着急,也有些压力,毕竟在转会市场她们已经引进了邵婷韩旭李梦等名将,也被称为中国篮坛的豪门球队。据了解为了完成冲击总冠军的目标,四川女篮依篮下88命中率!莱多这一技能突破砍165,胡明轩透露赢球真因广东宏远顺利晋级四分之一决赛,以联赛第5的身份对阵联赛第12的天津男篮,本就没有太大压力。这对广东宏远来说也不算什么坏事,可以帮助球队尽快熟悉季后赛的节奏,尽快进入到季后赛模式中。有种走红毯叫撒狗粮,罗晋唐嫣甜蜜对视,王子文出场空气都变甜了有种走红毯叫撒狗粮,罗晋唐嫣甜蜜对视,王子文出场空气都变甜了。其实和朋友在一起,最不希望的就是朋友和自己的爱人一起出现,这样的感觉真的是让人有点受不了,毕竟在整个过程中要是单身的朋宝可梦阿尔宙斯全精灵展示宝可梦阿尔宙斯到目前为止有242只精灵,今天菜头把所有精灵列举出来大家看看自己还有哪个精灵没有获得吧。其中一些稀有宠物后面括号是获取方式捕捉地点喔。NO。001。木木枭(博士领取,手游每日榜单(2022年4月3日)每日更新游戏榜单和新鲜资讯,关注我不迷路。关注我的都棒棒哒!今天是2022年4月3日,首先来看看今天的畅销榜单变化今天具体的榜单如下网易哈利波特魔法觉醒今天畅销榜排名第10。这是一王者CP台词你听过几个记得我第一次玩接触王者这个游戏是在2016年,初三的暑假。下面王者情侣的对话台词你听过几个呢?皱眉得意紫霞and至尊宝紫霞现身吧,早就知道你有问题至尊宝因为你看起来像女人,我才不伤
午评沪指跌0。21创业板指跌1。2,旅游酒店农牧饲渔等板块逆市走强金融界12月13日消息今日A股三大指数开盘涨跌不一,开盘后沪指呈现窄幅震荡态势,深成指创业板指逐步走弱,其中后者跌幅超过1,另外科创50指数亦跌逾1。截至午间收盘,沪指跌0。21,四川广安产村相融乡村美如画12月12日,拍摄的四川省广安市广安区花桥镇竹林村道路四通八达产业欣欣向荣民居焕然一新,呈现出乡村振兴的生机盎然画卷。无人机拍摄今年4月,四川省广安市广安区花桥镇探索农旅融合新路投西藏文化及特色产品体验馆落户德州12月12日,鲁藏携手经贸行西藏文化及特色产品体验馆项目战略合作签约仪式举行。日喀则市委副书记常务副市长山东省政府副秘书长山东省第十批援藏干部领队陈耕,山东省商务厅党组成员副厅长一遵义绥阳生态旅游资源宣传走进卡塔尔首都多哈绥阳旅游宣传视频在卡塔尔首都多哈TawarMall购物中心大屏播放。绥阳融媒供图中新网贵州新闻12月12日电(记者瞿宏伦)记者12日从中共绥阳县委宣传部获悉,在2022卡塔尔世界杯这三年这三年,有你,有我,有疫情,季节还是那个季节,春天的百花不逊色秋天的月亮天上挂,夏天的凉风四面吹,冬天大雪小雪又一年。这三年,每一天每一月每一年,你我为了碎银几两,掸着阳尘去,踏着你幸福吗大家好,我是小志,今天想问大家一个问题你幸福吗?幸福,到底是什么?有人说幸福是比较级,需要有东西垫底才容易感受到。我饿了,看别人手里拿个肉包子,那他就比我幸福我冷了,看别人穿一件厚苹果AirPods充电盒即便满电在iPhone上电量仍显示为0苹果于12月13日推出了iOS16。2更新,引入了iCloud端到端加密功能高级数据保护AppleMusic唱歌无边记应用等。不过用户在更新至iOS16。2之后遇到了一个BUGAiiOS16。2两大爆款新功能,这回安卓是真没有!苹果iOS16。2正式版发布苹果刚推出了全新的iOS16。2与iPadOS16。2正式版,不同于之前版本的修修补补,这回16。2版本带来了两个全新的功能无边记AppleMusic唱CNN中英双语新闻用户实时发布马斯克航班定位马斯克亲自封禁TwittersuspendsaccountthattrackedMusksprivatejetTwitteronWednesdaypermanentlysuspendedanac小米13纯体验向点评有望成为继小米6之后下一代钉子户机型文小伊评科技最近一段时间小米13得热度一直非常高,很多小伙伴也在后台想要笔者分享一下关于小米13这款机型得真实体验如何,有没有什么特别需要注意的地方。那么本文就结合自己在实际上手过阳了吃什么好得快?过来人的经验,助您抗阳之路一臂之力这几天我发现上班时大家都相互躲着,尽管都带了口罩,但是每隔几分钟就有同事拿出酒精来喷。甚至曾经很多人都喜欢的茶水间也很少有人去了,到了下班的点大家一溜烟就不见了,比兔子跑的还快。大