Other Flashcards

1
Q

Cors

A

Cross origin resource sharing

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. CORS also relies on a mechanism by which browsers make a “preflight” request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. In that preflight, the browser sends headers that indicate the HTTP method and headers that will be used in the actual request.

An example of a cross-origin request: the front-end JavaScript code served from https://domain-a.com uses XMLHttpRequest to make a request for https://domain-b.com/data.json.

For security reasons, browsers restrict cross-origin HTTP requests initiated from scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy. This means that a web application using those APIs can only request resources from the same origin the application was loaded from unless the response from other origins includes the right CORS headers.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What is SOLID

A
Single Responsibility Principal
Open Closed Principal
Liskov Substitution Principal
Interface Segregation Principal
Dependency Inversion Principal
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

CQRS

A

CQRS stands for Command and Query Responsibility Segregation.

Apattern that separates read and update operations for a data store. Implementing CQRS in your application can maximize its performance, scalability, and security.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What is Agile

A

Agile is an iterative approach to project management and software development that helps teams deliver value to their customers faster and with fewer headaches. Instead of betting everything on a “big bang” launch, an agile team delivers work in small, but consumable, increments. Requirements, plans, and results are evaluated continuously so teams have a natural mechanism for responding to change quickly.

Whereas the traditional “waterfall” approach has one discipline contribute to the project, then “throw it over the wall” to the next contributor, agile calls for collaborative cross-functional teams. Open communication, collaboration, adaptation, and trust amongst team members are at the heart of agile. Although the project lead or product owner typically prioritizes the work to be delivered, the team takes the lead on deciding how the work will get done, self-organizing around granular tasks and assignments.

Agile isn’t defined by a set of ceremonies or specific development techniques. Rather, agile is a group of methodologies that demonstrate a commitment to tight feedback cycles and continuous improvement.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Cloud native

A

The term cloud native refers to the concept of building and running applications to take advantage of the distributed computing offered by the cloud delivery model. Cloud native apps are designed and built to exploit the scale, elasticity, resiliency, and flexibility the cloud provides.

As defined by the Cloud Native Computing Foundation (CNCF), Cloud native technologies empower organizations to build and run scalable applications in public, private, and hybrid clouds. Features such as containers, service meshes, microservices, immutable infrastructure, and declarative application programming interfaces (APIs) best illustrate this approach.

These features enable loosely coupled systems that are resilient, manageable, and observable. They allow engineers to make high-impact changes frequently and with minimal effort.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Benefits of cloud native

A

Benefits of a cloud native application

Cloud native applications—or native cloud applications (NCAs)—are programs designed for a cloud computing architecture. They have many benefits.

Independence: Their architecture makes it possible to build cloud native applications independently of each other. This means you also can manage and deploy them individually.
Resiliency: A well-designed cloud native application is able to survive and stay online even in the event of an infrastructure outage.
Standards-based: For interoperability and workload portability, cloud native services are often based on open source and standards based technology. This helps reduce vendor lock-in and results in increased portability.
Business agility: Cloud native applications enable flexible deployment options across the network, and are also smaller than traditional apps, which makes them easier to develop, deploy, and iterate.
Automation: Cloud native applications use DevOps automations features and enable continuous delivery and deployment of software changes that get released on a regular basis. Additionally, developers can use methodologies like blue-green and canary deployments to make improvements to the apps without any disruption to the user experience.
No downtime: Thanks to container orchestrators such as Kubernetes, you can deploy a software update with essentially zero downtime.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Cloud native - server less functions

A

Functions

The term serverless functions describes an architecture style that focuses on increasing developers’ productivity. A serverless application lets you write code on a platform that functions as a service (FaaS) using event-driven architectures and various backend-as-a-service (BaaS) models. This eliminates the need to worry about provisioning, patching, scaling, security, high availability, and so forth. With FaaS platforms, such as Oracle Functions, applications are broken up into small pieces of code (nanoservices), which are dynamically scheduled and run on demand when triggered by an event. The advantage of this approach is that code is called and executed only when needed, and you pay only for the resources used during the execution duration. This differs from a classic server approach, in which applications are loaded into a server and spend most of their time idle, waiting for requests. Thus, in serverless computing, you pay only for computing resources you actually use, rather than paying for idle resources.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Programming Paradigm

