PM memilih untuk pengaturan yang terlalu rumit yang tidak seorang pun memiliki pengalaman dengan [ditutup]


51

Baru-baru ini saya memulai sebuah proyek yang sepertinya tidak terlalu sulit untuk dibuat, konsepnya adalah aplikasi yang cukup sederhana yang harus menerima input setiap sekarang (mungkin 10x sehari), dan mencoba untuk melakukan beberapa operasi pada mereka dan mengumpulkan semua hasil pada akhirnya. Aplikasi ini kemudian akan mendapatkan portal web front-end yang dapat digunakan pelanggan untuk melihat hasilnya, bukan ilmu roket.

Untuk ini saya awalnya memanfaatkan pustaka concurrency bawaan Python ( ThreadPoolExecutor) dan menggunakan pustaka yang mudah digunakan untuk front-end (saya memilih Flask karena mudah untuk pemula dan relatif mudah untuk memelihara dan menguji).


Setelah kami setengah dari proyek, PM menyatakan kami harus menggunakan kemampuan antrian pesan pihak ketiga daripada utas dan harus menerapkan load balancing, yang akhirnya terjadi adalah bahwa kami akhirnya mulai bekerja dengan Celery, Redis, RabbitMQ, Nginx, uWSGI dan sekelompok layanan pihak ketiga besar lainnya yang tidak ada yang punya pengalaman nyata dengannya.

Pada akhirnya ini mengarah pada sekelompok kode spaghetti, tugas-tugas yang tidak dapat diuji (karena kompleksitas perpustakaan pihak ketiga, menambal kode itu bahkan tidak berfungsi) dan banyak sakit kepala karena tidak ada yang tahu apa nilai tambah dari layanan ini. .


Sebelum Anda mengatakan "Ya, Anda harus menggunakan layanan itu", perlu diingat bahwa tidak ada yang tahu bagaimana menggunakan ini atau bahkan tahu apa yang mereka lakukan selain memperkenalkan kode terganggu kondisi ras.

Apa yang harus saya lakukan? Pada titik ini, akan terlalu mahal untuk kembali ke apa yang kita miliki dan PM sudah mati untuk menggunakan layanan ini, meskipun produk akhir sekarang lebih buruk daripada di awal. Apakah ada gunanya mendiskusikan hal ini dengannya? Apakah saya meminta lebih banyak waktu? Atau jawaban yang kasar, apakah saya terlalu bodoh untuk pekerjaan saya?


12
Masalah apa yang dipecahkan concurrency untuk Anda? Siapa yang akan menggunakan sistem ini? Nilai bisnis apa yang dicapai? Apakah ada masalah skalabilitas yang signifikan yang perlu ditangani? Sebagai pengembang, Anda harus menjadi PM mengapa alat dan lib ini diperlukan. Maka Anda mungkin mulai memahami bagaimana alat ini akan membantu jika sama sekali.
RibaldEddie

7
Anda bekerja dengan PM yang tidak produktif. Anda bisa tinggal atau pergi. Mungkin kekonyolan yang sama akan terjadi dengan proyek lain di bawah PM yang sama.
Frank Hileman

80
Mengapa seorang PM membuat keputusan teknis ?! Itu bau proyek nyata jika aku memang menciumnya.
RubberDuck

13
Ini seperti membelikan seorang anak gergaji dan menekan mereka untuk pergi keluar dan menemukan pohon untuk ditebang sehingga itu tidak membuang-buang uang.
JeffO

28
Sepertinya proyek ini membutuhkan pemimpin teknis yang kuat yang tidak takut untuk tertawa histeris pada manajer proyek yang berpura-pura menjadi arsitek solusi. Anda benar-benar hanya harus menganggukkan kepala setuju, dan kemudian membangun solusi yang masuk akal pula. Ya. Ini tidak akan terbang denganku.
Greg Burghardt

Jawaban:


89

Setelah kami setengah proyek, PM menyatakan kami harus menggunakan kemampuan antrian pesan pihak ketiga bukan utas dan harus menerapkan load balancing

Ini bukan hal yang tepat bagi seorang PM untuk "menyatakan" secara sepihak. Dua alasan:

  1. Keputusan desain harus dibuat oleh sumber daya teknis dan hanya sebagai respons terhadap NFR . Jadi, tanyakan dengan sopan kepada PM Anda apakah ada NFR baru dan jika Anda bisa mendapatkan detailnya.

  2. Jika NFR sedang diperkenalkan di tengah proyek, itu mungkin harus dilakukan melalui kontrol perubahan . Kontrol perubahan sangat penting dari perspektif tata kelola; itu tidak hanya akan menjadi input untuk kebutuhan Anda, tetapi juga merupakan input penting untuk kasus uji QA, penyebaran operasi dan buku pegangan dukungan, dan (di sini adalah bagian yang sangat penting) jadwal PM . Jika persyaratan baru memperkenalkan lebih banyak pekerjaan, tim pengembangan seharusnya memiliki kesempatan untuk mengkomunikasikan perkiraan pembangunan baru, dan PM harus memutuskan apakah mereka dapat hidup dengan tanggal yang baru, menambah lebih banyak sumber daya, atau mendorong kembali pemangku kepentingan yang memperkenalkan NFR.

Sekarang jika benar-benar ada NFR yang bonafid, dan tidak ada cara untuk mengelaknya, mungkin juga tepat untuk meminta sumber daya baru atau berbeda yang memiliki pengetahuan dengan teknologi yang sedang diperkenalkan, atau meminta anggaran pelatihan untuk sebagian dari Anda yang sudah ada sumber daya. Jadi ada aspek biaya juga.

Jika Anda berbicara bahasa PM - jadwal dan biaya - saya pikir Anda akan mendapatkan lebih banyak daya tarik daripada berbicara tentang bagaimana perasaan pengembang tentang desain yang dihasilkan. Hal-hal itu berdampak nyata.

Seorang PM harus tahu lebih baik daripada memperkenalkan hal-hal seperti ini dengan cepat tanpa pemerintahan, tanpa kontrol, dan tanpa konsensus. Jika mereka tidak mendapatkannya, Anda mungkin perlu meningkatkan ke manajemen produk atau manajemen program, karena ia menempatkan kualitas dan jadwal pada risiko yang tidak perlu.


21
Ok, ini jawabannya. Seorang manajer proyek tidak boleh membuat keputusan semacam ini. Uang? Waktu? Manajemen proyek menangani ini. RabbitMQ? Tidak mungkin.
Greg Burghardt

Saya suka jawaban ini banyak. Ada kontrol di tempat untuk memastikan Anda tidak hanya memiliki neraka hanya jatuh pada Anda. Duduklah bersamanya dan bicarakan hal itu.
Rhys Johns

3
Namun, satu hal adalah bahwa kadang-kadang saat itu menyebalkan, Anda mungkin hanya perlu belajar teknologi atau perpustakaan baru. Apakah ini akan memakan waktu, ya, tapi mungkin hanya sepadan.
Rhys Johns

5
Sebagai manajer proyek, saya sangat setuju dengan jawaban ini.
James McLeod

13
Dalam organisasi yang lebih kecil, "Manajer Proyek" seringkali adalah bos. Mereka mungkin memiliki telinga pemilik \ CEO, dan mungkin secara efektif menjadi Pengembang atau Arsitek Pimpinan Teknis atau kombinasi fasik. Dalam hal ini cakupan dari pengiriman mereka tidak jelas.
Kereta luncur

31

Apa yang bodoh adalah membiarkan diri Anda mati .

Apa yang Anda gambarkan adalah bahwa Anda telah kehilangan perasaan kritis. Tidak ada rasa kontrol dan tidak ada cara yang jelas untuk kembali ke sana.

Hal terakhir yang harus Anda lakukan adalah bekerja keras, menundukkan kepala, dan diam-diam menderita sampai mereka akhirnya mengakui bahwa proyek ini akan berakhir.

Yang harus Anda lakukan adalah berpikir sangat keras tentang apa yang berhak Anda harapkan.

Jika mereka ingin Anda menggunakan teknologi yang tidak Anda pahami, Anda harus mengharapkan waktu untuk mempelajarinya. Jangan malu dengan apa yang tidak Anda ketahui. Gunakan ketidaktahuan Anda sebagai gada. Ketika mereka menuntut Anda menggunakan sesuatu, tanyakan mengapa. Jangan terima 'karena'. Jangan terima 'praktik terbaik modern'. Jangan menerima 'skala kemampuan' tanpa mendapatkan harapan yang nyata, dapat diuji,.