A

A programming paradigm can be termed as an approach or a style of writing code. Most of the modern programming languages fall into two general paradigms: imperative (procedural, OOP etc.) and declarative(functional etc.).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Declarative vs imperative examples

A

Popular examples of declarative languages are database query languages such as SQL, markup languages like HTML and CSS, and in functional and logic programming languages.

Popular examples of imperative languages are Java,C++ and C#

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

DRY principal

A

Don’t repeat yourself

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Git Bisect

A

The idea behind git bisect is to perform a binary search in the history to find a particular regression. Imagine that you have the following development history:

… — 0 — 1 — 2 — 3 — 4* — 5 — current
You know that your program is not working properly at the current revision, and that it was working at the revision 0. So the regression was likely introduced in one of the commits 1, 2, 3, 4, 5, current.

You could try to check out each commit, build it, check if the regression is present or not. If there is a large number of commits, this can take a long time. This is a linear search. We can do better by doing a binary search. This is what the git bisect command does. At each step it tries to reduce the number of revisions that are potentially bad by half.

You’ll use the command like this:

$ git stash save
$ git bisect start
$ git bisect bad
$ git bisect good 0
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[< … sha … >] 3
After this command, git will checkout a commit. In our case, it’ll be commit 3. You need to build your program, and check whether or not the regression is present. You’ll also need to tell git the status of this revision with either git bisect bad if the regression is present, or git bisect good if it is not.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Binary Search Algorithm

A

Binary Search is a searching algorithm used in a sorted array by repeatedly dividing the search interval in half. The idea of binary search is to use the information that the array is sorted and reduce the time complexity to O(Log n).

The basic steps to perform Binary Search are:

Begin with an interval covering the whole array.
If the value of the search key is less than the item in the middle of the interval, narrow the interval to the lower half.
Otherwise, narrow it to the upper half.
Repeatedly check until the value is found or the interval is empty.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

REST

A

A REST API (also known as RESTful API) is an application programming interface (API or web API) that conforms to the constraints of REST architectural style and allows for interaction with RESTful web services. REST stands for representational state transfer and was created by computer scientist Roy Fielding.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

SOA

A

SOA, or service-oriented architecture, defines a way to make software components reusable via service interfaces. These interfaces utilize common communication standards in such a way that they can be rapidly incorporated into new applications without having to perform deep integration each time.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

SOA vs Microservice

A

SOA vs. microservices
Experts have filled a few thousand of print and digital pages comparing SOA and microservices and defining the subtleties of their relationship to one another. For the purposes of this article, the chief differences between the two are the coupling of components and scope of use:

SOA is an enterprise-wide concept. It enables existing applications to be exposed over loosely-coupled interfaces, each corresponding to a business function, that enables applications in one part of an extended enterprise to reuse functionality in other applications.
Microservices architecture is an application-scoped concept. It enables the internals of a single application to be broken up into small pieces that can be independently changed, scaled, and administered. It does not define how applications talk to one another—for that we are back to the enterprise scope of the service interfaces provided by SOA.
Microservices architecture emerged and gained steam with the rises of virtualization, cloud computing, Agile development practices, and DevOps. Most of the advantages of microservices in these contexts arise from the complete decoupling of the components, which simplifies and improves the following:

Developer agility and productivity: Microservices enable developers to incorporate new technologies to one part of the application without catching up the rest of the application. Any component can be modified, tested, and deployed independently of the others, which speeds iteration cycles.
Scalability: Microservices can take maximum advantage of cloud scalability—any component can be scaled independently of the others for the fastest possible response to workload demands and the most efficient use of computing resources.
Resilience: Again, thanks to decoupling, the failure of one microservice does not impact the others. And each microservice can perform to its own availability requirements without staking the other components or the entire application to greatest common availability requirements.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