Maksud saya maksudnya mereka HARUS memberi tahu Anda berapa banyak permintaan per hari / jam / menit yang mereka inginkan dapat dilakukan. Jelaskan bahwa Anda bermaksud membangun sesuatu untuk menjalankan sistem ini sesuai dengan spesifikasi tersebut.

Dengan cara ini Anda dapat menggunakan percobaan gratis 30 hari untuk membuktikan bahwa hal terbaik yang mereka inginkan layak atau jika Anda lebih baik tetap berpegang pada apa yang sudah Anda ketahui.

Sekarang perlu diingat. Itu bukan alat yang memperkenalkan kode kondisi ras. Kalian melakukan itu. Anda perlu belajar BAGAIMANA Anda melakukan itu sehingga Anda dapat membatalkannya.

Dan tidak. Tidak terlalu mahal untuk kembali ke apa yang Anda miliki. PM tidak dapat memiliki apa yang mereka inginkan hanya dengan menuntutnya. Anda harus mendorong kembali hingga Anda dapat secara efektif menggunakan apa yang diinginkan PM atau membuktikannya bukan apa yang dibutuhkan proyek.

Serius, menyerah pada ini tidak profesional dan mematikan bagi proyek.

Saya pernah ke sini. Lebih dari sekali. Itu memang membuat Anda merasa bodoh. Benar-benar bukan itu. Anda baru saja tersesat.

Bicaralah dengan PM. Secara jujur. Letakkan semuanya. Tunjukkan bahwa Anda bersedia untuk belajar tetapi tidak ingin dibawa naik. Tidak pernah desain atau kode berdasarkan iman. Buat PM menunjukkan kepada Anda bagaimana melakukan apa yang mereka inginkan. Jangan pura-pura mengerti saat Anda tidak. Jangan katakan itu akan dilakukan ketika tidak mau. Jika Anda akan percaya pada sesuatu, percayalah pada diri sendiri. Anda harus bersedia untuk mengatakan TIDAK.

Jika itu tidak berhasil memoles resume karena Anda akan membutuhkannya segera. Dengan satu atau lain cara.


7
Now keep in mind. It isn't the tools that introduced race-condition plagued code. You guys did that. You need to learn HOW you did that so you can undo that.Ya, bagian ini sangat menonjol pada saya. Apakah itu seledri atau benang, segala jenis konkurensi dapat memperkenalkan kondisi balapan. Masalah yang sama mungkin ada di kode berbasis thread.
Izkata

10

Ini harus benar-benar di workplace.stackexchange.com, karena masalahnya bukan pertanyaan pengembangan perangkat lunak, tetapi tentang hubungan kerja.

Jika Anda yakin bahwa pendekatan sederhana Anda akan berhasil dan menghasilkan hasil kerja agak cepat, maka PM Anda adalah kekuatan destruktif di perusahaan Anda yang harus dihapus. Cari tahu bagaimana cara menyampaikan berita ke tingkat di atasnya: Bahwa tim Anda memiliki solusi yang sederhana dan berfungsi yang telah membuat kemajuan yang baik, dan untuk alasan yang tidak ada yang dapat menjelaskan PM Anda memaksa Anda untuk mencoba solusi yang jauh lebih kompleks, menggunakan banyak alat yang tidak ada yang tahu, tidak ada yang mengerti, tidak ada yang tahu apakah itu berguna sama sekali, dan bahwa keputusan PM Anda yang tidak terduga menyebabkan Anda semua kesulitan dan menyebabkan proyek menjadi terlambat dan tidak berfungsi.


1

Tidak mengetahui konteks dan strategi produk yang dikejar oleh manajemen Anda, sulit untuk menjawab pertanyaan Anda secara objektif.

Berikut beberapa argumen obyektif. Namun mungkin itu bukan yang Anda harapkan:

  • " Perlu diingat bahwa belum ada yang tahu cara menggunakan produk ini ".
  • Hanya menggunakan alat dan teknik yang dikenal sempurna akan memastikan produktivitas tinggi. Tetapi itu akan sangat membatasi kemampuan untuk berinovasi. Di beberapa pasar, ini bisa berakibat fatal bagi produk Anda. Sebagai contoh, hampir 30 tahun yang lalu, saya mengusulkan untuk menggunakan windows 3.0 untuk mengembangkan versi baru dari produk CAD yang berhasil di bawah MS-DOS. Manajer produk keberatan bahwa ini bukan lingkungan yang terbukti, bahwa itu akan terlalu kompleks dan terlalu sulit untuk dipelajari bagi tim, dan lagi pula, bahwa " Windows tidak akan pernah menjadi lingkungan utama " ... Saya membiarkan Anda menebak keberhasilan produknya 2 tahun kemudian.
  • Ini semua masalah biaya dan manfaat. Biaya bereksperimen vs manfaat skalabilitas dan penerapan yang dipastikan oleh pihak ketiga yang berpengalaman dengan instalasi besar dan beban kerja yang berat.
  • Kelemahan dari menambahkan teknologi baru dapat diperhalus, dengan pelatihan yang sesuai, atau dukungan / pelatihan awal oleh konsultan yang berpengalaman.

Pada akhirnya, pilihan ekonomi adalah tanggung jawab manajer produk Anda. Diskusikan dengan dia pro dan kontra, untuk memastikan bahwa dia membuat keputusan dengan informasi lengkap dan tidak meremehkan kompleksitas yang ditambahkan. Dan jika dia tetap di jalurnya, cobalah untuk mencapai yang terbaik: Anda tidak akan kehilangan apa pun dan dalam kasus terburuk, Anda akan memiliki teknologi baru di CV Anda.


1

Ada dua pendekatan untuk perpustakaan pihak ketiga (dan komponen lainnya):

  1. Gunakan sebanyak mungkin dari mereka
  2. Gunakan sesedikit mungkin dari mereka

Pendekatan saya adalah (2). Kedengarannya seperti pendekatan Anda juga (2), tetapi manajer proyek menyukai pendekatan tersebut (1).

Ada tiga cara Anda dapat menangani situasi ini. Entah Anda membiarkan PM melakukan apa pun yang diinginkan PM, Anda mencoba meyakinkan PM untuk mengubah pendekatan ke perpustakaan pihak ketiga, atau Anda memilih dengan kaki Anda dan memilih pekerjaan lain.