SDLC (Sofware Development Life Cycle) Phases

A
  1. Planning
  2. Define Requirements
  3. Design and Prototyping
  4. Software Development
  5. Testing
  6. Deployment
  7. Operations and Maintenance
17
Q

SDLC Phases

A
  1. Planning
    In the Planning phase, project leaders evaluate the terms of the project. This includes calculating labor and material costs, creating a timetable with target goals, and creating the project’s teams and leadership structure.

Planning can also include feedback from stakeholders. Stakeholders are anyone who stands to benefit from the application. Try to get feedback from potential customers, developers, subject matter experts, and sales reps.

Planning should clearly define the scope and purpose of the application. It plots the course and provisions the team to effectively create the software. It also sets boundaries to help keep the project from expanding or shifting from its original purpose.

  1. Define Requirements
    Defining requirements is considered part of planning to determine what the application is supposed to do and its requirements. For example, a social media application would require the ability to connect with a friend. An inventory program might require a search feature.

Requirements also include defining the resources needed to build the project. For example, a team might develop software to control a custom manufacturing machine. The machine is a requirement in the process.

  1. Design and Prototyping
    The Design phase models the way a software application will work. Some aspects of the design include:

Architecture – Specifies programming language, industry practices, overall design, and use of any templates or boilerplate
User Interface – Defines the ways customers interact with the software, and how the software responds to input
Platforms – Defines the platforms on which the software will run, such as Apple, Android, Windows version, Linux, or even gaming consoles
Programming – Not just the programming language, but including methods of solving problems and performing tasks in the application
Communications – Defines the methods that the application can communicate with other assets, such as a central server or other instances of the application
Security – Defines the measures taken to secure the application, and may include SSL traffic encryption, password protection, and secure storage of user credentials

Prototyping can be a part of the Design phase. A prototype is like one of the early versions of software in the Iterative software development model. It demonstrates a basic idea of how the application looks and works. This “hands-on” design can be shown to stakeholders. Use feedback o improve the application. It’s less expensive to change the Prototype phase than to rewrite code to make a change in the Development phase.

  1. Software Development
    This is the actual writing of the program. A small project might be written by a single developer, while a large project might be broken up and worked by several teams. Use an Access Control or Source Code Management application in this phase. These systems help developers track changes to the code. They also help ensure compatibility between different team projects and to make sure target goals are being met.

The coding process includes many other tasks. Many developers need to brush up on skills or work as a team. Finding and fixing errors and glitches is critical. Tasks often hold up the development process, such as waiting for test results or compiling code so an application can run. SDLC can anticipate these delays so that developers can be tasked with other duties.

Software developers appreciate instructions and explanations. Documentation can be a formal process, including wiring a user guide for the application. It can also be informal, like comments in the source code that explain why a developer used a certain procedure. Even companies that strive to create software that’s easy and intuitive benefit from the documentation.

Documentation can be a quick guided tour of the application’s basic features that display on the first launch. It can be video tutorials for complex tasks. Written documentation like user guides, troubleshooting guides, and FAQ’s help users solve problems or technical questions.

  1. Testing
    It’s critical to test an application before making it available to users. Much of the testing can be automated, like security testing. Other testing can only be done in a specific environment – consider creating a simulated production environment for complex deployments. Testing should ensure that each function works correctly. Different parts of the application should also be tested to work seamlessly together—performance test, to reduce any hangs or lags in processing. The testing phase helps reduce the number of bugs and glitches that users encounter. This leads to a higher user satisfaction and a better usage rate.
  2. Deployment
    In the deployment phase, the application is made available to users. Many companies prefer to automate the deployment phase. This can be as simple as a payment portal and download link on the company website. It could also be downloading an application on a smartphone.

Deployment can also be complex. Upgrading a company-wide database to a newly-developed application is one example. Because there are several other systems used by the database, integrating the upgrade can take more time and effort.

  1. Operations and Maintenance
    At this point, the development cycle is almost finished. The application is done and being used in the field. The Operation and Maintenance phase is still important, though. In this phase, users discover bugs that weren’t found during testing. These errors need to be resolved, which can spawn new development cycles.

In addition to bug fixes, models like Iterative development plan additional features in future releases. For each new release, a new Development Cycle can be launched.

18
Q

SDLC Models and Methodologies

A

Waterfall
The Waterfall SDLC model is the classic method of development. As each phase completes, the project spills over into the next step. This is a tried-and-tested model, and it works. One advantage of the Waterfall model is each phase can be evaluated for continuity and feasibility before moving on. It’s limited in speed, however, since one phase must finish before another can begin.

Agile
The AGILE model was designed by developers to put customer needs first. This method focuses strongly on user experience and input. This solves much of the problems of older applications that were arcane and cumbersome to use. Plus, it makes the software highly responsive to customer feedback. Agile seeks to release software cycles quickly, to respond to a changing market. This requires a strong team with excellent communication. It can also lead to a project going off-track by relying too heavily on customer feedback.

Iterative
In the Iterative development model, developers create an initial basic version of the software quickly. Then they review and improve on the application in small steps (or iterations). This approach is most often used in very large applications. It can get an application up and functional quickly to meet a business need. However, this process can exceed its scope quickly and risks using unplanned resources.

DevOps
The DevOps security model incorporates operations – the people who use the software – into the development cycle. Like Agile, this seeks to improve the usability and relevance of applications. One significant advantage of this model is the feedback from actual software users on the design and implementation steps. One drawback is that it requires active collaboration and communication. Those additional costs can be offset by automating parts of the development process.

19
Q

What is the difference between git pull and git fetch

A

In the simplest terms, git pull does a git fetch followed by a git merge.

When you use pull, Git tries to automatically do your work for you. It is context sensitive, so Git will merge any pulled commits into the branch you are currently working in. pull automatically merges the commits without letting you review them first. If you don’t closely manage your branches, you may run into frequent conflicts.

When you fetch, Git gathers any commits from the target branch that do not exist in your current branch and stores them in your local repository. However, it does not merge them with your current branch. This is particularly useful if you need to keep your repository up to date, but are working on something that might break if you update your files. To integrate the commits into your master branch, you use merge.

20
Q

Could you explain the Gitflow workflow

A

Gitflow workflow employs two parallel long-running branches to record the history of the project, master and develop:

Master - is always ready to be released on LIVE, with everything fully tested and approved (production-ready).
Hotfix - Maintenance or “hotfix” branches are used to quickly patch production releases. Hotfix branches are a lot like release branches and feature branches except they’re based on master instead of develop.
Develop - is the branch to which all feature branches are merged and where all tests are performed. Only when everything’s been thoroughly checked and fixed it can be merged to the master.
Feature - Each new feature should reside in its own branch, which can be pushed to the develop branch as their parent one.

21
Q

What does DevOps mean?

A

DevOps is a set of practices that combines software development (Dev) and IT operations (Ops). It aims to shorten the systems development life cycle and provide continuous delivery with high software quality.[1] DevOps is complementary with Agile software development; several DevOps aspects came from the Agile methodology.

DevOps is a newly emerging term in IT field, which is nothing but a practice that emphasizes the collaboration and communication of both software developers and other information-technology (IT) professionals. It focuses on delivering software product faster and lowering the failure rate of releases.

22
Q

What is Event Loop in Node.js

A

Generally speaking, the event loop is a mechanism that waits for and dispatches events or messages in a program. In Node.js, event loops are the central control flow constructs.

For example, every time a request is about to be handled, it’s put on the event loop and processed as soon as it’s ready to be processed. Node, instead of doing it on its own, delegates the responsibility of handling the system.

Because of such behaviour, Node is not actively waiting for this task to finish and can handle other requests in the meantime. The event loop makes Node.js faster and more efficient than other technologies

More:
The event loop is what allows Node.js to perform non-blocking I/O operations — despite the fact that JavaScript is single-threaded — by offloading operations to the system kernel whenever possible.