Jika Anda ingin meyakinkan PM untuk mengubah pendekatan, pertimbangkan argumen ini:

  • Waktunya belajar. Setiap perpustakaan eksternal memerlukan waktu untuk belajar, di mana waktu seorang programmer yang kompeten dapat menulis fungsionalitas yang diinginkan terutama jika perpustakaan besar dipilih hanya untuk melakukan hal yang sangat sederhana yang dapat dilakukan dalam beberapa ratus baris kode.
  • Dapat diganti.Jika Anda memiliki perpustakaan eksternal, bagaimana Anda memastikan bahwa jika pengembangannya dihentikan, Anda dapat menggantinya dengan perpustakaan lain yang serupa? Solusi saya adalah menghindari pustaka eksternal kapan pun saya bisa, dan kapan pun itu tidak memungkinkan, saya menulis pembungkus sederhana untuk abstrak bagian dari antarmuka pemrograman yang saya inginkan. Biasanya antarmuka yang saya inginkan jauh lebih sederhana daripada antarmuka yang ditawarkan perpustakaan. Kemudian kode saya mengakses perpustakaan eksternal hanya melalui bungkus ini, membuat penggantian menjadi mudah. Membangun seluruh aplikasi Anda pada beberapa kerangka kerja adalah hal yang tidak boleh. Servlets? Ya, mereka telah berada di sini untuk waktu yang lama dan terus berada di sini untuk masa yang akan datang. Mesin templat? Ya, meskipun mereka tidak sepenuhnya tergantikan (Anda biasanya memilih satu dan tetap dengan itu), nilai yang mereka bawa sangat besar, jadi pilih dengan hati-hati - dan perlu diingat bahwa ketika mengganti mesin template, Anda dapat memiliki dua mesin template dalam aplikasi yang sama tetapi Anda tidak dapat memiliki dua kerangka kerja dalam aplikasi yang sama biasanya. Apache Struts? Tidak, kerangka kerja menjadi mode dan keluar dari mode dengan cepat, dan Anda biasanya tidak dapat memiliki dua kerangka kerja dalam aplikasi yang sama.
  • Versi neraka. Dengan memilih perpustakaan eksternal, Anda harus memperbaruinya untuk menghindari kerentanan keamanan, dan memutakhirkannya dapat merusak banyak hal. Komponen yang dirancang dengan baik (seperti Java JRE) kompatibel dengan versi yang berbeda, tetapi pengalaman saya adalah bahwa sebagian besar perpustakaan adalah omong kosong karena memaksakan neraka versi besar. Selain itu, komponen X mungkin memerlukan Z versi 1 dan komponen Y mungkin memerlukan Z versi 2, dan Anda mungkin tidak dapat menghubungkan Z versi 1 dan Z versi 2 dalam aplikasi yang sama.
  • Kerentanan keamanan. Dengan memilih perpustakaan eksternal, jumlah kerentanan keamanan yang mudah dieksploitasi terhadap aplikasi Anda meningkat. Beberapa dapat mengklaim bahwa kode yang dikembangkan sendiri menyerupai keamanan melalui ketidakjelasan, tetapi sekali lagi saya akan mengatakan itu masih merupakan bentuk keamanan.
  • Masalah lisensi. Setiap perpustakaan eksternal memberlakukan lisensi sendiri pada bagian-bagian dari program Anda. Sebagai contoh, pustaka GPL tidak dapat digunakan dalam program non-GPL, dan pustaka LGPL juga memerlukan distribusi kode sumber bersama dengan binari, yang mungkin membutuhkan banyak bandwidth.
  • Waktu startup aplikasi. Setiap perpustakaan eksternal besar memperlambat waktu startup aplikasi Anda. Dengan menulis perpustakaan sederhana dan ramping di rumah, Anda dapat membuat waktu startup aplikasi Anda lebih cepat.
  • Jejak memori. Dengan memiliki X yang membutuhkan Y yang membutuhkan Z yang membutuhkan A yang membutuhkan B, Anda membutuhkan X + Y + Z + A + B dalam memori pada saat yang bersamaan. Dengan menerapkan hanya yang setara dengan X, sebut saja X ', in-house, Anda hanya perlu X' dalam memori. Dan biasanya jejak memori X 'kurang dari jejak memori X.
  • Risiko bug. Semakin banyak baris yang ada di komponen eksternal, semakin tinggi risiko Anda akan mengalami bug yang akan sulit diperbaiki karena banyaknya kode yang perlu Anda pahami. Jika Anda melakukan hal itu sendiri, Anda biasanya melakukannya dengan lebih sedikit baris kode (untuk melakukan apa yang Anda butuhkan, tidak ada yang lain), dan dengan demikian, risiko bug lebih kecil.
  • Kemampuan penyesuaian. Jika saya menulis SQL queries sendiri, saya tahu seperti apa query tersebut dan seberapa baik performanya pada mesin database yang diberikan dan diberikan serangkaian indeks. Jika, di sisi lain, kueri SQL ditulis oleh komponen eksternal, saya tidak tahu apa-apa tentang kinerjanya. Saya dulu bekerja di perusahaan tempat setiap halaman web mengambil beberapa detik untuk mengambilnya. Saya menduga penyebabnya adalah perpustakaan Hibernate yang mereka gunakan mengambil terlalu banyak data secara otomatis dari database ketika yang Anda butuhkan adalah satu item dan tidak semua item yang terkait dengan item tertentu ini. Saya meninggalkan perusahaan sebelum menemukan penyebab kelambatan sebenarnya, karena saya tidak suka pendekatan menggunakan sejumlah besar perpustakaan yang ada.

Waspadalah terutama jika perpustakaan menyebut dirinya kerangka kerja . Ini berarti perpustakaan mengharuskan Anda untuk membangun seluruh aplikasi Anda sendiri. Anda biasanya tidak dapat memiliki dua kerangka kerja dalam aplikasi yang sama; mereka akan bertarung satu sama lain tanpa hidup berdampingan secara damai. Pustaka utilitas pengembangan web? Ya tolong, ada terlalu sedikit. Jika saya pernah menemukan perpustakaan yang lebih baik daripada yang saya gunakan sekarang, saya dapat menggunakan perpustakaan yang baru ditemukan dalam kode baru sambil terus menggunakan perpustakaan lama dalam kode lama. Kerangka pengembangan web? Bunyi klakson besar TIDAK!