Every I/O requires a callback - once they are done they are pushed onto the event loop for execution. Since most modern kernels are multi-threaded, they can handle multiple operations executing in the background. When one of these operations completes, the kernel tells Node.js so that the appropriate callback may be added to the poll queue to eventually be executed.

23
Q

What is Test Driven Development (TDD)

A

Test Driven Development is a software development methodology whereby you write and run a set of tests before you write code.

The idea is that those tests will fail at first and then you start to write enough code to try to get all the tests to pass. Having all the tests pass could be a measure of the done criteria (dev-done) and also increases confidence in the quality of the code.

24
Q

Test Driven Development Pros & Cons

A

Pros of Test Driven Development

Because you are writing small tests at a time, it forces your code to be more modular (otherwise they’d be hard to test against). TDD helps you learn, understand, and internalise the key principles of good modular design.

TDD also forces good architecture. In order to make your code unit-testable, it must be properly modularized. Writing the tests first, various architectural problems tend to surface earlier.
Documents your code better than documentation (it doesn’t go out of date since you’re running it all the time).

Makes code easier to maintain and refactor. TDD helps to provide clarity during the implementation process and provides a safety-net when you want to refactor the code you’ve just written.
Makes collaboration easier and more efficient, team members can edit each others code with confidence because the tests will inform them if the changes are making the code behave in unexpected ways.

Because TDD essentially forces you to write unit tests before writing implementation code, refactoring of code becomes easier and faster. Refactoring code written two years ago is hard. If that code is backed up by a set of good unit tests, the process is made so much easier.

Helps prevents defects - well, at least it helps you find design or requirement issues right at the beginning. TDD provides early warning to design problems (when they are easier to fix).

Helps programmers really understand their code.

Creates an automated regression test suite, basically for free. i.e. you don’t need to spend time afterwards writing unit tests to test the implementation code.

It encourages small steps and improves the design because it makes you cut the unnecessary dependencies to facilitate the setup.

It helps to clarify requirements because you have to figure out concretely what inputs you have to feed and what outputs you expect.

Unit tests are especially valuable as a safety net when the code needs to be changed to either add new features or fix an existing bug. Since maintenance accounts for between 60 and 90% of the software life cycle, it’s hard to overstate how the time taken up front to create a decent set of unit tests can pay for itself over and over again over the lifetime of the project.

Testing while writing also forces you to try to make your interfaces clean enough to be tested. It’s sometimes hard to see the advantage of this until you work on a body of code where it wasn’t done, and the only way to exercise and focus on a given piece of code is to run the whole system and set a break-point.

“Stupid” mistakes are caught almost immediately. It helps developers find mistakes that would waste everyone’s time if they were found in QA.

Cons of Test Driven Development

The test suite itself has to be maintained; tests may not be completely deterministic (i.e. reliant on external dependencies).

The tests may be hard to write, esp. beyond the unit testing level.

Initially, it slows down development; for rapidly iterative startup environments the implementation code may not be ready for some time due to spending time writing tests first. (But in the long run, it actually speeds up development)

Like any programming, there is a big difference between doing it and doing it well. Writing good unit tests is an art form. This aspect of TDD is often not discussed, many managers tend to focus on metrics like code coverage; those metrics tell you nothing about the quality of the unit tests.

Unit testing is something the whole team has to buy into.

A challenge to learn. It can be intimidating and not easy for anyone to learn at first, especially trying to learn it on your own. It requires a lot of dedication (discipline, practice, persistence) and you have to have the goal that you want to continually get better at it.

Hard to apply to existing legacy code.

Lot’s of misconceptions that keep programmers from learning it.

Hard to start working this way. Especially if you have many many years of working the other way.

You sometimes have to mock a lot of things or things that are difficult to mock. It’s beneficial in the long term, but painful right now.

You have to perform housekeeping continually. Because booking more and more tests make your build longer and longer, it’s necessary to refine those tests to make them running more quickly or to remove redundant tests.

Like any good technique, unit testing can be carried to an extreme. The biggest benefits come from a moderate effort, with the tests always exercising the code in the simplest way possible. If you find yourself frequently refactoring your tests, there’s a good chance you’re spending too much time on the test suite.