0

Saya pikir PM Anda mengincar sistem yang sulit dikelola yang akan menghasilkan banyak pekerjaan pemeliharaan saat masih hidup, sehingga akan memastikan penghasilan Anda.

Secara pribadi, Anda tampaknya terjebak dengan python, lupakan saja python untuk sementara waktu, jangan kode dalam python selama setahun, pelajari hal-hal baru, Anda akan melihat ada bahasa lain yang dapat melakukan hal yang sama, dan mungkin lebih baik.

Seperti yang telah dinyatakan orang lain, pelajari alat-alatnya sebelum Anda mulai membuat kode dengannya. Mungkin menyarankan bahwa akan lebih baik untuk mengevaluasi tumpukan yang diperlukan bersama-sama, berdasarkan penelitian alat yang berbeda yang tampaknya cocok untuk tugas tersebut. Atau mungkin bertanya bagaimana dia membuat daftar itu, dia bisa mendapat bantuan dari seseorang yang mutakhir.


-2

Pengembang tidak boleh takut belajar menggunakan perpustakaan baru, kerangka kerja, teknologi, dll. Itu adalah bagian inti dari deskripsi pekerjaan pengembang, dan sangat masuk akal bagi seseorang untuk menyarankan bahwa tim bekerja dengan hal-hal pihak ketiga yang tidak ada yang memiliki pengalaman dengan, atau bahkan untuk menuntut tim melakukannya jika mereka berada dalam posisi untuk membuat keputusan teknis yang berwibawa bagi tim.

Namun, tidak masuk akal untuk berharap bahwa Anda bisa menarik teknologi baru (apalagi beberapa teknologi baru sekaligus) ke dalam tumpukan Anda dan terus membuat kemajuan. Waktu yang signifikan seharusnya telah dijadwalkan untuk mempelajari seluk beluk pendekatan baru dan mencari tahu desain yang baik untuk menggabungkan potongan-potongan baru, di mana tidak ada kemajuan nyata pada produk yang sebenarnya akan diharapkan (dari orang-orang yang melakukan pekerjaan pembelajaran / desain ini , yang mungkin atau mungkin tidak seluruh tim, meskipun jika tidak ada mungkin perlu lebih banyak waktu yang dijadwalkan untuk orang-orang yang belajar untuk mentransfer pengetahuan ke seluruh tim). Itulah biaya untuk membuat perubahan besar semacam ini. Mempelajari teknologi baru adalah bagian dari pekerjaan pengembang, tetapi itu bukan sesuatu yang terjadi begitu saja dengan biaya nol waktu.

Sepertinya itu tidak terjadi dari pertanyaan. Orang-orang terjun tepat dalam mencoba membuat implementasi yang baik di atas teknologi yang mereka sendiri tidak mengerti. Tentu saja kode yang dihasilkan sangat buruk.

Cobalah untuk meyakinkan PM Anda bahwa perusahaan akan perlu menghabiskan lebih banyak waktu di ini. Entah itu akan datang dalam bentuk berhenti sekarang, belajar dan menilai teknologi baru, mencari tahu desain yang baik dan membersihkan kekacauan implementasi saat ini. Atau itu akan datang dalam bentuk lebih banyak waktu yang terbuang untuk bug, perawatan, pengembangan yang lebih mahal, dll.

Tidak mungkin untuk mengatakan apakah pilihan teknis yang dijelaskan dalam pertanyaan (load balancing, antrian pesan, dll) sebenarnya sesuai. Saya tidak berpikir bahwa "tidak seorang pun di tim memiliki pengalaman bekerja dengan ini sebelumnya" adalah alasan yang baik untuk benar-benar mengesampingkan keputusan, tetapi hal itu meningkatkan biaya jangka pendek untuk membuat keputusan itu (yang dapat mengubah " keputusan terbaik untuk konteks), dan jika PM Anda tidak mempertimbangkan itu dan mengharapkan tim untuk segera menjadi sama produktifnya dengan orang-orang yang berpengalaman maka Anda harus mendorong kembali dengan alasan itu; mereka akan menetapkan jadwal proyek yang sangat tidak realistis, yang tidak menguntungkan siapa pun.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.