It can be easy to get distracted by “fluff” or fancy features in the unit testing framework. We should remember that simple tests are the fastest to create and the easiest to manage.
Although it is absolutely necessary, creating tests for failures can be tedious, but it pays off big time in the end.

Early stage refactoring requires refactoring test classes as well.

Unless everyone on the team correctly maintains their tests, the whole system can quickly degrade.

25
Q

What is semantic HTML?

A

A semantic element clearly describes its meaning to both the browser and the developer.

Examples of non-semantic elements: <div> and <span> - Tells nothing about its content.</span>

Examples of semantic elements: , , and - Clearly defines its content.</span></div>

26
Q

Big O Notation

A

Big O notation is a mathematical notation that describes the limiting behavior of a function when the argument tends towards a particular value or infinity. It is a member of a family of notations invented by Paul Bachmann, Edmund Landau, and others, collectively called Bachmann–Landau notation or asymptotic notation.

In plain words, Big O notation describes the complexity of your code using algebraic terms.

27
Q
A

Scrum is an agile way to manage a project, usually software development. Agile software development with Scrum is often perceived as a methodology; but rather than viewing Scrum as methodology, think of it as a framework for managing a process.

27
Q

What is Scrum?

A

Scrum is an agile way to manage a project, usually software development. Agile software development with Scrum is often perceived as a methodology; but rather than viewing Scrum as methodology, think of it as a framework for managing a process.

In the agile Scrum world, instead of providing complete, detailed descriptions of how everything is to be done on a project, much of it is left up to the Scrum software development team. This is because the team will know best how to solve the problem they are presented.

This is why in Scrum development, for example, a sprint planning meeting is described in terms of the desired outcome (a commitment to a set of features to be developed in the next sprint) instead of a set of Entry criteria, Task definitions, Validation criteria, Exit criteria (ETVX) and so on, as would be provided in most methodologies.

Scrum relies on a self-organizing, cross-functional team. The scrum team is self-organizing in that there is no overall team leader who decides which person will do which task or how a problem will be solved. Those are issues that are decided by the team as a whole.

And in Scrum, a team is cross functional, meaning everyone is needed to take a feature from idea to implementation.

Within agile development, Scrum teams are supported by two specific roles. The first is a ScrumMaster, who can be thought of as a coach for the team, helping team members use the Scrum process to perform at the highest level.

The product owner (PO) is the other role, and in Scrum software development, represents the business, customers or users, and guides the team toward building the right product.

28
Q

What is a sprint?

A

n Agile product development, a sprint is a set period of time during which specific work has to be completed and made ready for review.

Each sprint begins with a planning meeting. During the meeting, the product owner (the person requesting the work) and the development team agree upon exactly what work will be accomplished during the sprint. The development team has the final say when it comes to determining how much work can realistically be accomplished during the sprint, and the product owner has the final say on what criteria need to be met for the work to be approved and accepted.

The duration of a sprint is determined by the scrum master, the team’s facilitator and manager of the Scrum framework. Once the team reaches a consensus for how many days a sprint should last, all future sprints should be the same. Traditionally, a sprint lasts 30 days.

After a sprint begins, the product owner must step back and let the team do their work. During the sprint, the team holds daily stand-up meetings to discuss progress and brainstorm solutions to challenges. The project owner may attend these meetings as an observer but is not allowed to participate unless it is to answer questions. (See pigs and chickens). The project owner may not make requests for changes during a sprint and only the scrum master or project manager has the power to interrupt or stop the sprint.

At the end of the sprint, the team presents its completed work to the project owner and the project owner uses the criteria established at the sprint planning meeting to either accept or reject the work.

29
Q

React Composition

A
30
Q

React Composition

A

React Composition is a development pattern based on React’s original component model where we build components from other components using explicit defined props or the implicit children prop.

In terms of refactoring, React composition is a pattern that can be used to break a complex component down to smaller components, and then composing those smaller components to structure and complete your application.